diff --git a/deploy/historisation/grafana/dashboards/systeme.json b/deploy/historisation/grafana/dashboards/systeme.json index b30dd30..a8cb7a3 100644 --- a/deploy/historisation/grafana/dashboards/systeme.json +++ b/deploy/historisation/grafana/dashboards/systeme.json @@ -11,7 +11,7 @@ "version": 1, "refresh": "30s", "time": { - "from": "now/d", + "from": "now-24h", "to": "now" }, "timepicker": { @@ -71,7 +71,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_grid_power_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Puissance\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_grid_power_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Puissance\"})" }, { "refId": "B", @@ -79,7 +79,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"V\" and r.entity_id == \"airtria_mpii_v1_input_voltage_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Tension\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"V\" and r.entity_id == \"airtria_mpii_v1_input_voltage_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Tension\"})" }, { "refId": "C", @@ -87,7 +87,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"gx_device_grid_current_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Courant\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"gx_device_grid_current_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Courant\"})" } ], "gridPos": { @@ -177,6 +177,7 @@ "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": true } }, @@ -195,7 +196,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_consumption_power_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Consommation\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_consumption_power_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Consommation\"})" }, { "refId": "B", @@ -203,7 +204,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"Hz\" and r.entity_id == \"airtria_mpii_v1_output_frequency_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Frequence\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"Hz\" and r.entity_id == \"airtria_mpii_v1_output_frequency_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Frequence\"})" } ], "gridPos": { @@ -277,6 +278,7 @@ "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": true } }, @@ -295,7 +297,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"%\" and r.entity_id == \"victron_battery_soc\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Charge\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"%\" and r.entity_id == \"victron_battery_soc\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Charge\"})" }, { "refId": "B", @@ -303,7 +305,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_battery_power\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Puissance\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_battery_power\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Puissance\"})" }, { "refId": "C", @@ -311,7 +313,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"V\" and r.entity_id == \"victron_battery_voltage\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Tension\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"V\" and r.entity_id == \"victron_battery_voltage\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Tension\"})" }, { "refId": "D", @@ -319,7 +321,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_battery_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Courant\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_battery_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Courant\"})" }, { "refId": "E", @@ -327,7 +329,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"°C\" and r.entity_id == \"victron_battery_temperature\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Temperature\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"°C\" and r.entity_id == \"victron_battery_temperature\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Temperature\"})" } ], "gridPos": { @@ -473,6 +475,7 @@ "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": true } }, @@ -491,7 +494,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_evcs_ac_power\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Puissance\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_evcs_ac_power\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Puissance\"})" }, { "refId": "B", @@ -499,7 +502,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_evcs_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Courant\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_evcs_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Courant\"})" }, { "refId": "C", @@ -507,7 +510,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_evcs_set_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Consigne\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_evcs_set_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Consigne\"})" } ], "gridPos": { @@ -597,6 +600,7 @@ "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": true } }, @@ -615,7 +619,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_pv_power_system\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Production\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_pv_power_system\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Production\"})" }, { "refId": "B", @@ -623,7 +627,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_pv_power_10m_avg\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Moyenne 10 min\"})" + "query": "from(bucket: \"evcs\")\n |> range(start: -6h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_pv_power_10m_avg\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_time\", \"_value\"])\n |> rename(columns: {_value: \"Moyenne 10 min\"})" } ], "gridPos": { @@ -697,6 +701,7 @@ "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": true } }, @@ -715,7 +720,7 @@ "type": "influxdb", "uid": "evcs-influx" }, - "query": "import \"strings\"\n\nbase = from(bucket: \"evcs\")\n |> range(start: -7d)\n |> filter(fn: (r) => r._field == \"value\")\n |> filter(fn: (r) => r._measurement == \"V\" or r._measurement == \"A\" or r._measurement == \"W\")\n |> last()\n\nrs = base\n |> filter(fn: (r) => strings.containsStr(v: r.entity_id, substr: \"pv_tracker_solar_\"))\n |> map(fn: (r) => ({ r with tracker:\n if strings.containsStr(v: r.entity_id, substr: \"solar_1\") then \"Sud 1 (10 pan.)\"\n else if strings.containsStr(v: r.entity_id, substr: \"solar_2\") then \"Sud 2 (10 pan.)\"\n else if strings.containsStr(v: r.entity_id, substr: \"solar_3\") then \"Sud 3 (10 pan.)\"\n else \"Ouest (9 pan.)\" }))\n\nse = base\n |> filter(fn: (r) => r.entity_id == \"airtria_mppt1_pv_bus_voltage\"\n or r.entity_id == \"airtria_mppt1_pv_current\"\n or r.entity_id == \"airtria_mppt1_pv_yield_power\")\n |> map(fn: (r) => ({ r with tracker: \"Sud-est (10 pan.)\" }))\n\nunion(tables: [rs, se])\n |> keep(columns: [\"tracker\", \"_measurement\", \"_value\"])\n |> pivot(rowKey: [\"tracker\"], columnKey: [\"_measurement\"], valueColumn: \"_value\")\n |> sort(columns: [\"tracker\"])" + "query": "import \"strings\"\n\nbase = from(bucket: \"evcs\")\n |> range(start: -30m)\n |> filter(fn: (r) => r._field == \"value\")\n |> filter(fn: (r) => r._measurement == \"V\" or r._measurement == \"A\" or r._measurement == \"W\")\n |> last()\n\nrs = base\n |> filter(fn: (r) => strings.containsStr(v: r.entity_id, substr: \"pv_tracker_solar_\"))\n |> map(fn: (r) => ({ r with tracker:\n if strings.containsStr(v: r.entity_id, substr: \"solar_1\") then \"Sud 1 (10 pan.)\"\n else if strings.containsStr(v: r.entity_id, substr: \"solar_2\") then \"Sud 2 (10 pan.)\"\n else if strings.containsStr(v: r.entity_id, substr: \"solar_3\") then \"Sud 3 (10 pan.)\"\n else \"Ouest (9 pan.)\" }))\n\nse = base\n |> filter(fn: (r) => r.entity_id == \"airtria_mppt1_pv_bus_voltage\"\n or r.entity_id == \"airtria_mppt1_pv_current\"\n or r.entity_id == \"airtria_mppt1_pv_yield_power\")\n |> map(fn: (r) => ({ r with tracker: \"Sud-est (10 pan.)\" }))\n\nunion(tables: [rs, se])\n |> keep(columns: [\"tracker\", \"_measurement\", \"_value\"])\n |> pivot(rowKey: [\"tracker\"], columnKey: [\"_measurement\"], valueColumn: \"_value\")\n |> sort(columns: [\"tracker\"])" } ], "gridPos": { @@ -1000,7 +1005,7 @@ "format": "table", "rawQuery": true, "editorMode": "code", - "rawSql": "WITH axe AS (\n SELECT generate_series(date_trunc('minute', $__timeFrom()::timestamptz),\n date_trunc('minute', $__timeTo()::timestamptz),\n interval '1 minute') AS t\n),\nreleve AS (\n SELECT date_trunc('minute', ts) AS t,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_pv_power_system') AS Solaire,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_grid_power_l1') AS Reseau,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_consumption_power_l1') AS Maison,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_evcs_ac_power') AS Voiture\n FROM mesure WHERE $__timeFilter(ts) GROUP BY 1\n),\npar_minute AS (\n SELECT axe.t, releve.Solaire, releve.Reseau, releve.Maison, releve.Voiture\n FROM axe LEFT JOIN releve USING (t)\n),\npaliers AS (\n SELECT t, Solaire, Reseau, Maison, Voiture,\n count(Solaire) OVER (ORDER BY t) AS g_Solaire,\n count(Reseau) OVER (ORDER BY t) AS g_Reseau,\n count(Maison) OVER (ORDER BY t) AS g_Maison,\n count(Voiture) OVER (ORDER BY t) AS g_Voiture\n FROM par_minute\n),\nreport AS (\n SELECT t,\n first_value(Solaire) OVER (PARTITION BY g_Solaire ORDER BY t) AS Solaire,\n first_value(Reseau) OVER (PARTITION BY g_Reseau ORDER BY t) AS Reseau,\n first_value(Maison) OVER (PARTITION BY g_Maison ORDER BY t) AS Maison,\n first_value(Voiture) OVER (PARTITION BY g_Voiture ORDER BY t) AS Voiture\n FROM paliers\n)\nSELECT to_char(t, 'HH24') || ' h' AS \"Heure\",\n round((avg(Solaire) * count(Solaire) / 60.0 / 1000.0)::numeric, 2) AS \"Solaire\",\n round((avg(Reseau) * count(Reseau) / 60.0 / 1000.0)::numeric, 2) AS \"Reseau\",\n round((avg(Maison) * count(Maison) / 60.0 / 1000.0)::numeric, 2) AS \"Maison\",\n round((avg(Voiture) * count(Voiture) / 60.0 / 1000.0)::numeric, 2) AS \"Voiture\"\nFROM report\nGROUP BY date_trunc('hour', t), to_char(t, 'HH24')\nHAVING count(Solaire) > 0 OR count(Reseau) > 0 OR count(Maison) > 0 OR count(Voiture) > 0\nORDER BY date_trunc('hour', t)" + "rawSql": "WITH axe AS (\n SELECT generate_series(date_trunc('minute', $__timeFrom()::timestamptz),\n date_trunc('minute', $__timeTo()::timestamptz),\n interval '1 minute') AS t\n),\nreleve AS (\n SELECT date_trunc('minute', ts) AS t,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_pv_power_system') AS Solaire,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_grid_power_l1') AS Reseau,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_consumption_power_l1') AS Maison,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_evcs_ac_power') AS Voiture\n FROM mesure WHERE $__timeFilter(ts) GROUP BY 1\n),\npar_minute AS (\n SELECT axe.t, releve.Solaire, releve.Reseau, releve.Maison, releve.Voiture\n FROM axe LEFT JOIN releve USING (t)\n),\npaliers AS (\n SELECT t, Solaire, Reseau, Maison, Voiture,\n count(Solaire) OVER (ORDER BY t) AS g_Solaire,\n count(Reseau) OVER (ORDER BY t) AS g_Reseau,\n count(Maison) OVER (ORDER BY t) AS g_Maison,\n count(Voiture) OVER (ORDER BY t) AS g_Voiture\n FROM par_minute\n),\nreport AS (\n SELECT t,\n first_value(Solaire) OVER (PARTITION BY g_Solaire ORDER BY t) AS Solaire,\n first_value(Reseau) OVER (PARTITION BY g_Reseau ORDER BY t) AS Reseau,\n first_value(Maison) OVER (PARTITION BY g_Maison ORDER BY t) AS Maison,\n first_value(Voiture) OVER (PARTITION BY g_Voiture ORDER BY t) AS Voiture\n FROM paliers\n)\nSELECT to_char(t, 'DD/MM HH24') AS \"Heure\",\n round((avg(Solaire) * count(Solaire) / 60.0 / 1000.0)::numeric, 2) AS \"Solaire\",\n round((avg(Reseau) * count(Reseau) / 60.0 / 1000.0)::numeric, 2) AS \"Reseau\",\n round((avg(Maison) * count(Maison) / 60.0 / 1000.0)::numeric, 2) AS \"Maison\",\n round((avg(Voiture) * count(Voiture) / 60.0 / 1000.0)::numeric, 2) AS \"Voiture\"\nFROM report\nGROUP BY date_trunc('hour', t), to_char(t, 'DD/MM HH24')\nHAVING count(Solaire) > 0 OR count(Reseau) > 0 OR count(Maison) > 0 OR count(Voiture) > 0\nORDER BY date_trunc('hour', t)" } ], "gridPos": { diff --git a/deploy/historisation/grafana/dashboards/telephone.json b/deploy/historisation/grafana/dashboards/telephone.json index a382e31..95bbbe1 100644 --- a/deploy/historisation/grafana/dashboards/telephone.json +++ b/deploy/historisation/grafana/dashboards/telephone.json @@ -216,6 +216,7 @@ "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": true } }, @@ -327,6 +328,7 @@ "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": true } }, diff --git a/tools/gen-grafana-dashboards.py b/tools/gen-grafana-dashboards.py index 2273002..7d16d8e 100644 --- a/tools/gen-grafana-dashboards.py +++ b/tools/gen-grafana-dashboards.py @@ -91,6 +91,7 @@ def stat(title, targets, ds, x, y, w, h, desc="", overrides=None, texte="auto"): "colorMode": "value", "graphMode": "none", "justifyMode": "center", "percentChangeColorMode": "standard", + "noValue": "—", "wideLayout": True}} @@ -615,14 +616,36 @@ telephone = dashboard("evcs-telephone", "Sur le telephone", ( def flux_dernier(refid, mesure, entite, libelle, champ="value"): """Derniere valeur connue d'une entite, renommee pour l'affichage.""" - # Fenetre de 7 jours et non de quelques minutes : l'integration InfluxDB + # Fenetre de 6 HEURES : un compromis, et il merite d'etre explique. + # + # Trop large (7 jours, premiere version), le panneau Reseau affichait le + # 05/09 a minuit « Courant 2,2 A » — une valeur ecrite QUATORZE HEURES plus + # tot, du temps ou le contacteur etait ferme. Les capteurs du reseau + # passent en `unavailable` quand AC-IN disparait ; ils ne tombent pas a + # zero. Leur derniere valeur numerique reste donc celle d'avant, et elle + # ment. + # + # Trop etroite (30 minutes), on efface des valeurs JUSTES : la production + # nulle de la nuit est ecrite une fois au coucher du soleil et reste vraie + # jusqu'a l'aube. + # + # Six heures couvre une nuit sans soleil et une borne au repos, tout en + # ecartant une lecture vieille de quatorze heures. Au-dela, la case affiche + # un tiret — « aucune mesure recente », jamais un chiffre invente. + # Ancien commentaire : + # tentant — c'est ce que je faisais — mais le 05/09 a minuit le panneau + # Reseau affichait « Courant 2,2 A », valeur ecrite QUATORZE HEURES plus + # tot, du temps ou le contacteur etait ferme. Une case vide dit « aucune + # mesure recente » et c'est vrai ; un chiffre perime dit « voici la + # valeur » et c'est faux. + # Ancienne justification, conservee pour memoire : l'integration InfluxDB # de Home Assistant n'ecrit QUE sur changement d'etat. Une grandeur stable # — la borne a 0 A, voiture debranchee — n'a donc aucun point recent, et # une fenetre courte affiche une case vide la ou la valeur est simplement # constante. `last()` reste peu couteux sur une fenetre large. return flux(refid, f'from(bucket: "evcs")\n' - f' |> range(start: -7d)\n' + f' |> range(start: -6h)\n' f' |> filter(fn: (r) => r._measurement == "{mesure}"' f' and r.entity_id == "{entite}" and r._field == "{champ}")\n' f' |> last()\n' @@ -682,7 +705,7 @@ report AS ( for _, n in ENERGIE_CLES) + """ FROM paliers ) -SELECT to_char(t, 'HH24') || ' h' AS "Heure", +SELECT to_char(t, 'DD/MM HH24') AS "Heure", """ + ",\n".join( # Energie REELLEMENT accumulee : puissance moyenne x duree observee. # Pas la moyenne seule, qui comptait 22 minutes comme 60 et annoncait @@ -695,7 +718,7 @@ SELECT to_char(t, 'HH24') || ' h' AS "Heure", f' round((avg({n}) * count({n}) / 60.0 / 1000.0)::numeric, 2) AS "{n}"' for _, n in ENERGIE_CLES) + """ FROM report -GROUP BY date_trunc('hour', t), to_char(t, 'HH24') +GROUP BY date_trunc('hour', t), to_char(t, 'DD/MM HH24') HAVING """ + " OR ".join(f"count({n}) > 0" for _, n in ENERGIE_CLES) + """ ORDER BY date_trunc('hour', t)""" @@ -704,7 +727,7 @@ ORDER BY date_trunc('hour', t)""" TRACKERS_FLUX = '''import "strings" base = from(bucket: "evcs") - |> range(start: -7d) + |> range(start: -30m) |> filter(fn: (r) => r._field == "value") |> filter(fn: (r) => r._measurement == "V" or r._measurement == "A" or r._measurement == "W") |> last() @@ -738,7 +761,7 @@ systeme = dashboard("evcs-systeme", "Le systeme", ( "Replique locale de la vue generale VRM. La console Victron est hebergee " "dans le cloud : elle disparait quand une coupure d'orage emporte " "Internet. Tout ce qui est affiche ici est lu sur le reseau local."), - frm="now/d", refresh="30s", panels=[ + frm="now-24h", refresh="30s", panels=[ stat("Reseau", [ flux_dernier("A", "W", "victron_grid_power_l1", "Puissance"),