103 lines
3.3 KiB
JavaScript
103 lines
3.3 KiB
JavaScript
import Interrupt from './interrupt'
|
|
import Base from '@uci/base'
|
|
import logger from '@uci-utils/logger'
|
|
let log = {}
|
|
|
|
// will more easily create a group of sbc pin interrupts
|
|
|
|
class Interrupts extends Base {
|
|
|
|
constructor(pins, opts = {}) {
|
|
super(opts)
|
|
this.id = this.id || 'interrupts'
|
|
this.pins = pins.map(pin => Number(pin)) // make sure actual numbers are passed
|
|
this._interrupts = new Map()
|
|
this.resetCmd = opts.resetCmd || 'interrupt.reset'
|
|
log = logger({ name: 'interrupts', id: this.id, package:'@uci/interrupt', file:'src/interrupts.js'})
|
|
this.amendConsumerCommands({reset:makefunc.bind(this,'reset')})
|
|
this.amendSocketCommands({
|
|
reset:makefunc.bind(this,'reset'),
|
|
status:makefunc.bind(this,'status'),
|
|
fire:makefunc.bind(this,'fire'),
|
|
intervalReset:makefunc.bind(this,'intervalReset')
|
|
})
|
|
let pinopts = {}
|
|
this.pins.forEach(pin => {
|
|
// remove per pin opts and store
|
|
pinopts[pin] = Object.assign({}, opts[pin])
|
|
delete opts[pin]
|
|
pinopts[pin].multiple=true // each pin will only extend a simple emitter, uci-base
|
|
})
|
|
this.pins.forEach(pin => {
|
|
pinopts[pin] = Object.assign({}, opts, pinopts[pin])
|
|
pinopts[pin].id = pinopts[pin].id || this.id + ':' + pin
|
|
log.debug({ opts: pinopts[pin], method:'constructor', line:25, msg:`pin options for pin ${pin}`})
|
|
this._interrupts.set(pin, new Interrupt(pin, pinopts[pin]))
|
|
|
|
// bubble up events from single interrupts
|
|
const EVENTS=['log','interrupt','reset', 'ready'] // that should emit up from pin base
|
|
EVENTS.forEach(event => {
|
|
this.interrupt(pin).on(event, obj => {
|
|
if (event==='ready') this.emit('ready:'+pin,obj)
|
|
else {
|
|
if (Object.prototype.toString.call(obj) !== '[object Object]') { // is plain object
|
|
let data=obj
|
|
obj = {}
|
|
obj.data = data
|
|
}
|
|
obj.pin = pin
|
|
obj.id = pinopts[pin].id
|
|
this.emit(event,obj) // will emit a pin specific event
|
|
}
|
|
})
|
|
})
|
|
|
|
}) // end pins construct
|
|
|
|
this.on('interrupt', async ev=>{
|
|
await this.push(ev) // push interrupt to any connected consumers
|
|
})
|
|
|
|
} // end constructor
|
|
|
|
interrupt(pin) {
|
|
if (isNaN(pin)) return null
|
|
return this._interrupts.get(Number(pin))
|
|
} // pin type here same as when instantiated above.
|
|
|
|
async init() {
|
|
await super.init()
|
|
return Promise.all(
|
|
Array.from(this._interrupts).map(inter => {
|
|
return inter[1].init()
|
|
})
|
|
)
|
|
}
|
|
|
|
registerHook(func) { // same hook for each pin
|
|
this._interrupts.forEach(inter => {
|
|
inter.registerHook(func)
|
|
})
|
|
}
|
|
|
|
} // end Class
|
|
|
|
export default Interrupts
|
|
|
|
// combines indiviudal pin function calls into single call and combines returns
|
|
async function makefunc(fn, packet={}) {
|
|
if (!packet.pin || packet.pin==='all') {
|
|
let rpacket = {pins:[]}
|
|
for (let inter of this._interrupts.entries()) {
|
|
let ipacket = Object.assign({},packet)
|
|
delete(ipacket.cmd);delete(ipacket._header)
|
|
let res = await inter[1][fn](ipacket)
|
|
res.pin = inter[0]
|
|
rpacket.pins.push(res)
|
|
}
|
|
return rpacket
|
|
}
|
|
let pin = isNaN(Number(packet)) ? packet.pin : packet
|
|
if (this._interrupts.has(Number(pin))) return await this.interrupt(packet.pin)[fn](packet)
|
|
}
|