From 90496aa6241a666234578e54ab800a56f0cf0c1f Mon Sep 17 00:00:00 2001 From: Albert Stefanov Date: Mon, 12 Jan 2026 20:15:07 +0200 Subject: [PATCH 1/2] PoC: add echarts for sensor readings Directly read sensors from Prometheus instead of embedding Grafana in an iframe. This must be cleaned up a bit before merging. --- package.json | 4 +- public/locales/bg.yaml | 7 ++ public/locales/en.yaml | 7 ++ src/config.ts | 18 ++--- src/hooks/useEndpoints.ts | 4 ++ src/hooks/useLocale.ts | 0 src/pages/Sensors.tsx | 84 ++++++++++++++++++++-- src/widgets/SensorReadings/SensorPanel.tsx | 5 +- 8 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 src/hooks/useLocale.ts diff --git a/package.json b/package.json index 607b709..1112cd7 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,9 @@ "react-router-dom": "^7.11.0", "sass": "^1.97.0", "swr": "^2.3.8", - "vite-plugin-compression": "^0.5.1" + "vite-plugin-compression": "^0.5.1", + "echarts": "^6.0.0", + "echarts-for-react": "^3.0.5" }, "devDependencies": { "typescript":">=4.0.0", diff --git a/public/locales/bg.yaml b/public/locales/bg.yaml index ff79441..1fbed26 100644 --- a/public/locales/bg.yaml +++ b/public/locales/bg.yaml @@ -109,6 +109,11 @@ network_devices: new_network_device: Ново мрежово устройство edit: edit_network_device: Редакция на мрежово устройство +rooms: + big-room: Голяма зала + small-room: Малка зала + kitchen: Кухня + outside: Навън views: dashboard: sensor_readings: Температура и влажност на въздуха @@ -227,6 +232,8 @@ views: are_you_sure: 'Сигурни ли сте?' sensors: title: Показания на сензорите + temperature: Температура + humidity: Влажност action_log: title: Лог на действията columns: diff --git a/public/locales/en.yaml b/public/locales/en.yaml index 36c32e0..30ed0b4 100644 --- a/public/locales/en.yaml +++ b/public/locales/en.yaml @@ -103,6 +103,11 @@ network_devices: new_network_device: New network device edit: edit_network_device: Edit network device +rooms: + big-room: Big Room + small-room: Small Room + kitchen: Kitchen + outside: Outside views: dashboard: sensor_readings: Air temperature and humidity @@ -219,6 +224,8 @@ views: are_you_sure: 'Are you shnur?' sensors: title: Sensor readings + temperature: Temperature + humidity: Humidity action_log: title: Action logs columns: diff --git a/src/config.ts b/src/config.ts index dea8439..1c29a3b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -13,10 +13,10 @@ export const oidc = { export type MqttConfig = {[topic: string]: {label: string}} export const sensors: MqttConfig = { - 'sensors/big-room': {label: 'Big room',}, - 'sensors/small-room': {label: 'Small room',}, - 'sensors/kitchen': {label: 'Kitchen',}, - 'sensors/outside': {label: 'Outside',}, + 'sensors/big-room/test': {label: 'big-room'}, + 'sensors/small-room/test': {label: 'small-room',}, + 'sensors/kitchen/test': {label: 'kitchen',}, + 'sensors/outside/test': {label: 'outside',}, }; export const variantHosts: {[hostname: string]: string} = { @@ -45,12 +45,4 @@ export const variants: {[variant: string]: VariantConfig} = { logo: {url: colibriLogo, alt: 'colibri logo',}, title: 'Casa Libri', }, -} - -export const grafana = { - urls: [ - 'https://stats.initlab.org/d-solo/SGAb0ZXMk/temperature-and-humidity?orgId=1&refresh=1m&panelId=4', - 'https://stats.initlab.org/d-solo/SGAb0ZXMk/temperature-and-humidity?orgId=1&refresh=1m&panelId=5', - 'https://stats.initlab.org/d-solo/SGAb0ZXMk/temperature-and-humidity?orgId=1&refresh=1m&panelId=10', - ] -}; +} \ No newline at end of file diff --git a/src/hooks/useEndpoints.ts b/src/hooks/useEndpoints.ts index 0c41aa6..c897ba4 100644 --- a/src/hooks/useEndpoints.ts +++ b/src/hooks/useEndpoints.ts @@ -33,6 +33,10 @@ export function useMqttStatus(config?: SWRConfiguration) { return useCheckSWR<{ [topic: string]: RawMqttReading }>(import.meta.env.MQTT_PROXY_URL.concat('status'), config); } +export function useMqttHistory(config?: SWRConfiguration) { + return useCheckSWR<{ [sensor: string]: {[metric: string]: [[number, number]]} }>(import.meta.env.MQTT_PROXY_URL.concat('sensors/'), config); +} + export function useActionLog(config?: SWRConfiguration) { return useAuthSWR(import.meta.env.PORTIER_URL.concat('api/actionLog/0/0'), config); } diff --git a/src/hooks/useLocale.ts b/src/hooks/useLocale.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/Sensors.tsx b/src/pages/Sensors.tsx index 33fd886..8d4ac7d 100644 --- a/src/pages/Sensors.tsx +++ b/src/pages/Sensors.tsx @@ -1,22 +1,92 @@ import {Col, Row} from 'react-bootstrap'; import {useTranslation} from 'react-i18next'; -import {grafana} from '../config.ts'; +import {sensors} from '../config.ts'; +import {useMqttHistory} from "../hooks/useEndpoints.ts"; +import EChartsReact from "echarts-for-react"; const Sensors = () => { const {t} = useTranslation(); + const {data} = useMqttHistory(); - return (<> + if(!data) return <>; + + return <>

{t('views.sensors.title')}

- - {grafana.urls.map(url => -