diff --git a/examples/17-test.js b/examples/17-test.js deleted file mode 100644 index 38ce46b..0000000 --- a/examples/17-test.js +++ /dev/null @@ -1,59 +0,0 @@ -/* -* i2c bus unix socket and client in one for demo -* -*/ - -import Base from '../../uci-base/src/base' -import { spawn } from 'child_process' - -const PATH = '/opt/sockets/mcp.sock' - -const delay = time => new Promise(res=>setTimeout(()=>res(),time)) - - - -const i2cbus = spawn('node',['-r', '@std/esm', './examples/bus']) -i2cbus.stdout.on('data', function(buf) { - console.log('[I2C BUS]', String(buf)) -}) - -; -(async () => { - - let mcpclient = new Base({id:'mcpclient', sockets:'uc#c>n', uc:{path:PATH}}) - - mcpclient.reply = function (packet) { - console.log('for request ',packet._header.request) - console.log('mcp status is ',packet.status) - } - - await mcpclient.init() - console.log('=============sending============') - // const pins='2,3,4' - // const pins=3 - // const pins='all' - // const pins=[1,3,5,7] - - let packet = {cmd:'pin.cfg', pins:'all'} - await mcpclient.send(packet) - packet = {cmd:'pin.cfg', pins:'all', port:'B'} - await mcpclient.send(packet) - packet = {cmd:'pin.state.off', pins:'all' } - await mcpclient.send(packet) - packet = {cmd:'pin.state.off', pins:'all', port:'B' } - await mcpclient.send(packet) - packet = {cmd:'pin.state.on', pins:'2,7', port:'B' } - await mcpclient.send(packet) - packet = {cmd:'pin.state.on', pins:'3,6'} - await mcpclient.send(packet) - packet = {cmd:'pin.status', pins:'all'} - await mcpclient.send(packet) - packet = {cmd:'pin.status', pins:'all', port:'B'} - await mcpclient.send(packet) - - process.kill(process.pid, 'SIGTERM') - - -})().catch(err => { - console.error('FATAL: UNABLE TO START SYSTEM!\n',err) -}) diff --git a/examples/mcp-switch-relay.js b/examples/mcp-switch-relay.js deleted file mode 100644 index 627a801..0000000 --- a/examples/mcp-switch-relay.js +++ /dev/null @@ -1,65 +0,0 @@ -/* -* -* -*/ -import { MCP230XXi } from '../src' -import { MCP230XX } from '../src' -import Base from '@uci/base' - -const BUS_HOST = 'sbc' // if ihost not given will be the same as host: -const BUS_PORT = 1776 // 1776 is default port for i2c-bus module -const SW_ADDRESS = 0x25 // 1776 is default port for i2c-bus module -const RY_ADDRESS = 0x27 // 1776 is default port for i2c-bus module - -let announce = new Base({id:'switch:announce'}) - -let sw17 = new MCP230XXi([9,10],{id:'sw17', chip17:true, host:BUS_HOST, address:SW_ADDRESS+1}) -// let sw8 = new MCP230XXi([24],{id:'sw8', host:BUS_HOST, address:SW_ADDRESS}) -// let ry8 = new MCP230XX({id:'ry8', host:BUS_HOST, address:RY_ADDRESS}) -const reply = { reply: () => {} } -// ry8.c = reply; -sw17.c=reply -// sw8.c= reply - -function iprocess(details) { - console.log('--common interrupt processor--') - console.log(details) - announce.push() - // action function can do whatever but best would be to push the details to any attached client (mqtt or some database that then pushes - // local_action(details) -} - -// just something to do -async function local_action (details) { - if (details.id === 'sw17') { - await ry8.pin.state.toggle({pins:'2,4,6,8'}) - } - if (details.id === 'sw8') { - if (details.pin===1) { - if (details.state==='off') await ry8.pin.state.off({pins:'all'}) - else ry8.pin.state.on({pins:'all'}) - } - if (details.pin===8) { - if (details.state==='off') await ry8.pin.state.off({pins:'1,3,5,7'}) - else await ry8.pin.state.on({pins:'1,3,5,7'}) - } - } -} - - -(async () => { - - await sw17.init() - sw17.interruptProcessor(iprocess) - - // await sw8.init() - // sw8.interruptProcessor(iprocess) - // - // - // await ry8.init() - // let packet = {pins:'all', cfg:'output'} - // await ry8.pin.cfg(packet) - -})().catch(err => { - console.error('FATAL: UNABLE TO START SYSTEM!\n',err) -}) diff --git a/examples/mcp17.js b/examples/mcp17.js deleted file mode 100644 index 55426c0..0000000 --- a/examples/mcp17.js +++ /dev/null @@ -1,23 +0,0 @@ -/* -* i2c bus with both unix and tcp socket using defaults. For TCP that is host OS name and port 8080 -* -*/ -import MCP230XX from '../src/mcp230xx-packet' -// const PATH = '' - - ; -(async () => { - - // let chip8 = new MCP230XX({id:'mcp8-27', address:0x27, nmcp: { path: '/opt/sockets/mcp2.sock' }}) - let chip17 = new MCP230XX({id:'mcp17-26', chip17:true, address:0x26}) - - await chip17.init() - // await chip8.init() - console.log(await chip17.pin.cfg({pins:'all'})) - // console.log(await chip17.pin.cfg({pins:'all', cfg:'toggle_switch'})) - // console.log(await chip17.pin.cfg({pins:'all', port:'B', cfg:'toggle_switch'})) - // console.log(await chip8.pin.cfg({pins:'all', cfg:'toggle_switch'})) - -})().catch(err => { - console.error('FATAL: UNABLE TO START SYSTEM!\n',err) -}) diff --git a/examples/outputs.js b/examples/outputs.js new file mode 100644 index 0000000..2d0ddd5 --- /dev/null +++ b/examples/outputs.js @@ -0,0 +1,40 @@ +/* +* +* +*/ +import { MCP230XX } from '../src' + +// const TRANSPORT = process.env.TRANSPORT || 'tcp' +const HOST = process.env.BUS_HOST || 'sbc' +const PORT = process.env.BUS_PORT || 1776 +const ADDRESS = process.env.DEVICE_ADDR || 39 +const CHIP17 = !!process.env.CHIP17 || false + +; +(async () => { + + let outputs = new MCP230XX({id:'mcp', chip17:CHIP17, address:ADDRESS, bus:{host:HOST, port:PORT}}) + + console.log(await outputs.socketsInit()) + + await new Promise((resolve) => setTimeout(resolve,50)) + + outputs.on('ready:mcp', async ev => { + console.log('mcpready', ev) + // all pins are outputs by default + for (var i = 0; i < 10; i++) { + console.log('pass', i) + await outputs.commands.pin.state.on({pins:'all'}) + await outputs.commands.pin.state.on({port:'B', pins:'all'}) // will be ingnored on mcp23008 + await new Promise((resolve) => setTimeout(resolve,50)) + await outputs.commands.pin.state.off({pins:'all'}) + await outputs.commands.pin.state.off({port:'B', pins:'all'}) // will be ingnored on mcp23008 + } + + process.kill(process.pid, 'SIGTERM') + + }) + +})().catch(err => { + console.error('FATAL: UNABLE TO START SYSTEM!\n',err) +}) diff --git a/examples/switches.js b/examples/switches.js new file mode 100644 index 0000000..34410de --- /dev/null +++ b/examples/switches.js @@ -0,0 +1,64 @@ +/* +* +* +*/ +import { MCP230XXi } from '../src' + +const HOST = process.env.BUS_HOST +const PATH = process.env.BUS_PATH +const PORT = process.env.BUS_PORT || 1776 +const ADDRESS = process.env.DEVICE_ADDR || 0x26 +const CHIP17 = !!process.env.CHIP17 || true +const LISTEN_PORT = process.env.PORT || 9001 + +let switches = new MCP230XXi([9,10],{id:'switches', chip17:CHIP17, path:PATH, host:HOST, port:PORT, address:ADDRESS, iport:LISTEN_PORT}) + +// switches.registerSocket('interrupt','c','t',{host:'switchesd.local', port:1777}) + +; +(async () => { + + if (process.env.VERBOSE==='true') { + + switches.on('log', async log => { + if (log.level!=='trace') { + console.log( + 'LOG:',log.level,':', + log.msg, + 'socket:',log.socketName, + ) + if (log.packet) console.dir(log.packet) + } + }) + + switches.on('connection:socket', async ev => { + console.log('connection event: outbound > ', ev.state,'to socket',ev.socketName)// if (ev.state ==='connected') switches.duplex = true + }) + + switches.on('connection:consumer', async ev => { + // console.log(ev) + console.log('connection event: inbound >', ev.state,'from consumer',ev.name)// if (ev.state ==='connected') switches.duplex = true + }) + + } + + console.log('ready observers for switches', switches.ready.observerNames) + + switches.ready.addObserverDetails('bus',{msg:'this is some details related to bus observer'}) + + + switches.ready.subscribe(x=>{ + console.log('=====================switches ready================?',x ? 'YES':'NO') + console.log('what has failed: ',switches.ready.failure,' details:', switches.ready.details.get(switches.ready.failure)||'none') + }) + + // this.ready.subscribe('interrupt:connected',(res)=>console.log('interrupt connected............',res)) + // this.ready.subscribe('mcp',(res)=>console.log('mcp............',res)) + // this.ready.subscribe('interrupt:reset',(res)=>console.log('interrupt reset............',res)) + + let res = await switches.socketsInit() + if (res.errors) console.log(res) + +})().catch(err => { + console.error('FATAL: UNABLE TO START SYSTEM!\n',err) +}) diff --git a/package.json b/package.json index 47d819b..242ddcd 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "@uci/mcp", "main": "src", - "version": "0.1.37", + "version": "0.1.38", "description": "Classes and Helper Functions for using the MCP chip on I2C Bus", "scripts": { - "relays": "node -r esm examples/relays", + "outputs": "./node_modules/.bin/nodemon -r esm --preserve-symlinks examples/outputs", + "switches": "./node_modules/.bin/nodemon -r esm --preserve-symlinks examples/switches", "swrl": "UCI_ENV=dev node -r esm examples/mcp-switch-relay", "swr": "node -r esm examples/mcp-switch-relay", "test": "./node_modules/.bin/mocha --reporter list --timeout 30000", @@ -28,9 +29,16 @@ }, "homepage": "https://github.com/uCOMmandIt/uci-mcp#readme", "dependencies": { - "@uci/i2c-device": "^0.1.21", - "@uci-utils/logger": "^0.0.15", - "@uci-utils/byte": "^0.2.3" + "@uci-utils/bind-funcs": "^0.2.4", + "@uci-utils/byte": "^0.2.3", + "@uci-utils/logger": "0.0.15", + "@uci-utils/ready": "^0.1.2", + "@uci/base": "^0.1.36", + "@uci/i2c-device": "^0.1.24", + "@uci/logger": "0.0.6", + "@uci/socket": "^0.2.28", + "is-plain-object": "^3.0.0", + "merge-anything": "^2.4.4" }, "devDependencies": { "chai": "^4.2.0", diff --git a/src/commands.js b/src/commands.js index 3c2c398..4187c85 100644 --- a/src/commands.js +++ b/src/commands.js @@ -4,7 +4,6 @@ import logger from '@uci-utils/logger' let log = logger({file:'/src/commands.js', package:'@uci/mcp'}) - // TODO add uci debug logging export default { @@ -37,7 +36,7 @@ export default { } }, - // Individual Pin Configurations + // Pin(s) Configurations // set is for cfg: 'custom' assume a setting is zero unless given // packet = { pin:, port:, cfg: , set:{dir: 0, ivrt: 0, pullup: 0, intr: 0, usedef: 0,defval: 0} } // first get the current byte (pin) state for that setting @@ -45,9 +44,9 @@ export default { cfg: async function(packet){ let cfg = {} let reply = { cmd:'reply', status:{} } - packet.cfg = packet.cfg || 'output' - if (packet.cfg==='custom') cfg = packet.set - else cfg = PIN.cfgset[packet.cfg] + packet.config = packet.config || packet.cfg || 'output' + if (packet.config==='custom') cfg = packet.set + else cfg = PIN.cfgset[packet.config] for(let name of Object.keys(PIN.setting)) { let op = cfg[name] ? 'on' : 'off' log.debug({cmd:'pin.cfg', line:28, msg:'setting pin register', operation:op, registerName:name, resgisterNum:PIN.setting[name]}) @@ -58,31 +57,40 @@ export default { return reply }, - // state is equivalent to read + cfgs: async function({configs}){ + let res = await Promise.all(configs.map(config => this.commands.pin.cfg(config))) + let error = res.reduce((err,cfg) => {return (err || !!cfg.error)},false) + return ({error:error, res:res}) + }, + + // status is equivalent to read status: async function (packet) { + if(!this.chip17 && packet.port==='B') return {error:'sent request for port B. No such port on MCP2008'} let reg = packet.reg ? PIN.cmd[packet.reg] : PIN.cmd.gpio if (!reg) return {error:`unknown register ${packet.reg}`, packet:packet } - let reply = { cmd:'reply'} - let pins = parsePins(packet.pins) + let pins = parsePins(packet.pins || packet.pin) let state = new _.Byte() let bus = await this.bus.read(sreg(reg, packet.port)) if (bus.error) return bus state.value = bus.response - reply.status = - { port:state.toFmt('ARY'), - pins: pins.value.map(pin => { - if (state.toFmt('PLC').indexOf(pin) !==-1) return [pin, 'on'] - else return [pin,'off'] - }) - } + let reply = { + port:state.toFmt('ARY'), + pins: pins.value.map(pin => { + if (state.toFmt('PLC').indexOf(pin) !==-1) return [pin, 'on'] + else return [pin,'off'] + }) + } + if (packet.pin) reply.state = reply.pins[0][1] return reply }, _state: async function(packet,op,reg){ + if(!this.chip17 && packet.port==='B') return {error:'sent request for port B. No such port on MCP2008'} reg = (reg!==undefined)? reg : PIN.cmd.gpio log.debug({cmd:'pin._state', line:82, msg:'_state change request', operation:op, register:reg, packet:packet}) let reply = { cmd:'reply'} - let pins = parsePins(packet.pins) + let pins = parsePins(packet.pins || packet.pin) let state = new _.Byte() + // TODO support setting state on both ports if non given let bus = await this.bus.read(sreg(reg,packet.port)) if (bus.error) return bus state.value = bus.response diff --git a/src/mcp230xx.js b/src/mcp230xx.js index 50a56a7..a65d260 100644 --- a/src/mcp230xx.js +++ b/src/mcp230xx.js @@ -1,7 +1,5 @@ -import Device from '@uci/i2c-device' -// import Device from '../../uci-i2c-device/src/device-packet' +import { I2CDevice as Device, map, changed, isPlainObject, to, merge} from '@uci/i2c-device' import commands from './commands' - import logger from '@uci-utils/logger' let log = {} @@ -16,32 +14,30 @@ class MCP230XX extends Device { }) this.chip17 = opts.chip17 this.chipCfg = opts.chipCfg || 'default' - // this._configured = false + this.pinsCfg = opts.pinsCfg || this.chip17 ? [{port:'A', pins:'all'},{port:'B', pins:'all'}] : [{pins:'all'}] + this.commands = this.bindFuncs(commands) this.addNamespace('commands', 's') // allow access to commands via socket/server - // this._pin = this.commands.pin // add a simplier reference for local access - // this._chipcfg = this.commands.chip.cfg // add a simplier reference for local access - this.once('ready:i2c', () =>{ - this.configure() - if (this._ready) this._ready.call(this) - }) - } - async registerReadyFunc(func) { - this._ready = func - } + if (opts.lport) this.registerSocket('mcp-t','s','t',{port:opts.lport}) + if (opts.lpath) this.registerSocket('mcp-n','s','n',{path: opts.lpath}) + + this.ready.addObserver('mcp',this.ready.getObserver('i2c').pipe( + map(async ready => { + if (ready) { + let res = await this.commands.chip.cfg({cfg:this.chipCfg}) + if (!res.error) { + let res = await this.commands.pin.cfgs({configs:this.pinsCfg}) + return res.error? false :true + } return false + } + return false + }) + )) + + } // end contructor - async configure() { - let res = await this.commands.chip.cfg({cfg:this.chipCfg}) - if (res.error) { - let err={level:'fatal', msg:'unable to configure mcp chip', error:res.error, cfg:this.chipCfg, address:this.address} - log.fatal(err) - this.emit('status', err) - } else { - this.emit('status', {level:'info', msg:'mcp chip was properly configured', cfg:this.chipCfg}) - this.emit('ready:mcp') - } - } } // end of MCP230XX Class export default MCP230XX +export {MCP230XX, map, changed, isPlainObject, to, merge} diff --git a/src/mcp230xxi.js b/src/mcp230xxi.js index fa89d58..804276e 100644 --- a/src/mcp230xxi.js +++ b/src/mcp230xxi.js @@ -1,5 +1,6 @@ -import MCP230XX from './mcp230xx' +import {MCP230XX, map, changed, isPlainObject, to, merge} from './mcp230xx' import { byteFormat } from '@uci-utils/byte' +// import Ready from '@uci-utils/ready' import logger from '@uci-utils/logger' let log = {} @@ -17,11 +18,11 @@ class MCP230XXi extends MCP230XX { if (!Array.isArray(pins)) { options = pins; pins = options.interrupt.pins} // if pins sent via .interrupt.pins let opts = Object.assign({},options) // don't allow passed options to mutate if (opts.interrupt) delete opts.interrupt.pins // if .interrupt was passed then .pins must be removed - delete opts.sockets // .sockets is used by uci base so clear it if was used by enduser and sent by mistake log.debug({method:'constructor', line:21, msg:'passed options before setting',options:opts}) + opts.lport = opts.lport || (opts.interrupt || {}).port || opts.iport + if (!opts.lport) opts.lpath = opts.lpath || (opts.interrupt || {}).ipath || opts.ipath || 'interrupt' // must has a socket litener for interrupt process super(opts) - this.opts = opts - + this.pinsCfg = opts.pinsCfg || this.chip17 ? [{port:'A', pins:'all', cfg:'input_interrupt'},{port:'B', pins:'all', cfg:'input_interrupt'}] : [{pins:'all', cfg:'input_interrupt'}] log = logger({ file: 'src/mcp230xxi.js', class: 'MCP230XXi', @@ -29,127 +30,116 @@ class MCP230XXi extends MCP230XX { id: this.id }) - log.debug({ method:'constructor', line:32, opts: opts, msg:'mcp interrupt options after calling super() on base'}) - - pins.forEach(pin => { + pins.forEach((pin,index) => { this[pin] = opts['i' + pin] || {} + this[pin].mport = this[pin].mport || index ? 'B' : 'A' }) this.pins = pins this.commands.interrupt = this.bindFuncs(icommands) // add interrupt pin commands to base set in "command.js" - this.addNamespace('commands', 'c') // add access via push to same commands - this._interruptProcess = process - this.ready = false - log.debug({ opts: opts, pins: pins }, 'options for mcp interrupt processor') - } + this._interruptProcess = process.bind(this) // default processor - async init() { - if (this.ipath) await this.addSocket('inter-n','s','n',{path:this.ipath}) - if (this.iport) await this.addSocket('inter-t','s','t',{port:this.iport}) - await super.init() - // this will set default type to internal pullup, only need to to change indivial pins to external if desired - await this.commands.pin.cfg({port:'A',pins:'all',cfg:'input_interrupt'}) - let status = await this._resetInterrupt('A') - log.debug({method:'init', line:52, msg:'default configure all port A pins as interrupts. Resetting port A interrupt', status:status}) - if (this.chip17) { - await this.commands.pin.cfg({port:'B',pins:'all',cfg:'input_interrupt'}) - let status = await this._resetInterrupt('B') - log.debug({method:'init', line:52, msg:'default configure all port B pins as interrupts. Resetting port B interrupt', status:status}) - } - } - async _readyInterrupt(port) { - let istate = await this.bus.read(port !== 'B' ? 0x07 : 0x17) - if (istate.response) { - this.ready = false + + const conditionHandler = async ev => { + if ((ev||{}).state ==='connected'){ + let data = (ev.data ||{}) + if (data.type === 'interrupt' || [ev.name, data.name, data.id].some(name => (name||'').includes('interrupt')) ) { + return true + } + } return false } - else { - this.ready = true - return true - } + + this.ready.addObserver('interrupt:connected',this.getSocket(`mcp-${opts.lport? 't':'n'}`),{event:'connection:consumer',condition:conditionHandler}) + + this.ready.addObserver('interrupt:reset',this.ready.combineObservers(['mcp','interrupt:connected']).pipe( + map(async ready=>{ + if (ready) return await this.resetInterrupt() + return false + }) + )) + } // end constructor + + async interruptState(pin) { + let istate = await this.bus.read(this.getPort(pin) !== 'B' ? 0x07 : 0x17) + let pullup = (this.chipCfg||'').includes('Pullup') ? true : false + let state = istate.response ? true && pullup : false || !pullup + return state } - async _resetInterrupt(port) { - await this.bus.read(port !== 'B' ? 0x08 : 0x18) // 0x08 is intcap interrupt capture register - log.debug({method:'_resetInterrupt', line:72, msg: `reset interrupt for port ${port || 'A'},${this.id} arg ${port !== 'B' ? 0x08 : 0x18}`}) - return(await this._readyInterrupt(port)) + async resetInterrupt(pins) { + if (!Array.isArray(pins)) pins = pins ? [pins] : this.pins + this._ireset = (await Promise.all(pins.map(async pin => { + await this.bus.read(this.getPort(pin) !== 'B' ? 0x08 : 0x18) // 0x08 is intcap interrupt capture register + return(await this.interruptState(pin)) + }) + )).reduce((res,val) => res && val) + return this._ireset } - _getPortByPin(pin) { - let port = this[pin] ? this[pin].mport : null - let index = this.pins.map(pin => pin.toString()).indexOf(pin.toString()) - port = port || index <= 0 ? 'A' : 'B' - return port + getPort(pin) { + if (pin==='A' || pin==='B') return pin + return this[pin].mport } - interruptProcessor(func) { - this._interruptProcess = func + registerInterruptProcessor(func) { + this._interruptProcess = func.bind(this) } } // end of MCP230XXi Class export default MCP230XXi +export { MCP230XXi, map, changed, isPlainObject, to, merge} // default processor function process(details) { details.id = this.id console.log('----default interrupt processor for mcp instance----') - console.log('here is where you could either locally take some action for send/push on a message to another process') + console.log('here is where you could either locally take some action or send on a message to another process') console.log('create your own function and register it with .interruptProcesser(function)') console.log(this.id) console.dir(details) + console.log('------------------------------------------') } // commands to be added to pin packet command functions const icommands = { + status: async function(packet) { - // pin is interrupt pin on sbc for port - let port = packet.port || this._getPortByPin(packet.pin) - let res = await this._readyInterrupt(port) - return {cmd:'reply', request:'interrupt.status', port:port, ipin:packet.pin, ready:res} + let pin = packet.ipin || packet.pin + let state = await this.interruptState(pin) + return {cmd:'reply', request:'interrupt.status', port:this.getPort(pin), ipin:pin, ready:state} }, reset: async function(packet) { - // pin is interrupt pin on sbc for port - let port = packet.port || this._getPortByPin(packet.pin) - log.error({cmd:'interrupt.reset', line:114, packet: packet, port:port, msg:`forced remote interrupt reset for port ${port}`}) - await this._resetInterrupt(port) - let res = await this._readyInterrupt(port) - return {cmd:'reply', request:'interrupt.reset', port:port, ipin:packet.pin, ready:res} + let pin = packet.ipin || packet.pin + let state = await this.resetInterrupt(pin) + let res = {level:state ? 'debug':'error', msg:`remote reset request from ${packet._header.sender.instanceID} for pin ${pin}: ${state?'ready': 'error'}` } + this.emit('log',res) + return {state:state} }, - // given a gpio interrupt then push a packet with cmd: 'pin.interrupt.find' and pin: the gpio pin number + // finds which mcp pin caused the interrupt find: async function(inter) { - if (this.ready) { - // protects tripped interrupt before it's fully initialized, or interrupt requests arriving before porcessing is complete - this.ready = false - log.debug({cmd:'interrupt.find', line:124, msg:'raw packet from interrupt, finding pin that caused interrupt', inter:inter}) - let packet = { pins: 'all', reg: 'intf' } - packet.port = inter.port || this._getPortByPin(inter.pin) - let res = await this.commands.pin.status(packet) // read port interrupt status - let status = await this._resetInterrupt(packet.port) - this.ready = true - log.debug({cmd:'interrupt.find', line:130, interrupt:res, reset:status, msg:'interrupt read and reset'}) - if (!res.status) { + let ipin = inter.ipin || inter.pin + if (!await this.interruptState(ipin)) { // if it's already reset then this is false trip + let res = await this.commands.pin.status({ pins: 'all', reg: 'intf', port:this.getPort(ipin) }) // read port interrupt status + let status = await this.resetInterrupt(ipin) // now reset + let pin = byteFormat(res.port||[], { in: 'ARY', out: 'PLC' })[0] + if (!pin) { log.warn({cmd:'interrupt.find', line:132, inter:inter, msg:'no pin associated with interrupt'}) return { error: 'no pin associated with interrupt' } } - let pin = byteFormat(res.status.port, { in: 'ARY', out: 'PLC' }) - res.pin = pin[0] - packet.pins = pin[0] - packet.reg = null - if (packet.pins) { // avoid bad interrupt (i.e. no pin caused interrupt) - res.ipin = inter.pin - res.port = packet.port - delete inter.cmd; delete inter._header; delete inter.pin - Object.assign(res,inter) - delete res.status - res.interrupt_ready = status || false - res.state = (await this.commands.pin.status(packet)).status.pins[0][1] - this._interruptProcess(res) - return res - } else { - log.warn({cmd:'interrupt.find', line:151, inter:inter, msg:'no pin associated with interrupt'}) - return { error: 'no pin associated with interrupt' } + else { // avoid bad interrupt (i.e. no pin caused interrupt) + delete inter.cmd; delete inter._header + inter.ipin = ipin + inter.pin = pin + inter.port = this[ipin].mport + inter.interrupt_ready = status + inter.state = (await this.commands.pin.status({pin:pin, port:this.getPort(ipin)})).state + this._interruptProcess(inter) + // replying with reset command which is also a check + return {cmd:'reset', pin:ipin} } } } -} + +} // end commands