uci-interrupt/src/interrupts.js

108 lines
3.2 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.commands = {
fire:makefunc.bind(this,'fire'),
status:makefunc.bind(this,'status'),
reset:makefunc.bind(this,'reset'),
}
this.addNamespace('commands', 's') // give access to these commands above if a socket/server is created
let pinopts = {}
pins.forEach(pin => {
// remove per pin opts and store
pinopts[pin] = Object.assign({}, opts[pin])
delete opts[pin]
})
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','connection','connection:consumer', 'connection:socket'] // that should emit up from pin base
EVENTS.forEach(event => {
this.interrupt(pin).on(event, obj => {
if (Object.prototype.toString.call(obj) !== '[object Object]') {
let data=obj
obj = {}
obj.data = data
}
obj.pin = pin
obj.id = pinopts[pin].id
this.emit(event,obj)
})
})
})
this._interrupts.forEach( inter => {
inter.on('interrupt', packet => {
this.send(packet) // send via common consumer
this.emit('interrupt',packet)
})
inter.on(this.resetCmd, packet => {
this.send(packet) // send via common consumer
this.emit(this.resetCmd,packet)
})
})
} // end constructor
interrupt(pin) { return this._interrupts.get(Number(pin)) } // get a handle to single interrupt
async init() {
return Promise.all(
Array.from(this._interrupts).map(inter => {
return inter[1].init()
})
)
}
// only adds consumer sockets to each interrupt to same socket/server
// alternatively use listen handler and single socket
async addInterSocket(name,type) {
if (type !=='s') {
this._interrupts.forEach( inter => {
inter.registerSocket(...arguments)
})
}
}
registerHook(func) {
this._interrupts.forEach(inter => {
inter.registerHook(func)
})
}
} // end Class
export default Interrupts
async function makefunc(fn, packet) {
if (!packet.pin || packet.pin==='all') {
for (let inter of this._interrupts.entries()) {
packet[inter[0]] = await inter[1][fn]()
}
packet.cmd='reply'
return packet
}
let pin = isNaN(Number(packet)) ? packet.pin : packet
if (this._interrupts.has(Number(pin))) return await this.interrupt(packet.pin)[fn](packet)
}