diff --git a/examples/single.js b/examples/single.js index 1e5eaf9..9a3bbad 100644 --- a/examples/single.js +++ b/examples/single.js @@ -4,11 +4,11 @@ import Base from '@uci/base' // let interrupt = new Interrupt(24,{id:'test-interrupt', wait:0}) // let listener = new Base({sockets:'inter#s>n', inter:{path:'interrupt:24'}, id:'listener'}) -let interrupt = new Interrupt(24,{id:'test-interrupt', wait:0, host:'localhost', hook:true}) -let listener = new Base({sockets:'inter#s>t', inter:{port:9024}, id:'listener'}) +let interrupt = new Interrupt(24,{id:'test-interrupt', wait:0, hook:true, mock:true}) +let processor = new Base({sockets:'inter#c>t', inter:{port:9024}, id:'listener'}) -listener.interrupt = async function (packet) { +processor.interrupt = async function (packet) { return new Promise((resolve) => { console.log('interrupt socket listener got') console.dir(packet) @@ -20,9 +20,10 @@ listener.interrupt = async function (packet) { ; (async () => { - console.log(await listener.init()) - await interrupt.init() + console.log(await interrupt.init()) + console.log(await processor.init()) interrupt.fire() + processor.send({cmd: 'fire'}) // interrupt.fire() // interrupt.fire() // interrupt.fire() diff --git a/src/interrupt-c.js b/src/interrupt-c.js new file mode 100644 index 0000000..b091efb --- /dev/null +++ b/src/interrupt-c.js @@ -0,0 +1,123 @@ +import bus, { Gpio } from 'pigpio' +// import bus, { Gpio } from 'pigpio-mock' +// import btc from 'better-try-catch' +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={}) { + + opts.itrt = opts.itrt || {} + if (opts.itrt || opts.host) { + opts.itrt.host = opts.host || opts.itrt.host + if (opts.itrt.host) { + opts.itrt.port = opts.itrt.port || opts.port || 9000+pin + opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrt#c>t' + } + } + if (opts.path || opts.itrn || !opts.itrt.host) { + opts.itrn = opts.itrn || {} + opts.itrn.path = opts.path || opts.itrn.path || 'interrupt:'+ pin + opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrn#c>n' + } + if (opts.sockets==='') throw ('must have at least one socket client') + 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.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 + 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 + fire() { + console.log('manually firing interrupt for pin', this.pin_num) + this.pin.emit('interrupt',1) + } + + 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 sending',packet) + this.send(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 diff --git a/src/interrupt.js b/src/interrupt.js index b091efb..823c5fa 100644 --- a/src/interrupt.js +++ b/src/interrupt.js @@ -1,6 +1,7 @@ -import bus, { Gpio } from 'pigpio' +// 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' @@ -12,20 +13,28 @@ let log = {} export default class Interrupt extends Base { constructor(pin,opts={}) { - opts.itrt = opts.itrt || {} - if (opts.itrt || opts.host) { - opts.itrt.host = opts.host || opts.itrt.host - if (opts.itrt.host) { - opts.itrt.port = opts.itrt.port || opts.port || 9000+pin - opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrt#c>t' - } - } - if (opts.path || opts.itrn || !opts.itrt.host) { + 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#c>n' + opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrn#s>n' } - if (opts.sockets==='') throw ('must have at least one socket client') + 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' + } + super(opts) console.dir(opts) log = logger({name:'interrupt',id:this.id}) @@ -34,13 +43,16 @@ export default class Interrupt extends Base { 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.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.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 @@ -54,6 +66,20 @@ export default class Interrupt extends Base { async init(){ await super.init() // for cntrl-c exit of interrupt + // create the pigio pin_num + bus = await import('../../pigpio-mock/src') + 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)) @@ -99,8 +125,8 @@ export default class Interrupt extends Base { packet.count += 1 packet.time = new Date().getTime() if(this._hook) packet = this.hook(packet) - // console.log('packet sending',packet) - this.send(packet) + // console.log('packet pushing to all clients',packet) + this.push(packet) } //sample hook