import i2c from 'i2c-bus' import pify from 'pify' import btc from 'better-try-catch' import Base from '@uci/base' import logger from '@uci/logger' let log = {} class I2CBus extends Base { constructor(opts) { log = logger({ name: 'i2c-bus', id: opts.id, file: 'src/bus.js', class: 'Bus' }) if (opts.path) opts.ns = { path: opts.path } if (!opts.ns) opts.ns = { path: 'i2c-bus' } opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + 'ns#s>n' if (opts.tcp) { if (typeof opts.tcp === 'number') opts.ts = { port: opts.tcp } else opts.ts = { port: 1776 } opts.sockets = (opts.sockets ? opts.sockets + ',' : '') + 'ts#s>t' } super(opts) log.info({ opts: opts }, 'created bus with these opts') this.busnum = opts.busnum || 1 this.i2cbus = i2c.open(this.busnum, () => {}) this.bus = bus_funcs // this.init = this.init.bind(this) } async init() { await super.init() } // TODO see if default processing of base can handle this now async _packetProcess(sname, packet) { if (!packet.cmd) return { error: 'no cmd: key in packet', packet: packet } if (this.bus[packet.cmd]) { let checked = validateArgs(packet) // handle with before hook if (checked.error) return checked.error let [err, res] = await btc(this.bus[packet.cmd].bind(this))(packet.args) if (err) return { error: err.msg, packet: packet } packet.response = res || '' packet.cmd = 'reply' return packet } else return { error: 'no i2c bus function available for packet command', packet: packet } } } // end of Bus Packet Class export default I2CBus const validateArgs = function(packet) { let missing = [] const ne = arg => { if (packet.args[arg] === undefined) missing.push(arg) } if (packet.cmd === 'scan' || packet.cmd === 'close') return {} ne('address') switch (packet.cmd) { case 'readRaw': case 'writeRaw': ne('length') ne('buffer') break case 'read': case 'read2': case 'write': case 'write2': ne('cmd') } switch (packet.cmd) { case 'write': case 'write2': case 'send': ne('byte') } if (missing.length > 0) { return { error: `following bus arguments are missing ${missing}`, packet: packet } } return {} } const bus_funcs = { scan: function() { return pify(this.i2cbus.scan).bind(this.i2cbus)() }, close: function() { return pify(this.i2cbus.close).bind(this.i2cbus)() }, readRaw: function(args) { return pify(this.i2cbus.i2cRead).bind(this.i2cbus)( args.address, args.length, args.buffer ) }, writeRaw: function(args) { return pify(this.i2cbus.i2cWrite).bind(this.i2cbus)( args.address, args.length, args.buffer ) }, read: function(args) { // console.log('read: address, cmd', address, cmd) return pify(this.i2cbus.readByte).bind(this.i2cbus)(args.address, args.cmd) }, write: function(args) { // console.log('write: address, cmd, byte', args.address, args.cmd, args.byte) return pify(this.i2cbus.writeByte.bind(this.i2cbus))( args.address, args.cmd, args.byte ) }, read2: function(args) { return pify(this.i2cbus.readWord.bind(this.i2cbus))(args.address, args.cmd) }, write2: function(args) { return pify(this.i2cbus.writeWord.bind(this.i2cbus))( args.address, args.cmd, args.byte ) }, receive: function(args) { // console.log('receivebyte', address) return pify(this.i2cbus.receiveByte.bind(this.i2cbus))(args.address) }, send: function(args) { // console.log('sendbyte', address,byte) return pify(this.i2cbus.sendByte.bind(this.i2cbus))(args.address, args.byte) } } //end i2c functions