Unmarshal messages client side
This commit is contained in:
		
							
								
								
									
										1306
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1306
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -33,7 +33,8 @@
 | 
			
		||||
		"tailwindcss": "^3.4.3",
 | 
			
		||||
		"tslib": "^2.4.1",
 | 
			
		||||
		"typescript": "^5.0.0",
 | 
			
		||||
		"vite": "^5.0.3"
 | 
			
		||||
		"vite": "^5.0.3",
 | 
			
		||||
		"vite-plugin-node-polyfills": "^0.22.0"
 | 
			
		||||
	},
 | 
			
		||||
	"type": "module",
 | 
			
		||||
	"dependencies": {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,44 @@
 | 
			
		||||
export interface MarshalledMessage {
 | 
			
		||||
	id: number;
 | 
			
		||||
	ext: boolean;
 | 
			
		||||
	canfd: boolean;
 | 
			
		||||
	data: number[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type RawMessage = {
 | 
			
		||||
	ext?: boolean;
 | 
			
		||||
	canfd?: boolean;
 | 
			
		||||
	id: number;
 | 
			
		||||
	data: Buffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function marshalMessage(msg: RawMessage): MarshalledMessage {
 | 
			
		||||
	return {
 | 
			
		||||
		id: msg.id,
 | 
			
		||||
		ext: msg.ext ?? false,
 | 
			
		||||
		canfd: msg.canfd ?? false,
 | 
			
		||||
		data: Array.from(msg.data)
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function unmarshalMessage(msg: MarshalledMessage): RawMessage {
 | 
			
		||||
	return {
 | 
			
		||||
		id: msg.id,
 | 
			
		||||
		ext: msg.ext,
 | 
			
		||||
		canfd: msg.canfd,
 | 
			
		||||
		data: Buffer.from(msg.data)
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface AMSMessage {
 | 
			
		||||
	type: 'error' | 'status' | 'slaveStatus' | 'slaveLog' | 'shuntCurrentLog' | 'shuntVoltage1Log' | 'shuntVoltage2Log';
 | 
			
		||||
	type:
 | 
			
		||||
		| 'error'
 | 
			
		||||
		| 'status'
 | 
			
		||||
		| 'slaveStatus'
 | 
			
		||||
		| 'slaveLog'
 | 
			
		||||
		| 'shuntCurrentLog'
 | 
			
		||||
		| 'shuntVoltage1Log'
 | 
			
		||||
		| 'shuntVoltage2Log';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface AMSError extends AMSMessage {
 | 
			
		||||
@ -74,3 +113,170 @@ export interface ShuntLog extends AMSMessage {
 | 
			
		||||
 | 
			
		||||
	value: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
import { N_CELLS_PER_SLAVE, N_TEMP_SENSORS_PER_SLAVE } from '$lib/defs';
 | 
			
		||||
 | 
			
		||||
export const CAN_ID_AMS_ERROR = 0x00c;
 | 
			
		||||
export const CAN_ID_AMS_STATUS = 0x00a;
 | 
			
		||||
export const CAN_ID_AMS_SLAVE_STATUS_BASE = 0x080;
 | 
			
		||||
export const CAN_ID_AMS_SLAVE_STATUS_MASK = 0xff0;
 | 
			
		||||
export const CAN_ID_AMS_SLAVE_LOG_BASE = 0x600;
 | 
			
		||||
export const CAN_ID_AMS_SLAVE_LOG_MASK = 0xf00;
 | 
			
		||||
export const CAN_ID_SHUNT_CURRENT = 0x521;
 | 
			
		||||
export const CAN_ID_SHUNT_VOLTAGE_1 = 0x522;
 | 
			
		||||
export const CAN_ID_SHUNT_VOLTAGE_2 = 0x523;
 | 
			
		||||
 | 
			
		||||
function decodeError(msg: RawMessage): AMSError | null {
 | 
			
		||||
	if (msg.data.length != 2) {
 | 
			
		||||
		console.warn('invalid error frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	console.log('error', msg);
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	return {
 | 
			
		||||
		type: 'error',
 | 
			
		||||
		kind: data[0],
 | 
			
		||||
		arg: data[1]
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeStatus(msg: RawMessage): AMSStatus | null {
 | 
			
		||||
	if (msg.data.length != 8) {
 | 
			
		||||
		console.warn('invalid status frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	return {
 | 
			
		||||
		type: 'status',
 | 
			
		||||
		state: data[0] & 0x7f,
 | 
			
		||||
		sdcClosed: !!(data[0] & 0x80),
 | 
			
		||||
		soc: data[1],
 | 
			
		||||
		minCellVolt: data.readUInt16BE(2) * 1e-3,
 | 
			
		||||
		maxCellTemp: data.readUInt16BE(4) * 0.0625,
 | 
			
		||||
		imdOK: !!(data[6] & 0x80)
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeSlaveStatus(msg: RawMessage): SlaveStatus | null {
 | 
			
		||||
	if (msg.data.length != 8) {
 | 
			
		||||
		console.warn('invalid slave status frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	return {
 | 
			
		||||
		type: 'slaveStatus',
 | 
			
		||||
 | 
			
		||||
		slaveId: data[0] & 0x7f,
 | 
			
		||||
		error: !!(data[0] & 0x80),
 | 
			
		||||
		soc: data[1],
 | 
			
		||||
		minCellVolt: data.readUInt16BE(2) * 1e-3,
 | 
			
		||||
		maxCellVolt: data.readUInt16BE(4) * 1e-3,
 | 
			
		||||
		maxTemp: data.readUInt16BE(6) * 0.0625
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeSlaveLog(msg: RawMessage): SlaveLog | null {
 | 
			
		||||
	if (msg.data.length != 8) {
 | 
			
		||||
		console.warn('invalid slave log frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const slaveId = (msg.id & 0xf0) >> 4;
 | 
			
		||||
	const logIndex = msg.id & 0x00f;
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	if (logIndex < N_CELLS_PER_SLAVE / 4) {
 | 
			
		||||
		const startIndex = logIndex * 4;
 | 
			
		||||
		const voltages = [];
 | 
			
		||||
		for (let i = 0; i < 4; i++) {
 | 
			
		||||
			voltages.push(data.readUInt16BE(2 * i) * 1e-3);
 | 
			
		||||
		}
 | 
			
		||||
		const msg: SlaveLogVoltage = {
 | 
			
		||||
			type: 'slaveLog',
 | 
			
		||||
			slaveId,
 | 
			
		||||
 | 
			
		||||
			logType: 'voltage',
 | 
			
		||||
			startIndex,
 | 
			
		||||
			voltages: voltages as [number, number, number, number]
 | 
			
		||||
		};
 | 
			
		||||
		return msg;
 | 
			
		||||
	} else if (logIndex == N_CELLS_PER_SLAVE / 4) {
 | 
			
		||||
		const msg: SlaveLogLastCell = {
 | 
			
		||||
			type: 'slaveLog',
 | 
			
		||||
			slaveId,
 | 
			
		||||
 | 
			
		||||
			logType: 'lastCell',
 | 
			
		||||
			voltage: data.readUInt16BE(0) * 1e-3,
 | 
			
		||||
			failed_temp_sensors: data.readInt32BE(2)
 | 
			
		||||
		};
 | 
			
		||||
		return msg;
 | 
			
		||||
	} else if (logIndex < N_CELLS_PER_SLAVE / 4 + 1 + N_TEMP_SENSORS_PER_SLAVE / 8) {
 | 
			
		||||
		const temperatures = [];
 | 
			
		||||
		for (let i = 0; i < 8; i++) {
 | 
			
		||||
			temperatures.push(data.readInt8(i) * 1);
 | 
			
		||||
		}
 | 
			
		||||
		const msg: SlaveLogTemperature = {
 | 
			
		||||
			type: 'slaveLog',
 | 
			
		||||
			slaveId,
 | 
			
		||||
 | 
			
		||||
			logType: 'temperature',
 | 
			
		||||
			startIndex: (logIndex - N_CELLS_PER_SLAVE / 4 - 1) * 8,
 | 
			
		||||
			temperatures: temperatures as [number, number, number, number, number, number, number, number]
 | 
			
		||||
		};
 | 
			
		||||
		return msg;
 | 
			
		||||
	} else {
 | 
			
		||||
		console.warn('Unknown slave log index', msg.id);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeShunt(msg: RawMessage, type: ShuntLog['type']): ShuntLog | null {
 | 
			
		||||
	if (msg.data.length != 6) {
 | 
			
		||||
		console.warn('invalid shunt log frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		type: type,
 | 
			
		||||
		value: msg.data.readInt32BE(2) * 1e-3
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function decodeMessage(msg: RawMessage): AMSMessage | null {
 | 
			
		||||
	if (msg.ext || msg.canfd) {
 | 
			
		||||
		console.warn('invalid message', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	let message: AMSMessage | null = null;
 | 
			
		||||
 | 
			
		||||
	if ((msg.id & CAN_ID_AMS_SLAVE_STATUS_MASK) == CAN_ID_AMS_SLAVE_STATUS_BASE) {
 | 
			
		||||
		message = decodeSlaveStatus(msg);
 | 
			
		||||
	} else if ((msg.id & CAN_ID_AMS_SLAVE_LOG_MASK) == CAN_ID_AMS_SLAVE_LOG_BASE) {
 | 
			
		||||
		message = decodeSlaveLog(msg);
 | 
			
		||||
	} else {
 | 
			
		||||
		switch (msg.id) {
 | 
			
		||||
			case CAN_ID_AMS_ERROR:
 | 
			
		||||
				message = decodeError(msg);
 | 
			
		||||
				break;
 | 
			
		||||
			case CAN_ID_AMS_STATUS:
 | 
			
		||||
				message = decodeStatus(msg);
 | 
			
		||||
				break;
 | 
			
		||||
			case CAN_ID_SHUNT_CURRENT:
 | 
			
		||||
				message = decodeShunt(msg, 'shuntCurrentLog');
 | 
			
		||||
				break;
 | 
			
		||||
			case CAN_ID_SHUNT_VOLTAGE_1:
 | 
			
		||||
				message = decodeShunt(msg, 'shuntVoltage1Log');
 | 
			
		||||
				break;
 | 
			
		||||
			case CAN_ID_SHUNT_VOLTAGE_2:
 | 
			
		||||
				message = decodeShunt(msg, 'shuntVoltage2Log');
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				console.warn(`unknown message id ${msg.id}`, msg);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,15 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
	import type { AMSError, AMSMessage, AMSStatus, SlaveLog, SlaveStatus, ShuntLog } from '$lib/messages';
 | 
			
		||||
	import {
 | 
			
		||||
		type AMSError,
 | 
			
		||||
		type AMSMessage,
 | 
			
		||||
		type AMSStatus,
 | 
			
		||||
		type SlaveLog,
 | 
			
		||||
		type SlaveStatus,
 | 
			
		||||
		type ShuntLog,
 | 
			
		||||
		type MarshalledMessage,
 | 
			
		||||
		unmarshalMessage,
 | 
			
		||||
		decodeMessage
 | 
			
		||||
	} from '$lib/messages';
 | 
			
		||||
	import { source } from 'sveltekit-sse';
 | 
			
		||||
	import MasterStatusDisplay from './master-status-display.svelte';
 | 
			
		||||
	import SlaveStatusDisplay from './slave-status-display.svelte';
 | 
			
		||||
@ -7,7 +17,6 @@
 | 
			
		||||
	import MasterErrorDisplay from './master-error-display.svelte';
 | 
			
		||||
	import { SlaveLogData } from '$lib/slave-log';
 | 
			
		||||
	import ShuntStatusDisplay from './shunt-status-display.svelte';
 | 
			
		||||
	// const value = source('/data').select('message');
 | 
			
		||||
 | 
			
		||||
	let error: AMSError | undefined;
 | 
			
		||||
	let amsStatus: AMSStatus | undefined;
 | 
			
		||||
@ -31,7 +40,11 @@
 | 
			
		||||
			if (!value) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			const msg = JSON.parse(value) as AMSMessage;
 | 
			
		||||
			const msg = decodeMessage(unmarshalMessage(JSON.parse(value) as MarshalledMessage));
 | 
			
		||||
			if (!msg) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			switch (msg.type) {
 | 
			
		||||
				case 'error':
 | 
			
		||||
					error = msg as AMSError;
 | 
			
		||||
@ -64,7 +77,11 @@
 | 
			
		||||
	<div class="vertical-wrapper">
 | 
			
		||||
		<MasterErrorDisplay {error} />
 | 
			
		||||
		<MasterStatusDisplay status={amsStatus} />
 | 
			
		||||
		<ShuntStatusDisplay currentLogData={shuntCurrentLog} voltage1LogData={shuntVoltage1Log} voltage2LogData={shuntVoltage2Log} />
 | 
			
		||||
		<ShuntStatusDisplay
 | 
			
		||||
			currentLogData={shuntCurrentLog}
 | 
			
		||||
			voltage1LogData={shuntVoltage1Log}
 | 
			
		||||
			voltage2LogData={shuntVoltage2Log}
 | 
			
		||||
		/>
 | 
			
		||||
	</div>
 | 
			
		||||
	{#each Object.entries(slaveStatus) as [id, status]}
 | 
			
		||||
		<SlaveStatusDisplay {id} {status} logData={slaveLog[id]} />
 | 
			
		||||
 | 
			
		||||
@ -1,155 +1,18 @@
 | 
			
		||||
import { produce } from 'sveltekit-sse';
 | 
			
		||||
import * as can from 'socketcan';
 | 
			
		||||
import type {
 | 
			
		||||
	AMSError,
 | 
			
		||||
	AMSMessage,
 | 
			
		||||
	AMSStatus,
 | 
			
		||||
	SlaveLog,
 | 
			
		||||
	SlaveLogLastCell,
 | 
			
		||||
	SlaveLogTemperature,
 | 
			
		||||
	SlaveLogVoltage,
 | 
			
		||||
	SlaveStatus,
 | 
			
		||||
	ShuntLog
 | 
			
		||||
import {
 | 
			
		||||
	type RawMessage,
 | 
			
		||||
	marshalMessage,
 | 
			
		||||
	CAN_ID_AMS_ERROR,
 | 
			
		||||
	CAN_ID_AMS_SLAVE_STATUS_MASK,
 | 
			
		||||
	CAN_ID_AMS_SLAVE_LOG_MASK,
 | 
			
		||||
	CAN_ID_AMS_SLAVE_LOG_BASE,
 | 
			
		||||
	CAN_ID_AMS_SLAVE_STATUS_BASE,
 | 
			
		||||
	CAN_ID_AMS_STATUS,
 | 
			
		||||
	CAN_ID_SHUNT_CURRENT,
 | 
			
		||||
	CAN_ID_SHUNT_VOLTAGE_1,
 | 
			
		||||
	CAN_ID_SHUNT_VOLTAGE_2
 | 
			
		||||
} from '$lib/messages';
 | 
			
		||||
import { N_CELLS_PER_SLAVE, N_TEMP_SENSORS_PER_SLAVE } from '$lib/defs';
 | 
			
		||||
 | 
			
		||||
const CAN_ID_AMS_ERROR = 0x00c;
 | 
			
		||||
const CAN_ID_AMS_STATUS = 0x00a;
 | 
			
		||||
const CAN_ID_AMS_SLAVE_STATUS_BASE = 0x080;
 | 
			
		||||
const CAN_ID_AMS_SLAVE_STATUS_MASK = 0xff0;
 | 
			
		||||
const CAN_ID_AMS_SLAVE_LOG_BASE = 0x600;
 | 
			
		||||
const CAN_ID_AMS_SLAVE_LOG_MASK = 0xf00;
 | 
			
		||||
const CAN_ID_SHUNT_CURRENT = 0x521;
 | 
			
		||||
const CAN_ID_SHUNT_VOLTAGE_1 = 0x522;
 | 
			
		||||
const CAN_ID_SHUNT_VOLTAGE_2 = 0x523;
 | 
			
		||||
 | 
			
		||||
type RawMessage = {
 | 
			
		||||
	ext?: boolean;
 | 
			
		||||
	canfd?: boolean;
 | 
			
		||||
	id: number;
 | 
			
		||||
	data: Buffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function decodeError(msg: RawMessage): AMSError | null {
 | 
			
		||||
	if (msg.data.length != 2) {
 | 
			
		||||
		console.warn('invalid error frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	console.log('error', msg);
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	return {
 | 
			
		||||
		type: 'error',
 | 
			
		||||
		kind: data[0],
 | 
			
		||||
		arg: data[1]
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeStatus(msg: RawMessage): AMSStatus | null {
 | 
			
		||||
	if (msg.data.length != 8) {
 | 
			
		||||
		console.warn('invalid status frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	return {
 | 
			
		||||
		type: 'status',
 | 
			
		||||
		state: data[0] & 0x7f,
 | 
			
		||||
		sdcClosed: !!(data[0] & 0x80),
 | 
			
		||||
		soc: data[1],
 | 
			
		||||
		minCellVolt: data.readUInt16BE(2) * 1e-3,
 | 
			
		||||
		maxCellTemp: data.readUInt16BE(4) * 0.0625,
 | 
			
		||||
		imdOK: !!(data[6] & 0x80)
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeSlaveStatus(msg: RawMessage): SlaveStatus | null {
 | 
			
		||||
	if (msg.data.length != 8) {
 | 
			
		||||
		console.warn('invalid slave status frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	return {
 | 
			
		||||
		type: 'slaveStatus',
 | 
			
		||||
 | 
			
		||||
		slaveId: data[0] & 0x7f,
 | 
			
		||||
		error: !!(data[0] & 0x80),
 | 
			
		||||
		soc: data[1],
 | 
			
		||||
		minCellVolt: data.readUInt16BE(2) * 1e-3,
 | 
			
		||||
		maxCellVolt: data.readUInt16BE(4) * 1e-3,
 | 
			
		||||
		maxTemp: data.readUInt16BE(6) * 0.0625
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeSlaveLog(msg: RawMessage): SlaveLog | null {
 | 
			
		||||
	if (msg.data.length != 8) {
 | 
			
		||||
		console.warn('invalid slave log frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const slaveId = (msg.id & 0xf0) >> 4;
 | 
			
		||||
	const logIndex = msg.id & 0x00f;
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
	if (logIndex < N_CELLS_PER_SLAVE / 4) {
 | 
			
		||||
		const startIndex = logIndex * 4;
 | 
			
		||||
		const voltages = [];
 | 
			
		||||
		for (let i = 0; i < 4; i++) {
 | 
			
		||||
			voltages.push(data.readUInt16BE(2 * i) * 1e-3);
 | 
			
		||||
		}
 | 
			
		||||
		const msg: SlaveLogVoltage = {
 | 
			
		||||
			type: 'slaveLog',
 | 
			
		||||
			slaveId,
 | 
			
		||||
 | 
			
		||||
			logType: 'voltage',
 | 
			
		||||
			startIndex,
 | 
			
		||||
			voltages: voltages as [number, number, number, number]
 | 
			
		||||
		};
 | 
			
		||||
		return msg;
 | 
			
		||||
	} else if (logIndex == N_CELLS_PER_SLAVE / 4) {
 | 
			
		||||
		const msg: SlaveLogLastCell = {
 | 
			
		||||
			type: 'slaveLog',
 | 
			
		||||
			slaveId,
 | 
			
		||||
 | 
			
		||||
			logType: 'lastCell',
 | 
			
		||||
			voltage: data.readUInt16BE(0) * 1e-3,
 | 
			
		||||
			failed_temp_sensors: data.readInt32BE(2)
 | 
			
		||||
		};
 | 
			
		||||
		return msg;
 | 
			
		||||
	} else if (logIndex < N_CELLS_PER_SLAVE / 4 + 1 + N_TEMP_SENSORS_PER_SLAVE / 8) {
 | 
			
		||||
		const temperatures = [];
 | 
			
		||||
		for (let i = 0; i < 8; i++) {
 | 
			
		||||
			temperatures.push(data.readInt8(i) * 1);
 | 
			
		||||
		}
 | 
			
		||||
		const msg: SlaveLogTemperature = {
 | 
			
		||||
			type: 'slaveLog',
 | 
			
		||||
			slaveId,
 | 
			
		||||
 | 
			
		||||
			logType: 'temperature',
 | 
			
		||||
			startIndex: (logIndex - N_CELLS_PER_SLAVE / 4 - 1) * 8,
 | 
			
		||||
			temperatures: temperatures as [number, number, number, number, number, number, number, number]
 | 
			
		||||
		};
 | 
			
		||||
		return msg;
 | 
			
		||||
	} else {
 | 
			
		||||
		console.warn('Unknown slave log index', msg.id);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function decodeShunt(msg: RawMessage, type: String): ShuntLog | null {
 | 
			
		||||
	if (msg.data.length != 6) {
 | 
			
		||||
		console.warn('invalid shunt log frame', msg);
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	const data = msg.data;
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		type: type,
 | 
			
		||||
 | 
			
		||||
		value: data.readInt32BE(2) * 1e-3,
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function POST() {
 | 
			
		||||
	return produce(async function start({ emit }) {
 | 
			
		||||
@ -165,39 +28,7 @@ export function POST() {
 | 
			
		||||
		]);
 | 
			
		||||
 | 
			
		||||
		network.addListener('onMessage', (msg: RawMessage) => {
 | 
			
		||||
			if (msg.ext || msg.canfd) {
 | 
			
		||||
				console.warn('invalid frame', msg);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			let message: AMSMessage | null = null;
 | 
			
		||||
			if ((msg.id & CAN_ID_AMS_SLAVE_STATUS_MASK) == CAN_ID_AMS_SLAVE_STATUS_BASE) {
 | 
			
		||||
				message = decodeSlaveStatus(msg);
 | 
			
		||||
			} else if ((msg.id & CAN_ID_AMS_SLAVE_LOG_MASK) == CAN_ID_AMS_SLAVE_LOG_BASE) {
 | 
			
		||||
				message = decodeSlaveLog(msg);
 | 
			
		||||
			} else {
 | 
			
		||||
				switch (msg.id) {
 | 
			
		||||
					case CAN_ID_AMS_ERROR:
 | 
			
		||||
						message = decodeError(msg);
 | 
			
		||||
						break;
 | 
			
		||||
					case CAN_ID_AMS_STATUS:
 | 
			
		||||
						message = decodeStatus(msg);
 | 
			
		||||
						break;
 | 
			
		||||
					case CAN_ID_SHUNT_CURRENT:
 | 
			
		||||
						message = decodeShunt(msg, 'shuntCurrentLog');
 | 
			
		||||
						break;
 | 
			
		||||
					case CAN_ID_SHUNT_VOLTAGE_1:
 | 
			
		||||
						message = decodeShunt(msg, 'shuntVoltage1Log');
 | 
			
		||||
						break;
 | 
			
		||||
					case CAN_ID_SHUNT_VOLTAGE_2:
 | 
			
		||||
						message = decodeShunt(msg, 'shuntVoltage2Log');
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (message) {
 | 
			
		||||
				emit('message', JSON.stringify(message));
 | 
			
		||||
			}
 | 
			
		||||
			emit('message', JSON.stringify(marshalMessage(msg)));
 | 
			
		||||
		});
 | 
			
		||||
		network.start();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import { sveltekit } from '@sveltejs/kit/vite';
 | 
			
		||||
import { defineConfig } from 'vite';
 | 
			
		||||
import { nodePolyfills } from 'vite-plugin-node-polyfills';
 | 
			
		||||
 | 
			
		||||
export default defineConfig({
 | 
			
		||||
	plugins: [sveltekit()]
 | 
			
		||||
	plugins: [sveltekit(), nodePolyfills()]
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user