Skip to content
Snippets Groups Projects
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;
    }
}