const pSettle = require('p-settle') import logger from '@uci-utils/logger' let log = logger({package:'@uci/gpio', file:'/src/commands.js'}) export default { on: async function(packet) { packet.pinCmd = 'on' await this.commands.set(packet) return packet }, off: async function(packet) { packet.pinCmd = 'off' await this.commands.set(packet) return packet }, toggle: async function(packet) { packet.pinCmd = 'toggle' await this.commands.set(packet) return packet }, set: async function(packet) { packet.pinCmd = packet.pinCmd || 'set' log.debug({msg:'packet set request', packet:packet}) let pins = parsePins.call(this, packet.pins || packet.pin || packet.gpios || packet.gpio || packet.ids || packet.id ) log.debug({msg:'pins to set', packet:packet, pins:pins}) // TODO could use this but need a way to know which res item is for what pin // packet.res = await pSettle( // pins.map(async pin => { // return this.pins[pin][packet.pinCmd](packet.value) // }), {concurrency:1} // ) packet.state = {} for (let pin of pins) { packet.state[pin] = await this.pins[pin][packet.pinCmd](packet.value) } log.info({msg:'pin(s) set result', packet:packet}) packet.cmd='status' this.emit('gpios',packet) // emit locally this.push(packet) // will push on any socket return packet }, get: async function(packet) { let pins = parsePins.call(this, this, packet.pins || packet.pin || packet.gpios || packet.gpio || packet.ids || packet.id) packet.state = {} pins.forEach(pin => packet.state[pin] = this.pins[pin].get(packet.read)) packet.cmd = 'status' return packet } } const parsePins = function(pins) { if (!pins) { console.log('no pins supplied aborting') throw new Error('no pins specified in command') } if (typeof pins==='number') pins = [pins] if (typeof pins==='string') { if (pins==='all') pins = Object.keys(this.pins) else { pins = pins.split(/[,:\s]+/).map(Number).filter( (x) => !Number.isNaN(x)) } } if (pins.some(pin => !(pin in this.pins),this)) console.log('pin not available') return pins }