little cleanup - update dependencies

master
David Kebler 2019-01-01 20:02:16 -08:00
parent e196083d5e
commit 55092303e8
4 changed files with 112 additions and 163 deletions

View File

@ -34,7 +34,8 @@
}, },
"dependencies": { "dependencies": {
"@uci/base": "^0.1.7", "@uci/base": "^0.1.7",
"@uci/logger": "0.0.3", "@uci/i2c-device": "^0.1.4",
"@uci/logger": "0.0.6",
"lodash.debounce": "^4.0.8" "lodash.debounce": "^4.0.8"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,79 +0,0 @@
'use strict'
// Creates an ES6 Interrupt class wrapper using the pigio C library and pigpio javascript wrapper package
// The pigipio C library is specifically coded for the Raspberry Pi but might be adapatable to any single board computer (sbc) with Gpios
// assuming they would be pigio C, compatiable.
// Must have pigpio C library installed first.
// On interrupt emits "fired" which can be caught by the code calling this interrupt instance for handling
// Understand there are two interrupts here. One is this class and one on the sbc/rpi via pigpio
// The sbc/pigpio interrupt emits an event which is listened for by this class which then emits
// a "fired" event which can be can be listed to by having a handle to an instance this class.
const
pigpio = require('pigpio'),
sbcGpio = pigpio.Gpio,
EventEmitter = require('events')
class Interrupt extends EventEmitter {
constructor(pin_number, handler, opts = {}) {
super()
this.pin_number = pin_number
this.handler = handler
this.mode = sbcGpio.INPUT
this.pull = opts.pull ? opts.pull : sbcGpio.PUD_DOWN
this.edge = opts.edge ? opts.edge : sbcGpio.RISING_EDGE
this.sbc_interrupt = new sbcGpio(
this.pin_number, {
mode: this.mode,
pullUpDown: this.pull,
// do not! set edge here as it will start the emitter -- see pigio js
}
)
}
// init() {
//
// // console.log(`initialize interrupt ${this.pin_number}`)
// return Promise.resolve()
//
// }
get pin() {
return this.pin_number
}
async start() {
console.log(`starting interrupt on pin ${ this.pin_number}`)
// 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))
})
let interrupt = this // scope `this` for use in the listener for each interrupt
// console.log(`interrupt listener set for rpi ${interrupt.pin_number}`)
this.sbc_interrupt.on('interrupt', function () {
// console.log(`the sbc interrupt tripped by sbc pin ${interrupt.pin_number}`)
interrupt.emit('fired') // emit an event that can be listened for by the device that created the interrupt instance
})
// rock n roll!!, start the pigpio interrupt
this.sbc_interrupt.enableInterrupt(this.edge)
}
// manual firing for testing
fire() {
let interrupt = this
console.log('manually firing interrupt', this.handler)
this.emit('fired')
}
exit() {
pigpio.terminate()
return Promise.reject(`keyboard termination...terminating interrupt on pin ${this.pin_number}`)
}
}
module.exports = Interrupt

View File

