Le tableau du systeme : fenetre glissante, et plus de valeur perimee

Trois defauts signales par le proprietaire sur une capture prise a 00:04.

1. FENETRE GLISSANTE. La plage etait « aujourd'hui » : a 00:04 il n'y avait que
   quatre minutes a montrer. Passee a 24 h glissantes. Les etiquettes d'heure
   portent desormais le jour, sans quoi « 22 h » designerait deux heures
   differentes dans la meme fenetre.

2. VALEUR PERIMEE PRESENTEE COMME ACTUELLE — le vrai defaut. Le panneau Reseau
   affichait « Courant 2,2 A » : ecrit QUATORZE HEURES plus tot, du temps ou le
   contacteur etait ferme, alors qu'il est ouvert depuis 10:08. Cause : ma
   fenetre de lecture de 7 jours, posee pour eviter les cases vides.

   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. Fenetre ramenee a 6 h : assez large pour couvrir une nuit sans
   soleil et une borne au repos — dont les zeros sont VRAIS — assez etroite
   pour ecarter une lecture de quatorze heures.

3. Une absence de mesure s'affiche desormais comme un tiret, jamais comme zero.

Verifie apres coup sur les valeurs reelles : Reseau Courant = tiret (la valeur
fausse a disparu), Chargeur PV = 0 W et Chargeur VE = 0 A conserves puisque
justes, Batterie et Charges CA en direct.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
Tallagrand Thierry
2026-09-05 01:05:22 +02:00
parent 0adf86fe1e
commit 38ed843536
3 changed files with 54 additions and 24 deletions

View File

@@ -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": {