fix(hal): make validator optional for dispenser-only operation
The HAL init hung indefinitely when the validator device didn't exist or failed to respond — blocking the entire init including the dispenser and Lightning connection. Now the validator is optional: - Checks device exists (fs.existsSync) before attempting to open - 15s timeout on validator.run() to prevent hanging - On failure, logs warning and proceeds with dispenser-only mode - All validator methods guarded with null checks This enables the BATM3 to run cash-out only when the MEI validator is not connected (e.g., during initial setup or testing). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
98b17073d8
commit
c8f76af113
1 changed files with 48 additions and 24 deletions
|
|
@ -68,11 +68,6 @@ export async function initializeHal(config: HalConfig): Promise<HalInstance> {
|
|||
const { validator: valConfig, dispenser: dispConfig } = config
|
||||
|
||||
// Create hardware instances
|
||||
const validator: BillValidator = hal.createValidator(valConfig.type, {
|
||||
rs232: { device: valConfig.device, fiatCode: valConfig.fiatCode },
|
||||
fiatCode: valConfig.fiatCode,
|
||||
})
|
||||
|
||||
const dispenser: BillDispenser = hal.createDispenser(dispConfig.type, {
|
||||
device: dispConfig.device,
|
||||
})
|
||||
|
|
@ -85,14 +80,35 @@ export async function initializeHal(config: HalConfig): Promise<HalInstance> {
|
|||
await dispenser.init(dispenserInitData)
|
||||
console.log('[HAL] Dispenser initialized')
|
||||
|
||||
// Start validator
|
||||
// Start validator (optional — proceed without if device is missing or fails)
|
||||
let validator: BillValidator | null = null
|
||||
try {
|
||||
const fs = await import('node:fs')
|
||||
const device = Array.isArray(valConfig.device) ? valConfig.device[0] : valConfig.device
|
||||
if (device && fs.existsSync(device)) {
|
||||
validator = hal.createValidator(valConfig.type, {
|
||||
rs232: { device: valConfig.device, fiatCode: valConfig.fiatCode },
|
||||
fiatCode: valConfig.fiatCode,
|
||||
})
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
validator.run((err?: Error) => {
|
||||
const timeout = setTimeout(() => {
|
||||
reject(new Error('Validator init timed out'))
|
||||
}, 15000)
|
||||
validator!.run((err?: Error) => {
|
||||
clearTimeout(timeout)
|
||||
if (err) return reject(err)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
console.log('[HAL] Validator started')
|
||||
} else {
|
||||
console.log('[HAL] Validator device not found, running dispenser-only')
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('[HAL] Validator failed to start, running dispenser-only:', err)
|
||||
validator = null
|
||||
}
|
||||
|
||||
// Track inventory
|
||||
const inventory: Record<number, number> = {}
|
||||
|
|
@ -104,6 +120,10 @@ export async function initializeHal(config: HalConfig): Promise<HalInstance> {
|
|||
|
||||
return {
|
||||
connectValidator: (callbacks: ValidatorCallbacks) => {
|
||||
if (!validator) {
|
||||
console.log('[HAL] No validator — cash-in disabled')
|
||||
return
|
||||
}
|
||||
validator.on('billsRead', (data: { denomination: number | null; code: number }) => {
|
||||
if (data.denomination !== null) {
|
||||
const decision = callbacks.shouldAcceptBill(data.denomination)
|
||||
|
|
@ -142,17 +162,17 @@ export async function initializeHal(config: HalConfig): Promise<HalInstance> {
|
|||
},
|
||||
|
||||
enableValidator: () => {
|
||||
validator.enable()
|
||||
validator.lightOn()
|
||||
validator?.enable()
|
||||
validator?.lightOn()
|
||||
},
|
||||
|
||||
disableValidator: () => {
|
||||
validator.disable()
|
||||
validator.lightOff()
|
||||
validator?.disable()
|
||||
validator?.lightOff()
|
||||
},
|
||||
|
||||
stackBill: () => validator.stack(),
|
||||
rejectBill: () => validator.reject(),
|
||||
stackBill: () => validator?.stack(),
|
||||
rejectBill: () => validator?.reject(),
|
||||
|
||||
dispenseCash: async (amounts): Promise<DispenseResult> => {
|
||||
console.log('[HAL] Dispensing:', amounts)
|
||||
|
|
@ -229,13 +249,17 @@ export async function initializeHal(config: HalConfig): Promise<HalInstance> {
|
|||
|
||||
cleanup: async () => {
|
||||
return new Promise<void>((resolve) => {
|
||||
validator.disable()
|
||||
validator.lightOff()
|
||||
validator?.disable()
|
||||
validator?.lightOff()
|
||||
dispenser.close()
|
||||
if (validator) {
|
||||
validator.close((err?: Error) => {
|
||||
if (err) console.error('[HAL] Validator close error:', err)
|
||||
resolve()
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue