added shunt readout and slave timeout
This commit is contained in:
		
							
								
								
									
										5475
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										5475
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,5 +1,5 @@
 | 
				
			|||||||
export interface AMSMessage {
 | 
					export interface AMSMessage {
 | 
				
			||||||
	type: 'error' | 'status' | 'slaveStatus' | 'slaveLog';
 | 
						type: 'error' | 'status' | 'slaveStatus' | 'slaveLog' | 'shuntCurrentLog' | 'shuntVoltage1Log' | 'shuntVoltage2Log';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface AMSError extends AMSMessage {
 | 
					export interface AMSError extends AMSMessage {
 | 
				
			||||||
@ -68,3 +68,9 @@ export interface SlaveLogTemperature extends SlaveLog {
 | 
				
			|||||||
	startIndex: number;
 | 
						startIndex: number;
 | 
				
			||||||
	temperatures: [number, number, number, number, number, number, number, number];
 | 
						temperatures: [number, number, number, number, number, number, number, number];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ShuntLog extends AMSMessage {
 | 
				
			||||||
 | 
						type: 'shuntCurrentLog' | 'shuntVoltage1Log' | 'shuntVoltage2Log';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,17 +1,21 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { AMSError, AMSMessage, AMSStatus, SlaveLog, SlaveStatus } from '$lib/messages';
 | 
						import type { AMSError, AMSMessage, AMSStatus, SlaveLog, SlaveStatus, ShuntLog } 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 '../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';
 | 
				
			||||||
 | 
						import ShuntStatusDisplay from './shunt-status-display.svelte';
 | 
				
			||||||
	// const value = source('/data').select('message');
 | 
						// const value = source('/data').select('message');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let error: AMSError | undefined;
 | 
						let error: AMSError | undefined;
 | 
				
			||||||
	let amsStatus: AMSStatus | undefined;
 | 
						let amsStatus: AMSStatus | undefined;
 | 
				
			||||||
	let slaveStatus: Record<number, SlaveStatus> = {};
 | 
						let slaveStatus: Record<number, SlaveStatus> = {};
 | 
				
			||||||
	let slaveLog: Record<number, SlaveLogData> = {};
 | 
						let slaveLog: Record<number, SlaveLogData> = {};
 | 
				
			||||||
 | 
						let shuntCurrentLog: ShuntLog | undefined;
 | 
				
			||||||
 | 
						let shuntVoltage1Log: ShuntLog | undefined;
 | 
				
			||||||
 | 
						let shuntVoltage2Log: ShuntLog | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function handleSlaveLog(msg: SlaveLog) {
 | 
						function handleSlaveLog(msg: SlaveLog) {
 | 
				
			||||||
		if (!(msg.slaveId in slaveLog)) {
 | 
							if (!(msg.slaveId in slaveLog)) {
 | 
				
			||||||
@ -43,14 +47,25 @@
 | 
				
			|||||||
				case 'slaveLog':
 | 
									case 'slaveLog':
 | 
				
			||||||
					handleSlaveLog(msg as SlaveLog);
 | 
										handleSlaveLog(msg as SlaveLog);
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
 | 
									case 'shuntCurrentLog':
 | 
				
			||||||
 | 
										shuntCurrentLog = msg as ShuntLog;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									case 'shuntVoltage1Log':
 | 
				
			||||||
 | 
										shuntVoltage1Log = msg as ShuntLog;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									case 'shuntVoltage2Log':
 | 
				
			||||||
 | 
										shuntVoltage2Log = msg as ShuntLog;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="wrapper">
 | 
					<div class="wrapper">
 | 
				
			||||||
	<MasterErrorDisplay {error} />
 | 
						<div class="vertical-wrapper">
 | 
				
			||||||
	<MasterStatusDisplay status={amsStatus} />
 | 
							<MasterErrorDisplay {error} />
 | 
				
			||||||
 | 
							<MasterStatusDisplay status={amsStatus} />
 | 
				
			||||||
 | 
							<ShuntStatusDisplay currentLogData={shuntCurrentLog} voltage1LogData={shuntVoltage1Log} voltage2LogData={shuntVoltage2Log} />
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
	{#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}
 | 
				
			||||||
@ -63,4 +78,13 @@
 | 
				
			|||||||
		justify-content: center;
 | 
							justify-content: center;
 | 
				
			||||||
		align-items: center;
 | 
							align-items: center;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.vertical-wrapper {
 | 
				
			||||||
 | 
							display: flex;
 | 
				
			||||||
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							justify-content: center;
 | 
				
			||||||
 | 
							align-items: center;
 | 
				
			||||||
 | 
							margin: 0;
 | 
				
			||||||
 | 
							padding: 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
@ -8,7 +8,8 @@ import type {
 | 
				
			|||||||
	SlaveLogLastCell,
 | 
						SlaveLogLastCell,
 | 
				
			||||||
	SlaveLogTemperature,
 | 
						SlaveLogTemperature,
 | 
				
			||||||
	SlaveLogVoltage,
 | 
						SlaveLogVoltage,
 | 
				
			||||||
	SlaveStatus
 | 
						SlaveStatus,
 | 
				
			||||||
 | 
						ShuntLog
 | 
				
			||||||
} from '$lib/messages';
 | 
					} from '$lib/messages';
 | 
				
			||||||
import { N_CELLS_PER_SLAVE, N_TEMP_SENSORS_PER_SLAVE } from '$lib/defs';
 | 
					import { N_CELLS_PER_SLAVE, N_TEMP_SENSORS_PER_SLAVE } from '$lib/defs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -18,6 +19,9 @@ 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_SHUNT_CURRENT = 0x521;
 | 
				
			||||||
 | 
					const CAN_ID_SHUNT_VOLTAGE_1 = 0x522;
 | 
				
			||||||
 | 
					const CAN_ID_SHUNT_VOLTAGE_2 = 0x523;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type RawMessage = {
 | 
					type RawMessage = {
 | 
				
			||||||
	ext?: boolean;
 | 
						ext?: boolean;
 | 
				
			||||||
@ -132,6 +136,21 @@ function decodeSlaveLog(msg: RawMessage): SlaveLog | 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() {
 | 
					export function POST() {
 | 
				
			||||||
	return produce(async function start({ emit }) {
 | 
						return produce(async function start({ emit }) {
 | 
				
			||||||
		const network = can.createRawChannel('can0');
 | 
							const network = can.createRawChannel('can0');
 | 
				
			||||||
@ -139,7 +158,10 @@ 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_SHUNT_CURRENT, mask: 0xfff },
 | 
				
			||||||
 | 
								{ id: CAN_ID_SHUNT_VOLTAGE_1, mask: 0xfff },
 | 
				
			||||||
 | 
								{ id: CAN_ID_SHUNT_VOLTAGE_2, mask: 0xfff }
 | 
				
			||||||
		]);
 | 
							]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		network.addListener('onMessage', (msg: RawMessage) => {
 | 
							network.addListener('onMessage', (msg: RawMessage) => {
 | 
				
			||||||
@ -161,8 +183,15 @@ export function POST() {
 | 
				
			|||||||
					case CAN_ID_AMS_STATUS:
 | 
										case CAN_ID_AMS_STATUS:
 | 
				
			||||||
						message = decodeStatus(msg);
 | 
											message = decodeStatus(msg);
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					default:
 | 
										case CAN_ID_SHUNT_CURRENT:
 | 
				
			||||||
						console.warn('unknown frame', msg);
 | 
											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;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										63
									
								
								src/routes/shunt-status-display.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/routes/shunt-status-display.svelte
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
						import type { ShuntLog } from '$lib/messages';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						export let currentLogData: ShuntLog | undefined;
 | 
				
			||||||
 | 
						export let voltage1LogData: ShuntLog | undefined;
 | 
				
			||||||
 | 
						export let voltage2LogData: ShuntLog | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="shunt-content">
 | 
				
			||||||
 | 
						<h2><b>Shunt</b></h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<div class="log-collumn">
 | 
				
			||||||
 | 
							<div class="log-entry">
 | 
				
			||||||
 | 
								<div>Current:</div>
 | 
				
			||||||
 | 
								<div><b>{Math.round(currentLogData?.value*10)/10}A</b></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="log-collumn">
 | 
				
			||||||
 | 
							<div class="log-entry">
 | 
				
			||||||
 | 
								<div>Voltage 1:</div>
 | 
				
			||||||
 | 
								<div><b>{Math.round(voltage1LogData?.value*100)/100}V</b></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
						<div class="log-collumn">
 | 
				
			||||||
 | 
							<div class="log-entry">
 | 
				
			||||||
 | 
								<div>Voltage 2:</div>
 | 
				
			||||||
 | 
								<div><b>{Math.round(voltage2LogData?.value*100)/100}V</b></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
						</div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
						.shunt-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%, var(--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;
 | 
				
			||||||
 | 
							background-color: hsl(0, 60%, var(--lightness));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h2 {
 | 
				
			||||||
 | 
							text-align: center;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -1,39 +1,79 @@
 | 
				
			|||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
	import type { SlaveStatus } from '$lib/messages';
 | 
						import { onMount } from 'svelte';
 | 
				
			||||||
	import type { SlaveLogData } from '$lib/slave-log';
 | 
					 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						import type { SlaveStatus } from '$lib/messages';
 | 
				
			||||||
 | 
						import { 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;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						let interval;
 | 
				
			||||||
 | 
						let lastMsgTime: number = 0;
 | 
				
			||||||
 | 
						let timeDifference: number = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						onMount(() => {
 | 
				
			||||||
 | 
							interval = setInterval(() => {
 | 
				
			||||||
 | 
								timeDifference = Date.now()-lastMsgTime;
 | 
				
			||||||
 | 
							}, 50);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						$: totalVoltage = logData?.voltages.slice(0, 15).reduce((acc, x) => acc + x, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						$: {
 | 
				
			||||||
 | 
							slavePing(logData);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function slavePing(logData: SlaveLogData | undefined): void {
 | 
				
			||||||
 | 
							lastMsgTime = Date.now();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="slave-content" style:--lightness={status.error ? "60%" : "100%"}>
 | 
					<div class="slave-content" style:--lightness={status.error ? '70%' : '100%'}>
 | 
				
			||||||
	<h2><b>Slave #{id}</b></h2>
 | 
						<h2><b>Slave #{id} Δrx_t: {Math.round(timeDifference / 1000)}s</b></h2>
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	<div class="log-collumn">
 | 
						<div class="log-collumn" style:--lightness={'' + Math.max(100 - ((timeDifference-200) / 150), 70) + '%'}>
 | 
				
			||||||
		<div class="log-entry"><div>Error:</div><div><b>{status.error}</b></div></div>
 | 
							<div class="log-entry">
 | 
				
			||||||
		<div class="log-entry"><div>Min. cell voltage:</div><div><b>{Math.round(status.minCellVolt*100)/100}V</b></div></div>
 | 
								<div>Error:</div>
 | 
				
			||||||
		<div class="log-entry"><div>Max. cell voltage:</div><div><b>{Math.round(status.maxCellVolt*100)/100}V</b></div></div>
 | 
								<div><b>{status.error}</b></div>
 | 
				
			||||||
		<div class="log-entry"><div>Max. temperature:</div><div><b>{Math.round(status.maxTemp*100)/100}°</b></div></div>
 | 
							</div>
 | 
				
			||||||
 | 
							<div class="log-entry">
 | 
				
			||||||
 | 
								<div>Min. cell voltage:</div>
 | 
				
			||||||
 | 
								<div><b>{Math.round(status.minCellVolt * 1000) / 1000}V</b></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
							<div class="log-entry">
 | 
				
			||||||
 | 
								<div>Max. cell voltage:</div>
 | 
				
			||||||
 | 
								<div><b>{Math.round(status.maxCellVolt * 1000) / 1000}V</b></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
							<div class="log-entry">
 | 
				
			||||||
 | 
								<div>Max. temperature:</div>
 | 
				
			||||||
 | 
								<div><b>{Math.round(status.maxTemp * 100) / 100}°</b></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
 | 
							<div class="log-entry">
 | 
				
			||||||
 | 
								<div>Total voltage:</div>
 | 
				
			||||||
 | 
								<div><b>{Math.round(totalVoltage * 100) / 100}V</b></div>
 | 
				
			||||||
 | 
							</div>
 | 
				
			||||||
		<!-- <div>SoC</div>
 | 
							<!-- <div>SoC</div>
 | 
				
			||||||
		<div>{status.soc}</div> -->
 | 
							<div>{status.soc}</div> -->
 | 
				
			||||||
		<!-- <div>Failed temperature sensors</div>
 | 
							<!-- <div>Failed temperature sensors</div>
 | 
				
			||||||
		<div>{logData?.failedTempSensors ?? 0}</div> -->
 | 
							<div>{logData?.failedTempSensors ?? 0}</div> -->
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	{#if logData}
 | 
						{#if logData}
 | 
				
			||||||
		<div class="log-collumn">
 | 
							<div class="log-collumn">
 | 
				
			||||||
			{#each logData.voltages as volt, i}
 | 
								{#each logData.voltages as volt, i}
 | 
				
			||||||
				{#if i < 15}
 | 
									{#if i < 15}
 | 
				
			||||||
					<div class="log-entry" style:--hue={Math.max(((volt-2.5)*70.5), 0)}>
 | 
										<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>V{i}:</div>
 | 
				
			||||||
 | 
											<div><b>{Math.round(volt * 1000) / 1000}V</b></div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				{/if}
 | 
									{/if}
 | 
				
			||||||
			{/each}
 | 
								{/each}
 | 
				
			||||||
			{#each logData.temperatures as temp, i}
 | 
								{#each logData.temperatures as temp, i}
 | 
				
			||||||
				{#if i > 33 && i < 44}
 | 
									{#if i > 33 && i < 44}
 | 
				
			||||||
					<div class="log-entry" style:--hue={210-(temp*3.5)}>
 | 
										<div class="log-entry" style:--hue={210 - temp * 3.5}>
 | 
				
			||||||
						<div>T{i}:</div><div><b>{temp}°</b></div>
 | 
											<div>T{i}:</div>
 | 
				
			||||||
 | 
											<div><b>{temp}°</b></div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				{/if}
 | 
									{/if}
 | 
				
			||||||
			{/each}
 | 
								{/each}
 | 
				
			||||||
@ -51,9 +91,9 @@
 | 
				
			|||||||
		border: 2px solid black;
 | 
							border: 2px solid black;
 | 
				
			||||||
		font-size: 14px;
 | 
							font-size: 14px;
 | 
				
			||||||
		margin-top: 10px;
 | 
							margin-top: 10px;
 | 
				
			||||||
		background-color: hsl(0, 60%, --lightness);
 | 
							background-color: hsl(0, 60%, var(--lightness));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	.log-entry {
 | 
						.log-entry {
 | 
				
			||||||
		display: grid;
 | 
							display: grid;
 | 
				
			||||||
		grid-template-columns: 5fr 3fr;
 | 
							grid-template-columns: 5fr 3fr;
 | 
				
			||||||
@ -65,9 +105,10 @@
 | 
				
			|||||||
	.log-collumn {
 | 
						.log-collumn {
 | 
				
			||||||
		display: flex;
 | 
							display: flex;
 | 
				
			||||||
		flex-direction: column;
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							background-color: hsl(0, 60%, var(--lightness));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	h2 {
 | 
						h2 {
 | 
				
			||||||
		text-align: center;
 | 
							text-align: center;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user