@ -8,39 +8,43 @@ import Base from '@uci/base'
import logger from '@uci/logger' import logger from '@uci/logger'
let log = {} let log = {}
export default class Interrupt extends Base { class Interrupt extends Base {
constructor(pin,opts={}) { constructor(pin, opts = {}) {
if (opts.path || opts.itrn ) { if (opts.path || opts.itrn) {
opts.itrn = opts.itrn || {} opts.itrn = opts.itrn || {}
opts.itrn.path = opts.path || opts.itrn.path || 'interrupt:'+ pin opts.itrn.path = opts.path || opts.itrn.path || 'interrupt:' + pin
opts.itrn.conPacket = opts.conPacket opts.itrn.conPacket = opts.conPacket
opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrn#s>n' opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + 'itrn#s>n'
} }
if (opts.topics || opts.itrm) { if (opts.topics || opts.itrm) {
opts.itrm = opts.itrm || {} opts.itrm = opts.itrm || {}
opts.itrm.topics = opts.topics || 'interrupt/'+ pin opts.itrm.topics = opts.topics || 'interrupt/' + pin
opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrm#s>m' opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + 'itrm#s>m'
} }
if (opts.itrw || opts.wport) { if (opts.itrw || opts.wport) {
opts.itrw.port = opts.itrw.port || opts.wport || 9100+pin opts.itrw.port = opts.itrw.port || opts.wport || 9100 + pin
opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrw#s>w' opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + 'itrw#s>w'
} }
// default is a tcp socket server at 9000+pin // default is a tcp socket server at 9000+pin
if (opts.itrt || opts.port || !opts.sockets) { if (opts.itrt || opts.port || !opts.sockets) {
opts.itrt = opts.itrt || {} opts.itrt = opts.itrt || {}
opts.itrt.port = opts.itrt.port || opts.port || 9000+pin opts.itrt.port = opts.itrt.port || opts.port || 9000 + pin
opts.itrt.conPacket = opts.conPacket opts.itrt.conPacket = opts.conPacket
opts.sockets = (opts.sockets ? (opts.sockets + ',') : '') + 'itrt#s>t' opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + 'itrt#s>t'
} }
super(opts) super(opts)
this.id = (opts.id ||'interrupt') + ':' + pin this.id = (opts.id || 'interrupt') + ':' + pin
log = logger({name:'interrupt',id:this.id}) log = logger({ name: 'interrupt', id: this.id })
log.info({pins:pin, opts:opts},'created interrupt with these opts') log.info({ pins: pin, opts: opts }, 'created interrupt with these opts')
this.pin_num = pin this.pin_num = pin
this.mock = opts.mock || process.env.MOCK this.mock = opts.mock || process.env.MOCK
this.wait = opts.wait || 0 // debounce is off by default 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.dbopts = {
maxWait: opts.maxwait || 500,
leading: opts.leading || true,
trailing: opts.trailing || false
}
this.edge = opts.edge this.edge = opts.edge
this.pull = opts.pull this.pull = opts.pull
this.pin = {} //set at init this.pin = {} //set at init
@ -49,51 +53,62 @@ export default class Interrupt extends Base {
this.packet.pin = pin this.packet.pin = pin
this.packet.cmd = this.packet.cmd || opts.pushcmd || 'interrupt' this.packet.cmd = this.packet.cmd || opts.pushcmd || 'interrupt'
this.packet.count = 0 this.packet.count = 0
} // end constructor } // end constructor
async init() {
async init(){
await super.init() await super.init()
// for cntrl-c exit of interrupt // for cntrl-c exit of interrupt
// create the pigio pin_num // create the pigio pin_num
if (this.mock) bus = await import('pigpio-mock') if (this.mock) bus = await import('pigpio-mock')
else bus = await import('pigpio') else bus = await import('pigpio')
this.pin = new bus.Gpio( this.pin = new bus.Gpio(this.pin_num, {
this.pin_num, {
mode: bus.Gpio.INPUT, mode: bus.Gpio.INPUT,
pullUpDown: this.pull || bus.Gpio.PUD_DOWN pullUpDown: this.pull || bus.Gpio.PUD_DOWN
// do not! set edge here as it will start the emitter -- see pigio js // do not! set edge here as it will start the emitter -- see pigio js
}) })
process.on('SIGINT', () => { process.on('SIGINT', () => {
this.exit().then((resp) => console.log('\n', resp)) // unexport on cntrl-c this.exit()
.then(resp => console.log('\n', resp)) // unexport on cntrl-c
.catch(err => console.log('error:', err)) .catch(err => console.log('error:', err))
}) })
let cb = () => {} let cb = () => {}
if (this.wait===0) { if (this.wait === 0) {
cb = this._interruptProcess.bind(this,this.packet) cb = this._interruptProcess.bind(this, this.packet)
console.log(`starting interrupt on pin ${this.pin_num} without debounce`) 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`) 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
}`
)
} }
else { this.pin.on('interrupt', cb)
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 // rock n roll!!, start the pigpio interrupt
if(!this.mock) this.pin.enableInterrupt(this.edge || bus.Gpio.RISING_EDGE ) if (!this.mock) this.pin.enableInterrupt(this.edge || bus.Gpio.RISING_EDGE)
} }
// manual firing for testing // manual firing for testing
async fire() { async fire() {
console.log('manually firing interrupt for pin', this.pin_num) console.log('manually firing interrupt for pin', this.pin_num)
this.pin.emit('interrupt',1) this.pin.emit('interrupt', 1)
return Promise.resolve({status:'fired'}) return Promise.resolve({ status: 'fired' })
} }
exit() { exit() {
@ -102,31 +117,36 @@ export default class Interrupt extends Base {
} }
// default processor // default processor
async _interruptProcess (packet) { async _interruptProcess(packet) {
packet.count += 1 packet.count += 1
packet.time = new Date().getTime() packet.time = new Date().getTime()
if(this._hook) packet = await this.hook(packet) if (this._hook) packet = await this.hook(packet)
log.info({packet:packet},'packet pushing to all clients') log.info({ packet: packet }, 'packet pushing to all clients')
this.push(packet) this.push(packet)
} }
//sample hook //sample hook
hook (packet) { hook(packet) {
// return a promise if anything async happens in hook // return a promise if anything async happens in hook
// new Promise((resolve) => { // new Promise((resolve) => {
console.log('=======================') console.log('=======================')
console.log(`pin ${packet.pin} on sbc gpio bus has thrown an interrupt`) console.log(`pin ${packet.pin} on sbc gpio bus has thrown an interrupt`)
console.log(`pushing to all connected socket client with cmd:${packet.cmd}`) console.log(`pushing to all connected socket client with cmd:${packet.cmd}`)
console.dir(packet) console.dir(packet)
console.log('This hook allow you to modify the packet being pushed to connected clients') console.log(
console.log('add .hook method for your instance or extended class to overwrite this') 'This hook allow you to modify the packet being pushed to connected clients'
console.log('Must be promise returning if anything async happens in your hook') )
console.log(
'add .hook method for your instance or extended class to overwrite this'
)
console.log(
'Must be promise returning if anything async happens in your hook'
)
console.log('=======================') console.log('=======================')
return packet return packet
// resolve(packet) // resolve(packet)
// }) // })
} }
} // end Class } // end Class
export default Interrupt

View File

@ -3,67 +3,74 @@ import Interrupt from './interrupt'
import logger from '@uci/logger' import logger from '@uci/logger'
let log = {} let log = {}
export default class Interrupts { class Interrupts {
constructor(pins,opts={}) { constructor(pins, opts = {}) {
this.id = this.id || 'interrupts' this.id = this.id || 'interrupts'
this.pins = pins this.pins = pins
this.interrupt={} this.interrupt = {}
log = logger({name:'interrupts',id:this.id}) log = logger({ name: 'interrupts', id: this.id })
let pinopts={} let pinopts = {}
pins.forEach (pin =>{ // remove per pin opts and store pins.forEach(pin => {
pinopts[pin]=Object.assign({},opts[pin]) // remove per pin opts and store
delete(opts[pin]) pinopts[pin] = Object.assign({}, opts[pin])
delete opts[pin]
}) })
pins.forEach (pin =>{ pins.forEach(pin => {
pinopts[pin] = Object.assign({}, opts, pinopts[pin]) pinopts[pin] = Object.assign({}, opts, pinopts[pin])
pinopts[pin].id = (opts.id ||'interrupt') + ':' + pin pinopts[pin].id = (opts.id || 'interrupt') + ':' + pin
pinopts[pin].conPacket = { cmd:opts.resetCmd, pin:pin } pinopts[pin].conPacket = { cmd: opts.resetCmd, pin: pin }
log.info({opts:pinopts[pin]},`pin options for pin ${pin}`) log.info({ opts: pinopts[pin] }, `pin options for pin ${pin}`)
this.interrupt[pin] = new Interrupt(pin,pinopts[pin]) this.interrupt[pin] = new Interrupt(pin, pinopts[pin])
}) })
} }
async init() { async init() {
return Promise.all(this.pins.map(pin => {return this.interrupt[pin].init()})) return Promise.all(
this.pins.map(pin => {
return this.interrupt[pin].init()
})
)
} }
// manual firing for testing // manual firing for testing
fire(pin) { fire(pin) {
if(pin) { if (pin) {
this.interrupt[pin].pin.emit('interrupt',1) this.interrupt[pin].pin.emit('interrupt', 1)
console.log('manually firing interrupt for pin', pin) console.log('manually firing interrupt for pin', pin)
} } else {
else {
console.log('manually firing interrupt for pins', this.pins) console.log('manually firing interrupt for pins', this.pins)
this.pins.forEach (async pin =>{ this.pins.forEach(async pin => {
this.interrupt[pin].pin.emit('interrupt',1) this.interrupt[pin].pin.emit('interrupt', 1)
}) })
} }
} }
setHook(func) { setHook(func) {
this.pins.forEach (async pin =>{ this.pins.forEach(async pin => {
this.interrupt[pin].hook=func this.interrupt[pin].hook = func
}) })
} }
// new test // new test
push(packet) { push(packet) {
this.pins.forEach (async pin =>{ this.pins.forEach(async pin => {
console.log('all push', pin, packet) console.log('all push', pin, packet)
this.interrupt[pin].push(packet) this.interrupt[pin].push(packet)
}) })
} }
} // end Class } // end Class
export default Interrupts
// default hook // default hook
const hook = (packet) => { const hook = packet => {
console.log('======Common for all Pins Default Hook=================') console.log('======Common for all Pins Default Hook=================')
console.log(`pin ${packet.pin} on sbc gpio bus has thrown ${packet.count}th interrupt`) console.log(
console.log('sending to all connected consumers/clients with default cmd:"interrupt"') `pin ${packet.pin} on sbc gpio bus has thrown ${packet.count}th interrupt`
)
console.log(
'sending to all connected consumers/clients with default cmd:"interrupt"'
)
console.dir(packet) console.dir(packet)
console.log('this is the default beforeHook') console.log('this is the default beforeHook')
console.log('add .hook for your instance or extended class') console.log('add .hook for your instance or extended class')