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) }