// import bus, { Gpio } from 'pigpio' // import bus, { Gpio } from 'pigpio-mock' // import btc from 'better-try-catch' let bus = {} import debounce from 'lodash.debounce' // import throttle from 'lodash.throttle' // import debounce from 'debounce-fn' import Base from '@uci/base' import logger from '@uci/logger' let log = {} export default class Interrupt extends Base { constructor(pin,opts={}) { if (opts.path || opts.itrn ) { opts.itrn = opts.itrn || {} opts.itrn.path = opts.path || opts.itrn.path || 'interrupt:'+ pin opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrn#s>n' } if (opts.topics || opts.itrm) { opts.itrm = opts.itrm || {} opts.itrm.topics = opts.topics || 'interrupt/'+ pin opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrm#s>m' } if (opts.itrw || opts.wport) { opts.itrw.port = opts.itrw.port || opts.wport || 9100+pin opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrw#s>w' } // default is a tcp socket server at 9000+pin if (opts.itrt || opts.port || !opts.sockets) { opts.itrt = opts.itrt || {} opts.itrt.port = opts.itrt.port || opts.port || 9000+pin opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrt#s>t' } console.log('sockets', opts.sockets) super(opts) console.dir(opts) log = logger({name:'interrupt',id:this.id}) log.info({pins:pin, opts:opts},'created interrupt with these opts') this.pin_num = pin this.mock = opts.mock this.wait = opts.wait || 0 // debounce is off by default this.dbopts = { maxWait:opts.maxwait || 500, leading: opts.leading || true, trailing:opts.trailing || false} // this.edge = opts.edge || Gpio.RISING_EDGE this.edge = opts.edge this.pull = opts.pull this.pin = {} //set at init // this.pin = new Gpio( // pin, { // mode: Gpio.INPUT, // pullUpDown: opts.pull || Gpio.PUD_DOWN // // do not! set edge here as it will start the emitter -- see pigio js // }) this._hook = opts.hook this.packet = opts.packet || {} this.packet.pin = pin this.packet.cmd = this.packet.cmd || 'interrupt' this.packet.count = 0 } // end constructor async init(){ await super.init() // for cntrl-c exit of interrupt // create the pigio pin_num if (this.mock) bus = await import('../../pigpio-mock/src') else bus = await import('pigpio') // console.log(bus.Gpio) this.pin = new bus.Gpio( this.pin_num, { mode: bus.Gpio.INPUT, pullUpDown: this.pull || bus.Gpio.PUD_DOWN // do not! set edge here as it will start the emitter -- see pigio js }) process.on('SIGINT', () => { this.exit().then((resp) => console.log('\n', resp)) // unexport on cntrl-c .catch(err => console.log('error:', err)) }) // const pinDebounce = function (processor, wait, options, packet) { // console.log(processor,wait,options,packet) // return debounce.bind(this,processor.bind(this,packet),wait, options) // return debounce.bind(processor.bind(this,packet),wait) // return debounce.bind(null,processor,{ wait:wait}) // } // else cb = pinDebounce(this.interruptProcess,this.wait,this.dbopts,this.packet) let cb = () => {} if (this.wait===0) { cb = this._interruptProcess.bind(this,this.packet) console.log(`starting interrupt on pin ${this.pin_num} without debounce`) log.info({packet:this.packet},`starting interrupt on pin ${this.pin_num} without debounce`) } else { cb = debounce(this._interruptProcess.bind(this,this.packet),this.wait,this.dbopts) console.log(`starting interrupt on pin ${this.pin_num} with debounce wait:${this.wait} options:${JSON.stringify(this.dbopts)}` ) log.info({packet:this.packet, wait:this.wait, options:this.dbopts},`starting interrupt on pin ${this.pin_num} with debounce wait:${this.wait}` ) } this.pin.on('interrupt',cb) // rock n roll!!, start the pigpio interrupt if(!this.mock) this.pin.enableInterrupt(this.edge) } // manual firing for testing async fire() { console.log('manually firing interrupt for pin', this.pin_num) this.pin.emit('interrupt',1) return Promise.resolve({status:'fired'}) } exit() { bus.terminate() return Promise.reject('keyboard termination...terminating interrupts') } // default processor async _interruptProcess (packet) { packet.count += 1 packet.time = new Date().getTime() if(this._hook) packet = this.hook(packet) // console.log('packet pushing to all clients',packet) this.push(packet) } //sample hook hook (packet) { // new Promise((resolve) => { console.log('=======================') console.log(`pin ${packet.pin} on sbc gpio bus has thrown an interrupt`) console.log('sending to all connected sockets with default cmd:"interrupt"') console.dir(packet) console.log('this is the default beforeHook') console.log('add "beforeHook" for your instance or extended class') console.log('=======================') return packet // resolve(packet) // }) } } // end Class