ltv-bridge.js 3.63 KiB
import WSSPipe from './wss-pipe.js'
const TS = require('./typeset.js')
const SerialPort = require('serialport')
const ByteLength = require('@serialport/parser-byte-length')
// this has a local store of vent data
let store = []
let indice = 0
// setup conn to browser: happens in WSSPipe
WSSPipe.start().then((ws) => {
//ws.send(data) available
ws.onmessage = (msg) => {
msg = JSON.parse(msg.data)
if(msg.type == "plot update request"){
let resp = { type: "plot update" }
// msg.lastRecvdIndice
if(msg.lastRecvdIndice > indice){ // something wrapped, just set to zero
msg.lastRecvdIndice = 0
} else if (msg.lastRecvdIndice + 500 < indice){ // missed more than 500 data pts, reset
msg.lastRecvdIndice = indice - 500
}
// find indice (by identifier) of the requested
let ind = store.find((elem) => {
return (elem[0] == msg.lastRecvdIndice)
})
if(ind){
resp.array = store.slice(ind)
} else {
resp.array = []
}
ws.send(JSON.stringify(resp))
}
}
ws.onerror = (err) => {
console.log('wss error', err)
}
ws.onclose = (evt) => {
// because this local script is remote-kicked,
// we shutdown when the connection is gone
console.log('wss closes, exiting')
process.exit()
// were this a standalone network node, this would not be true
}
})
// do ltv recieve,
const port = new SerialPort('/dev/ttyAMA0', {
baudRate: 60096
})
port.on('open', () => {
console.log('open')
})
port.on('error', (err) => {
console.log(err)
})
const parser = port.pipe(new ByteLength({length: 1}))
// ok, packets are like:
/*
start (uint8) | length (uint8) | packet type (uint8) | data (len - 1) | crc (uint8) |
start byte is always 0xFA
*/
let packet = new Uint8Array(255)
let pi = 0 // packet indice (where inside of, during parse)
let pl = 0 // packet length (expected len)
let ip = false // in packet
parser.on('data', (data) => {
// read if
if(ip){
if(pi == 0){
// length byte
pl = data[0]
}
// store all bytes, increment ptr
packet[pi] = data[0]
pi ++
if(pi > pl + 1){
onPacket(packet) // pass, then ptr swap to new... shouldn't leak back
packet = new Uint8Array(255)
pi = 0
pl = 0
ip = false
}
}
// start byte / 0xFA
if(data[0] == 250 && !ip){
ip = true
pi = 0
}
})
let onPacket = (pck) => {
// now this looks like
// [0] length
// [1] packet type
// [...] data bytes
// [n] crc byte
//console.log("packet", pck)
switch(pck[1]){
case 1:
//realtime data
//[2] uint8 insp state (table of 18 states)
//[3,4] int16 prox pres (-5 to 120)
//[5,6] int16 xdcr flow (-200 to 200)
//[7,8] int16 volume (1ml res) (0 to 3000)
let data = {
inspState: TS.read('uint8', pck, 2),
proxPres: TS.read('int16', pck, 3),
xdcrFlow: TS.read('int16', pck, 5),
volume: TS.read('int16', pck, 7)
}
// seems like this works, I guess timestamp these things now and keep them around locally...
// then run a server, client should req. the local store ?
store.push([indice, data.inspState, data.proxPres, data.xdcrFlow, data.volume])
indice ++
// occasionally lop off 1000 entries, so as not to explode local memory
if(store.length > 3000){
console.log("rollover")
store = store.slice(-2000)
}
//console.log(data)
break;
default:
//not plotting others currently
break;
}
}