Compare commits
	
		
			4 Commits
		
	
	
		
			main
			...
			Shunt-inte
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bbb2534987 | |||
| 826318652d | |||
| 333939df87 | |||
| 971d6380e0 | 
@ -1,2 +1,2 @@
 | 
				
			|||||||
export const N_CELLS_PER_SLAVE = 15;
 | 
					export const N_CELLS_PER_SLAVE = 15;
 | 
				
			||||||
export const N_TEMP_SENSORS_PER_SLAVE = 32;
 | 
					export const N_TEMP_SENSORS_PER_SLAVE = 44;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
export interface AMSMessage {
 | 
					export interface AMSMessage {
 | 
				
			||||||
	type: 'error' | 'status' | 'slaveStatus' | 'slaveLog';
 | 
						type: 'error' | 'status' | 'shunt' |  'slaveStatus' | 'slaveLog';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface AMSError extends AMSMessage {
 | 
					export interface AMSError extends AMSMessage {
 | 
				
			||||||
@ -29,6 +29,30 @@ export interface AMSStatus extends AMSMessage {
 | 
				
			|||||||
	// TODO: IMD state & R_iso
 | 
						// TODO: IMD state & R_iso
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface Shunt extends AMSMessage {
 | 
				
			||||||
 | 
						type: 'shunt';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logType: 'current' | 'voltage1' | 'voltage2';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ShuntCurrent extends Shunt {
 | 
				
			||||||
 | 
						logType: 'current';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						current: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ShuntVoltage1 extends Shunt {
 | 
				
			||||||
 | 
						logType: 'voltage1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						voltage: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ShuntVoltage2 extends Shunt {
 | 
				
			||||||
 | 
						logType: 'voltage2';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						voltage: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface SlaveStatus extends AMSMessage {
 | 
					export interface SlaveStatus extends AMSMessage {
 | 
				
			||||||
	type: 'slaveStatus';
 | 
						type: 'slaveStatus';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,9 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { AMSError, AMSMessage, AMSStatus, SlaveLog, SlaveStatus } from '$lib/messages';
 | 
						import type { AMSError, AMSMessage, AMSStatus, Shunt, ShuntCurrent, ShuntVoltage1, ShuntVoltage2, SlaveLog, SlaveStatus } from '$lib/messages';
 | 
				
			||||||
	import { source } from 'sveltekit-sse';
 | 
						import { source } from 'sveltekit-sse';
 | 
				
			||||||
	import MasterStatusDisplay from './master-status-display.svelte';
 | 
						import MasterStatusDisplay from './master-status-display.svelte';
 | 
				
			||||||
	import SlaveStatusDisplay from './slave-status-display.svelte';
 | 
						import SlaveStatusDisplay from './slave-status-display.svelte';
 | 
				
			||||||
 | 
						import ShuntStatusDisplay from './shunt-status-display.svelte';
 | 
				
			||||||
	import '../app.css';
 | 
						import '../app.css';
 | 
				
			||||||
	import MasterErrorDisplay from './master-error-display.svelte';
 | 
						import MasterErrorDisplay from './master-error-display.svelte';
 | 
				
			||||||
	import { SlaveLogData } from '$lib/slave-log';
 | 
						import { SlaveLogData } from '$lib/slave-log';
 | 
				
			||||||
@ -10,6 +11,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	let error: AMSError | undefined;
 | 
						let error: AMSError | undefined;
 | 
				
			||||||
	let amsStatus: AMSStatus | undefined;
 | 
						let amsStatus: AMSStatus | undefined;
 | 
				
			||||||
 | 
						let shunt: Shunt | undefined;
 | 
				
			||||||
 | 
						let shuntA: ShuntCurrent | undefined
 | 
				
			||||||
 | 
						let shuntV1: ShuntVoltage1 | undefined;
 | 
				
			||||||
 | 
					    let shuntV2: ShuntVoltage2 | undefined;
 | 
				
			||||||
	let slaveStatus: Record<number, SlaveStatus> = {};
 | 
						let slaveStatus: Record<number, SlaveStatus> = {};
 | 
				
			||||||
	let slaveLog: Record<number, SlaveLogData> = {};
 | 
						let slaveLog: Record<number, SlaveLogData> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -35,6 +40,9 @@
 | 
				
			|||||||
				case 'status':
 | 
									case 'status':
 | 
				
			||||||
					amsStatus = msg as AMSStatus;
 | 
										amsStatus = msg as AMSStatus;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
 | 
									case 'shunt':
 | 
				
			||||||
 | 
										shunt = msg as Shunt;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
				case 'slaveStatus': {
 | 
									case 'slaveStatus': {
 | 
				
			||||||
					const status = msg as SlaveStatus;
 | 
										const status = msg as SlaveStatus;
 | 
				
			||||||
					slaveStatus[status.slaveId] = status;
 | 
										slaveStatus[status.slaveId] = status;
 | 
				
			||||||
@ -47,13 +55,20 @@
 | 
				
			|||||||
		});
 | 
							});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<h1>FaSTTUBe Charger</h1>
 | 
					<div class="wrapper">
 | 
				
			||||||
 | 
						<MasterErrorDisplay {error} />
 | 
				
			||||||
 | 
						<MasterStatusDisplay status={amsStatus} />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<MasterErrorDisplay {error} />
 | 
					 | 
				
			||||||
<MasterStatusDisplay status={amsStatus} />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="slaves">
 | 
					 | 
				
			||||||
	{#each Object.entries(slaveStatus) as [id, status]}
 | 
						{#each Object.entries(slaveStatus) as [id, status]}
 | 
				
			||||||
		<SlaveStatusDisplay {id} {status} logData={slaveLog[id]} />
 | 
							<SlaveStatusDisplay {id} {status} logData={slaveLog[id]} />
 | 
				
			||||||
	{/each}
 | 
						{/each}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
						.wrapper {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: row;
 | 
				
			||||||
 | 
							justify-content: center;
 | 
				
			||||||
 | 
							align-items: center;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -4,6 +4,10 @@ import type {
 | 
				
			|||||||
	AMSError,
 | 
						AMSError,
 | 
				
			||||||
	AMSMessage,
 | 
						AMSMessage,
 | 
				
			||||||
	AMSStatus,
 | 
						AMSStatus,
 | 
				
			||||||
 | 
						Shunt,
 | 
				
			||||||
 | 
						ShuntCurrent,
 | 
				
			||||||
 | 
						ShuntVoltage1,
 | 
				
			||||||
 | 
						ShuntVoltage2,
 | 
				
			||||||
	SlaveLog,
 | 
						SlaveLog,
 | 
				
			||||||
	SlaveLogLastCell,
 | 
						SlaveLogLastCell,
 | 
				
			||||||
	SlaveLogTemperature,
 | 
						SlaveLogTemperature,
 | 
				
			||||||
@ -18,6 +22,8 @@ const CAN_ID_AMS_SLAVE_STATUS_BASE = 0x080;
 | 
				
			|||||||
const CAN_ID_AMS_SLAVE_STATUS_MASK = 0xff0;
 | 
					const CAN_ID_AMS_SLAVE_STATUS_MASK = 0xff0;
 | 
				
			||||||
const CAN_ID_AMS_SLAVE_LOG_BASE = 0x600;
 | 
					const CAN_ID_AMS_SLAVE_LOG_BASE = 0x600;
 | 
				
			||||||
const CAN_ID_AMS_SLAVE_LOG_MASK = 0xf00;
 | 
					const CAN_ID_AMS_SLAVE_LOG_MASK = 0xf00;
 | 
				
			||||||
 | 
					const CAN_ID_AMS_SHUNT_BASE = 0x520;
 | 
				
			||||||
 | 
					const CAN_ID_AMS_SHUNT_MASK = 0xff0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RawMessage = {
 | 
					type RawMessage = {
 | 
				
			||||||
	ext?: boolean;
 | 
						ext?: boolean;
 | 
				
			||||||
@ -59,6 +65,45 @@ function decodeStatus(msg: RawMessage): AMSStatus | null {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function decodeShunt(msg: RawMessage): Shunt | null {
 | 
				
			||||||
 | 
						if (msg.data.length != 6) {
 | 
				
			||||||
 | 
							console.warn( 'invalid shunt frame', msg);
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const index = msg.id & 0x00f;
 | 
				
			||||||
 | 
						const data = msg.data;
 | 
				
			||||||
 | 
						if (index == 1) {
 | 
				
			||||||
 | 
							const msg: ShuntCurrent = {
 | 
				
			||||||
 | 
								type: 'shunt',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logType: 'current',
 | 
				
			||||||
 | 
								current: data.readInt32BE(2) * 1e-3,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							return msg;
 | 
				
			||||||
 | 
						} else if (index == 2) {
 | 
				
			||||||
 | 
							const msg: ShuntVoltage1 = {
 | 
				
			||||||
 | 
								type: 'shunt',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logType: 'voltage1',
 | 
				
			||||||
 | 
								voltage: data.readInt32BE(2) * 1e-3,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							return msg;
 | 
				
			||||||
 | 
						} else if (index == 3) {
 | 
				
			||||||
 | 
							const msg: ShuntVoltage2 = {
 | 
				
			||||||
 | 
								type:  'shunt',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logType: 'voltage2',
 | 
				
			||||||
 | 
								voltage: data.readInt32BE(2) * 1e-3,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							return msg;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							console.warn('Unknown shunt index', msg.id);
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function decodeSlaveStatus(msg: RawMessage): SlaveStatus | null {
 | 
					function decodeSlaveStatus(msg: RawMessage): SlaveStatus | null {
 | 
				
			||||||
	if (msg.data.length != 8) {
 | 
						if (msg.data.length != 8) {
 | 
				
			||||||
		console.warn('invalid slave status frame', msg);
 | 
							console.warn('invalid slave status frame', msg);
 | 
				
			||||||
@ -139,7 +184,9 @@ export function POST() {
 | 
				
			|||||||
			{ id: CAN_ID_AMS_ERROR, mask: 0xfff },
 | 
								{ id: CAN_ID_AMS_ERROR, mask: 0xfff },
 | 
				
			||||||
			{ id: CAN_ID_AMS_STATUS, mask: 0xfff },
 | 
								{ id: CAN_ID_AMS_STATUS, mask: 0xfff },
 | 
				
			||||||
			{ id: CAN_ID_AMS_SLAVE_STATUS_BASE, mask: CAN_ID_AMS_SLAVE_STATUS_MASK },
 | 
								{ id: CAN_ID_AMS_SLAVE_STATUS_BASE, mask: CAN_ID_AMS_SLAVE_STATUS_MASK },
 | 
				
			||||||
			{ id: CAN_ID_AMS_SLAVE_LOG_BASE, mask: CAN_ID_AMS_SLAVE_LOG_MASK }
 | 
								{ id: CAN_ID_AMS_SLAVE_LOG_BASE, mask: CAN_ID_AMS_SLAVE_LOG_MASK },
 | 
				
			||||||
 | 
								{ id: CAN_ID_AMS_SHUNT_BASE, mask:
 | 
				
			||||||
 | 
								CAN_ID_AMS_SHUNT_MASK }
 | 
				
			||||||
		]);
 | 
							]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		network.addListener('onMessage', (msg: RawMessage) => {
 | 
							network.addListener('onMessage', (msg: RawMessage) => {
 | 
				
			||||||
@ -153,6 +200,8 @@ export function POST() {
 | 
				
			|||||||
				message = decodeSlaveStatus(msg);
 | 
									message = decodeSlaveStatus(msg);
 | 
				
			||||||
			} else if ((msg.id & CAN_ID_AMS_SLAVE_LOG_MASK) == CAN_ID_AMS_SLAVE_LOG_BASE) {
 | 
								} else if ((msg.id & CAN_ID_AMS_SLAVE_LOG_MASK) == CAN_ID_AMS_SLAVE_LOG_BASE) {
 | 
				
			||||||
				message = decodeSlaveLog(msg);
 | 
									message = decodeSlaveLog(msg);
 | 
				
			||||||
 | 
								} else if ((msg.id & CAN_ID_AMS_SHUNT_MASK) == CAN_ID_AMS_SHUNT_BASE) {
 | 
				
			||||||
 | 
									message = decodeShunt(msg);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				switch (msg.id) {
 | 
									switch (msg.id) {
 | 
				
			||||||
					case CAN_ID_AMS_ERROR:
 | 
										case CAN_ID_AMS_ERROR:
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -4,18 +4,35 @@
 | 
				
			|||||||
	export let status: AMSStatus | undefined;
 | 
						export let status: AMSStatus | undefined;
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#if status}
 | 
					<div class="master-content">
 | 
				
			||||||
	<h2>Master Status</h2>
 | 
						{#if status}
 | 
				
			||||||
	<div class="status-table">
 | 
							<h2><b>Master Status</b></h2>
 | 
				
			||||||
		<div>State:</div>
 | 
							<div class="log-collumn">
 | 
				
			||||||
		<div>{status.state}</div>
 | 
								<div>State: {status.state}</div>
 | 
				
			||||||
		<div>SDC Closed:</div>
 | 
								<div>SDC Closed: {status.sdcClosed}</div>
 | 
				
			||||||
		<div>{status.sdcClosed}</div>
 | 
								<div>SoC: {status.soc}</div>
 | 
				
			||||||
		<div>SoC:</div>
 | 
								<div>Min. cell voltage: {Math.round(status.minCellVolt * 100) / 100}</div>
 | 
				
			||||||
		<div>{status.soc}</div>
 | 
								<div>Max. cell temperature: {Math.round(status.maxCellTemp * 100) / 100}</div>
 | 
				
			||||||
		<div>Min. cell voltage:</div>
 | 
							</div>
 | 
				
			||||||
		<div>{status.minCellVolt}</div>
 | 
						{/if}
 | 
				
			||||||
		<div>Max. cell temperature:</div>
 | 
					</div>
 | 
				
			||||||
		<div>{status.maxCellTemp}</div>
 | 
					
 | 
				
			||||||
	</div>
 | 
					<style>
 | 
				
			||||||
{/if}
 | 
						.master-content {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							width: 12vw;
 | 
				
			||||||
 | 
							border: 2px solid black;
 | 
				
			||||||
 | 
							padding: 2px;
 | 
				
			||||||
 | 
							margin: 2px;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.log-collumn {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h2 {
 | 
				
			||||||
 | 
							text-align: center;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								src/routes/shunt-status-display.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/routes/shunt-status-display.svelte
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					    import type { Shunt, ShuntCurrent, ShuntVoltage1, ShuntVoltage2 } from "$lib/messages";
 | 
				
			||||||
 | 
					    export let shuntData: Shunt | undefined;
 | 
				
			||||||
 | 
					    export let shuntA: ShuntCurrent | undefined;
 | 
				
			||||||
 | 
					    export let shuntV1: ShuntVoltage1 | undefined;
 | 
				
			||||||
 | 
					    export let shuntV2: ShuntVoltage2 | undefined;
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="shunt-content">
 | 
				
			||||||
 | 
					    {#if shuntData}
 | 
				
			||||||
 | 
					        <h2><b>Shunt Data</b></h2>
 | 
				
			||||||
 | 
					        <div class="log-collumn">
 | 
				
			||||||
 | 
					            <div>Current: {Math.round(shuntA.current * 100) / 100} </div>
 | 
				
			||||||
 | 
					            <div>Battery side voltage: {Math.round(shuntV1.voltage * 100) / 100}</div>
 | 
				
			||||||
 | 
					            <div>Vehicle side voltage: {Math.round(shuntV2.voltage * 100) / 100}</div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    {/if}
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
						.shunt-content {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							width: 12vw;
 | 
				
			||||||
 | 
							border: 2px solid black;
 | 
				
			||||||
 | 
							padding: 2px;
 | 
				
			||||||
 | 
							margin: 2px;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.log-collumn {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h2 {
 | 
				
			||||||
 | 
							text-align: center;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -1,40 +1,73 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { SlaveStatus } from '$lib/messages';
 | 
						import type { SlaveStatus } from '$lib/messages';
 | 
				
			||||||
	import type { SlaveLogData } from '$lib/slave-log';
 | 
						import type { SlaveLogData } from '$lib/slave-log';
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	export let id: number;
 | 
						export let id: number;
 | 
				
			||||||
	export let status: SlaveStatus;
 | 
						export let status: SlaveStatus;
 | 
				
			||||||
	export let logData: SlaveLogData | undefined;
 | 
						export let logData: SlaveLogData | undefined;
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<h2>Slave #{id}</h2>
 | 
					<div class="slave-content" style:--lightness={status.error ? "60%" : "100%"}>
 | 
				
			||||||
 | 
						<h2><b>Slave #{id}</b></h2>
 | 
				
			||||||
<div class="status-table">
 | 
						
 | 
				
			||||||
	<div>Error</div>
 | 
						<div class="log-collumn">
 | 
				
			||||||
	<div>{status.error}</div>
 | 
							<div class="log-entry"><div>Error:</div><div><b>{status.error}</b></div></div>
 | 
				
			||||||
	<div>Min. cell voltage</div>
 | 
							<div class="log-entry"><div>Min. cell voltage:</div><div><b>{Math.round(status.minCellVolt*100)/100}V</b></div></div>
 | 
				
			||||||
	<div>{status.minCellVolt}</div>
 | 
							<div class="log-entry"><div>Max. cell voltage:</div><div><b>{Math.round(status.maxCellVolt*100)/100}V</b></div></div>
 | 
				
			||||||
	<div>Max. cell voltage</div>
 | 
							<div class="log-entry"><div>Max. temperature:</div><div><b>{Math.round(status.maxTemp*100)/100}°</b></div></div>
 | 
				
			||||||
	<div>{status.maxCellVolt}</div>
 | 
							<!-- <div>SoC</div>
 | 
				
			||||||
	<div>Max. temperature</div>
 | 
							<div>{status.soc}</div> -->
 | 
				
			||||||
	<div>{status.maxTemp}</div>
 | 
							<!-- <div>Failed temperature sensors</div>
 | 
				
			||||||
	<div>SoC</div>
 | 
							<div>{logData?.failedTempSensors ?? 0}</div> -->
 | 
				
			||||||
	<div>{status.soc}</div>
 | 
						</div>
 | 
				
			||||||
	<div>Failed temperature sensors</div>
 | 
						
 | 
				
			||||||
	<div>{logData?.failedTempSensors ?? 0}</div>
 | 
						{#if logData}
 | 
				
			||||||
</div>
 | 
							<div class="log-collumn">
 | 
				
			||||||
 | 
					 | 
				
			||||||
{#if logData}
 | 
					 | 
				
			||||||
	<details>
 | 
					 | 
				
			||||||
		<div class="status-table">
 | 
					 | 
				
			||||||
			{#each logData.voltages as volt, i}
 | 
								{#each logData.voltages as volt, i}
 | 
				
			||||||
				<div>V_{i}</div>
 | 
									{#if i < 15}
 | 
				
			||||||
				<div>{volt}</div>
 | 
										<div class="log-entry" style:--hue={Math.max(((volt-2.5)*70.5), 0)}>
 | 
				
			||||||
 | 
											<div>V{i}:</div><div><b>{Math.round(volt*100)/100}V</b></div>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
									{/if}
 | 
				
			||||||
			{/each}
 | 
								{/each}
 | 
				
			||||||
			{#each logData.temperatures as temp, i}
 | 
								{#each logData.temperatures as temp, i}
 | 
				
			||||||
				<div>T_{i}</div>
 | 
									{#if i > 33 && i < 44}
 | 
				
			||||||
				<div>{temp}</div>
 | 
										<div class="log-entry" style:--hue={210-(temp*3.5)}>
 | 
				
			||||||
 | 
											<div>T{i}:</div><div><b>{temp}°</b></div>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
									{/if}
 | 
				
			||||||
			{/each}
 | 
								{/each}
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</details>
 | 
						{/if}
 | 
				
			||||||
{/if}
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
						.slave-content {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							width: 12vw;
 | 
				
			||||||
 | 
							padding: 2px;
 | 
				
			||||||
 | 
							margin: 2px;
 | 
				
			||||||
 | 
							border: 2px solid black;
 | 
				
			||||||
 | 
							font-size: 14px;
 | 
				
			||||||
 | 
							margin-top: 10px;
 | 
				
			||||||
 | 
							background-color: hsl(0, 60%, --lightness);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						.log-entry {
 | 
				
			||||||
 | 
							display: grid;
 | 
				
			||||||
 | 
							grid-template-columns: 5fr 3fr;
 | 
				
			||||||
 | 
							margin: 2px;
 | 
				
			||||||
 | 
							padding: 2px;
 | 
				
			||||||
 | 
							background-color: hsl(var(--hue), 80%, 80%);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.log-collumn {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h2 {
 | 
				
			||||||
 | 
							text-align: center;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user