add process observer
make combination observer outbound consumer to bus and bus process
  make new observer which is an extention of that to device ack the bus
commands.js
  all custom socket name (option) for bus  .i2cbus
master
David Kebler 2020-01-18 22:20:16 -08:00
parent 390e4d1854
commit da16dded9e
3 changed files with 35 additions and 32 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@uci/i2c-device",
"version": "0.1.25",
"version": "0.1.26",
"description": "Device Classes for I2C Interfacing",
"main": "src/device",
"scripts": {

View File

@ -4,7 +4,7 @@ export default {
ack: async function (){
// TODO if mux channel used check it as well
let bus = await this.send('bus',{ cmd:'scan'})
let bus = await this.send(this.i2cbusName,{ cmd:'scan'})
if (bus.error) return bus
let res = { cmd:'reply', ack: false, address:this.address, scan:bus.response}
if (bus.response.indexOf(+this.address) !== -1) res.ack = true
@ -13,44 +13,44 @@ export default {
receive: async function() {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'receive', args: {address:this.address}})
return await this.send(this.i2cbusName,{ cmd:'receive', args: {address:this.address}})
},
send: async function(byte) {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'send', args: {address:this.address, byte:byte }})
return await this.send(this.i2cbusName,{ cmd:'send', args: {address:this.address, byte:byte }})
},
// for devices needing a buffer/stream
readRaw: async function (length, buffer) {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'readRaw', args: {address:this.address, length:length, buffer:buffer }})
return await this.send(this.i2cbusName,{ cmd:'readRaw', args: {address:this.address, length:length, buffer:buffer }})
},
writeRaw: async function (length, buffer) {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'writeRaw', args: {address:this.address, length:length, buffer:buffer }})
return await this.send(this.i2cbusName,{ cmd:'writeRaw', args: {address:this.address, length:length, buffer:buffer }})
},
// both cmd and byte should be a single byte as a decimal or hex
read: async function (cmd) {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'read', args: {address:this.address, cmd:cmd }})
return await this.send(this.i2cbusName,{ cmd:'read', args: {address:this.address, cmd:cmd }})
},
write: async function (cmd, byte) {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'write', args: {address:this.address, cmd:cmd, byte:byte }})
return await this.send(this.i2cbusName,{ cmd:'write', args: {address:this.address, cmd:cmd, byte:byte }})
},
// for I2C devices that use a word length packackage
read2: async function (cmd) {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'read2', args: {address:this.address, cmd:cmd }})
return await this.send(this.i2cbusName,{ cmd:'read2', args: {address:this.address, cmd:cmd }})
},
write2: async function (cmd, bytes) {
if (this.channel) await this._setChannel()
return await this.send('bus',{ cmd:'write2', args: {address:this.address, cmd:cmd, byte:bytes }})
return await this.send(this.i2cbusName,{ cmd:'write2', args: {address:this.address, cmd:cmd, byte:bytes }})
}
}

View File

@ -5,40 +5,43 @@ let log = {}
class I2CDevice extends Base {
constructor(opts) {
// opts.ndevice = opts.ndevice || {}
// opts.tdevice = opts.tdevice || {}
// opts.ndevice.path = opts.ndevice.path || opts.path || 'i2c-device'
// opts.tdevice.port = opts.tdevice.port || opts.port || 1777
opts.bus = opts.bus || Object.assign({},{host:opts.host, port:opts.port, path:opts.path})
if (opts.bus.host) opts.bus.port = opts.bus.port || 1776
else opts.bus.path = opts.bus.path || 'i2c-bus'
super(opts)
this.registerSocket('bus','c',opts.bus.host ? 't':'n',opts.bus)
// this.addSocket(opts.tdevice.name ||'device:tcp','s','t',opts.tdevice)
// this.addSocket(opts.ndevice.name ||'device:np','s','n',opts.ndevice)
log = logger({
file: 'src/device-packet.js',
class: 'Device',
name: 'i2c-device',
id: this.id
id: opts.id
})
if (!opts.address) log.fatal({ opts: opts, method:'constructor', line:26, msg:'no i2c bus address supplied'})
if (!opts.address) {
log.fatal({ opts: opts, method:'constructor', line:26, msg:'no i2c bus address supplied'})
throw new Error(`no i2c bus address supplied for device ${opts.id}:${opts.name}`)
}
opts.i2cbus = opts.i2cbus || { name:opts.name||'i2c-bus', type:'c', transport:'n', options:{name:opts.name ||'i2c-device', path:opts.path||'i2c-bus'}}
if ((opts.i2cbus.options || {}).host) opts.i2cbus.options.port = opts.i2cbus.options.port || 1776
else opts.i2cbus.options.path = opts.i2cbus.options.path || 'i2c-bus'
// console.log('+++++++++++++++++++++++BUS OPTIONS FOR CONSUMER SOCKET+++++++++++++++++')
// console.dir(opts.i2cbus)
super(opts)
this.registerSocket(opts.i2cbus)
this.address = +opts.address // make sure any passed number is number not a string
this.channel = +opts.channel // if using TAC9546A channel number on which device is attached
this.i2cbusName = opts.i2cbus.name || 'bus'
this.bus = this.bindFuncs(commands)
// todo don't override ack this way in case _s moves
this._s.ack = async (packet) => { return Object.assign(packet,await this.bus.ack()) } // give socket access to bus.ack
// emit on connected and available
this.ready.addObserver('i2c',this.ready.getObserver('bus').pipe(
map(async ready => {
if (ready) return (await this.bus.ack()).ack
return false
})
// ,
// map(() => {return false})
))
this.ready.addObserver(`${opts.i2cbus.name}:process`) // will emit on received <bus>:process ready packet
let busobs = this.ready.combineObservers(`${opts.i2cbus.name}`,[`${opts.i2cbus.name}:consumer`,`${opts.i2cbus.name}:process`])
// make device ack by extending bus observer
this.ready.addObserver('i2c:device:ack',busobs
.pipe(
map(async ready => {
if (ready) return (await this.bus.ack()).ack
return false
})
)
)
} // end contructor