mirror of
				https://github.com/KevinMidboe/hivemonitor.git
				synced 2025-10-29 17:40:25 +00:00 
			
		
		
		
	Hive & gateway elements that update live from message queues
This commit is contained in:
		
							
								
								
									
										50
									
								
								src/lib/components/GatewaySummary.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/lib/components/GatewaySummary.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | <script lang="ts"> | ||||||
|  | 	import { onMount } from 'svelte'; | ||||||
|  | 	import { gatewayMessageQueue } from '$lib/store'; | ||||||
|  | 	import { formatTemperature, formatBattery, diffTime } from '$lib/telemetryFormatters'; | ||||||
|  |  | ||||||
|  | 	import NetworkIcon from '$lib/icons/network.svelte'; | ||||||
|  | 	import SyncIcon from '$lib/icons/Sync.svelte'; | ||||||
|  | 	import ThermometerIcon from '$lib/icons/thermometer.svelte'; | ||||||
|  | 	import BatteryIcon from '$lib/icons/Battery.svelte'; | ||||||
|  | 	import Card from './Card.svelte'; | ||||||
|  | 	import GatewayModal from './modals/GatewayModal.svelte'; | ||||||
|  | 	import type { IGatewayTelemetry } from '$lib/interfaces/ITelemetry'; | ||||||
|  |  | ||||||
|  | 	let gateways: IGatewayTelemetry[] = []; | ||||||
|  | 	let sinceUpdate = 0; | ||||||
|  | 	let interval: number; | ||||||
|  |  | ||||||
|  | 	function updateGateways(telemetry: IGatewayTelemetry) { | ||||||
|  | 		if (interval) clearInterval(interval); | ||||||
|  | 		sinceUpdate = 0; | ||||||
|  |  | ||||||
|  | 		const hiveName = telemetry?.gateway_name; | ||||||
|  | 		if (!hiveName) return; | ||||||
|  | 		sinceUpdate = diffTime(new Date(telemetry?.t)); | ||||||
|  |  | ||||||
|  | 		let hiveIndex = gateways.findIndex((g) => g.gateway_name === hiveName); | ||||||
|  | 		if (hiveIndex >= 0) gateways[hiveIndex] = telemetry; | ||||||
|  | 		else gateways.push(telemetry); | ||||||
|  |  | ||||||
|  | 		gateways = gateways.sort((a, b) => (a.gateway_name > b.gateway_name ? 1 : -1)); | ||||||
|  | 		interval = setInterval(() => (sinceUpdate = Math.floor(sinceUpdate + 1)), 1000); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	onMount(() => gatewayMessageQueue.subscribe(updateGateways)); | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | {#each gateways as gateway} | ||||||
|  | 	<Card title={gateway.gateway_name} opens={GatewayModal} data={gateway}> | ||||||
|  | 		<NetworkIcon slot="logo" /> | ||||||
|  |  | ||||||
|  | 		<ThermometerIcon slot="first-icon" /> | ||||||
|  | 		<span slot="first-value">{formatTemperature(gateway?.temperature)}°C</span> | ||||||
|  |  | ||||||
|  | 		<SyncIcon slot="second-icon" /> | ||||||
|  | 		<span slot="second-value">{sinceUpdate} s</span> | ||||||
|  |  | ||||||
|  | 		<BatteryIcon slot="third-icon" /> | ||||||
|  | 		<span slot="third-value">{formatBattery(gateway?.battery_level)} V</span> | ||||||
|  | 	</Card> | ||||||
|  | {/each} | ||||||
							
								
								
									
										56
									
								
								src/lib/components/HiveSummary.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/lib/components/HiveSummary.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | <script lang="ts"> | ||||||
|  | 	import { onMount } from 'svelte'; | ||||||
|  | 	import { hiveMessageQueue } from '$lib/store'; | ||||||
|  | 	import { | ||||||
|  | 		formatWeight, | ||||||
|  | 		formatTemperature, | ||||||
|  | 		formatHumidity, | ||||||
|  | 		diffTime | ||||||
|  | 	} from '$lib/telemetryFormatters'; | ||||||
|  |  | ||||||
|  | 	import HiveLogo from '$lib/icons/hive.svelte'; | ||||||
|  | 	import WeightLogo from '$lib/icons/weight.svelte'; | ||||||
|  | 	import ThermometerIcon from '$lib/icons/thermometer.svelte'; | ||||||
|  | 	import HumidityLogo from '$lib/icons/humidity.svelte'; | ||||||
|  | 	import Card from './Card.svelte'; | ||||||
|  | 	import HiveModal from './modals/HiveModal.svelte'; | ||||||
|  | 	import type { IHiveTelemetry } from '$lib/interfaces/ITelemetry'; | ||||||
|  |  | ||||||
|  | 	let sinceUpdate = 0; | ||||||
|  | 	let interval: number; | ||||||
|  | 	let hives: IHiveTelemetry[] = []; | ||||||
|  |  | ||||||
|  | 	function updateHives(telemetry: IHiveTelemetry) { | ||||||
|  | 		if (interval) clearInterval(interval); | ||||||
|  |  | ||||||
|  | 		const hiveName = telemetry?.hive_name; | ||||||
|  | 		if (!hiveName) return; | ||||||
|  | 		sinceUpdate = diffTime(new Date(telemetry?.t)); | ||||||
|  |  | ||||||
|  | 		let hiveIndex = hives.findIndex((h) => h.hive_name === hiveName); | ||||||
|  | 		if (hiveIndex >= 0) hives[hiveIndex] = telemetry; | ||||||
|  | 		else hives.push(telemetry); | ||||||
|  |  | ||||||
|  | 		hives = hives.sort((a, b) => (a.hive_name > b.hive_name ? 1 : -1)); | ||||||
|  | 		interval = setInterval(() => (sinceUpdate = Number((sinceUpdate + 0.1).toFixed(1))), 100); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	onMount(() => hiveMessageQueue.subscribe(updateHives)); | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | {#each hives as hive} | ||||||
|  | 	<Card title={hive.hive_name} opens={HiveModal} data={hive}> | ||||||
|  | 		<HiveLogo slot="logo" /> | ||||||
|  |  | ||||||
|  | 		<WeightLogo slot="first-icon" /> | ||||||
|  | 		<span slot="first-value">{formatWeight(hive?.weight)}kg</span> | ||||||
|  |  | ||||||
|  | 		<ThermometerIcon slot="second-icon" /> | ||||||
|  | 		<span slot="second-value">{formatTemperature(hive?.temperature)}°C</span> | ||||||
|  |  | ||||||
|  | 		<HumidityLogo slot="third-icon" /> | ||||||
|  | 		<span slot="third-value">{formatHumidity(hive?.humidity)}%</span> | ||||||
|  | 	</Card> | ||||||
|  | {/each} | ||||||
|  |  | ||||||
|  | <p style="text-align: right; margin-top: 0">{sinceUpdate} s since last update</p> | ||||||
							
								
								
									
										17
									
								
								src/lib/store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/lib/store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | import { derived, writable } from 'svelte/store'; | ||||||
|  | import type { Writable } from 'svelte/store'; | ||||||
|  | import type IModal from '$lib/interfaces/IModal'; | ||||||
|  | import type { IGatewayTelemetry, IHiveTelemetry } from './interfaces/ITelemetry'; | ||||||
|  |  | ||||||
|  | // message queues | ||||||
|  | export const hiveMessageQueue: Writable<IHiveTelemetry> = writable(); | ||||||
|  | export const gatewayMessageQueue: Writable<IGatewayTelemetry> = writable(); | ||||||
|  |  | ||||||
|  | // setters | ||||||
|  | export const addHiveMessage = (msg: IHiveTelemetry) => hiveMessageQueue.set(msg); | ||||||
|  | export const addGatewayMessageQueue = (msg: IGatewayTelemetry) => gatewayMessageQueue.set(msg); | ||||||
|  |  | ||||||
|  | // modal state | ||||||
|  | export const modal: Writable<IModal | null> = writable(null); | ||||||
|  | export const modalOpen = derived(modal, ($modal) => $modal != null); | ||||||
|  | export const resetModal = () => modal.set(null); | ||||||
		Reference in New Issue
	
	Block a user