Files
EVCS/deploy/historisation/grafana/dashboards/batteries.json
Tallagrand Thierry 463f1b1b06 Les cellules disent desormais si le module chargeait
Le proprietaire veut « dans Grafana le detail de chaque cellule pendant la
charge ». Le detail existait deja ; ce qui manquait etait le « pendant la
charge » — rien ne disait QUAND le module chargeait, et un ecart entre cellules
ne veut rien dire hors de son courant : le 05/09 la cellule meneuse etait a
3555 mV sous 50 A et a 3496 mV sous 30 A, meme module, meme tension de parc.

Le releve console porte le courant depuis le 17/09, mais l ingestion ecrivait
`null` : elle ne lisait que les quinze tensions. Elle repere maintenant la
colonne `courant_mA` PAR SON NOM — les US5000 et les US2000C n emettent pas les
memes colonnes, et une position ferait lire la mauvaise grandeur des qu on
deplace le cable d un pack a l autre. Absente des anciens fichiers, donc les
lignes deja versees gardent leur courant inconnu.

Deux panneaux au tableau « Les batteries ».

« Sante des modules — tous, d un coup d oeil » : le resume qu on lit en premier,
tous modules ensemble, la ou les autres panneaux demandent de choisir un module
d avance. Ecart maintenant, ecart maximum sur la periode, cellule la plus haute
et la plus basse, courant au moment du releve, date du dernier releve. Releve au
deploiement : cinq modules vivants, ecarts de 1 a 3 mV — le parc restant est
sain, les trois modules atteints sont sortis le 12/09.

« Le module chargeait-il ? » : le courant du MODULE, lu dans la table des
cellules et non dans celle du parc, ce qui permet de voir qu un module se
charge moins que ses voisins.

Verifie contre la base et pas seulement execute : 75/75 requetes valides ne
prouve que l execution, donc les deux nouvelles ont ete rejouees avec la vraie
fenetre et rendent bien les grandeurs voulues.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
2026-09-18 02:56:03 +02:00

731 lines
22 KiB
JSON

{
"templating": {
"list": [
{
"name": "module",
"label": "Module",
"type": "query",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"refresh": 1,
"includeAll": false,
"multi": false,
"query": "SELECT DISTINCT module FROM cellule ORDER BY 1"
}
]
},
"uid": "evcs-batteries",
"title": "Les batteries",
"description": "Les quinze tensions de cellule de chaque module Pylontech, relevees sur la console de leur BMS. Aucune de ces valeurs n'existe cote Victron, qui ne publie que l'agregat du parc. Les paliers de couleur sont ceux du materiel lui-meme : 3480, 3520, 3550 et 3600 mV.",
"tags": [
"evcs"
],
"timezone": "Europe/Paris",
"editable": true,
"schemaVersion": 39,
"version": 1,
"refresh": "1m",
"time": {
"from": "now-7d",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"30s",
"1m",
"5m",
"15m",
"1h"
]
},
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"name": "Annotations & Alerts",
"iconColor": "rgba(0, 211, 255, 1)",
"type": "dashboard"
},
{
"name": "Evenements",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"enable": false,
"iconColor": "semi-dark-orange",
"hide": false,
"target": {
"format": "table",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, resume AS text, genre || ',' || coalesce(source,'?') AS tags FROM evenement WHERE $__timeFilter(ts) AND genre <> 'bilan' ORDER BY 1"
}
}
]
},
"panels": [
{
"type": "table",
"title": "Sante des modules — tous, d'un coup d'oeil",
"description": "Le resume qu'on lit en premier, tous modules ensemble — les autres panneaux demandent de choisir un module d'avance. L'ecart entre la cellule la plus haute et la plus basse est l'indicateur qui resume un module en un nombre : sous 20 mV il est sain, au-dela de 150 mV le BMS reduit le courant de charge de TOUT le parc. La colonne « Courant » dit si le module etait en charge au moment du releve : un ecart ne se compare qu'a courant comparable.",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "table",
"rawQuery": true,
"editorMode": "code",
"rawSql": "WITH vivants AS (\n SELECT module FROM cellule GROUP BY module\n HAVING max(ts) > now() - interval '2 hours'),\ndernier AS (\n SELECT DISTINCT ON (module) module, ts FROM cellule\n WHERE module IN (SELECT module FROM vivants)\n ORDER BY module, ts DESC),\nmaintenant AS (\n SELECT c.module, max(c.mv) - min(c.mv) AS ecart,\n max(c.mv) AS haute, min(c.mv) AS basse,\n max(c.courant_ma) AS ma, d.ts\n FROM cellule c JOIN dernier d ON d.module = c.module AND d.ts = c.ts\n GROUP BY c.module, d.ts),\nperiode AS (\n SELECT module, max(ecart) AS ecart_max FROM (\n SELECT module, ts, max(mv) - min(mv) AS ecart\n FROM cellule WHERE $__timeFilter(ts) GROUP BY module, ts) x\n GROUP BY module)\nSELECT m.module AS \"Module\",\n m.ecart AS \"Ecart maintenant\",\n p.ecart_max AS \"Ecart max sur la periode\",\n m.haute AS \"Plus haute\", m.basse AS \"Plus basse\",\n round(m.ma / 1000.0, 1) AS \"Courant (A)\",\n to_char(m.ts, 'DD/MM HH24:MI') AS \"Dernier releve\"\n FROM maintenant m LEFT JOIN periode p USING (module)\n ORDER BY m.ecart DESC"
}
],
"gridPos": {
"x": 0,
"y": 0,
"w": 24,
"h": 8
},
"fieldConfig": {
"defaults": {
"custom": {
"align": "left",
"cellOptions": {
"type": "auto"
},
"filterable": true
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Ecart maintenant"
},
"properties": [
{
"id": "unit",
"value": "mvolt"
},
{
"id": "custom.cellOptions",
"value": {
"type": "color-background"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 20
},
{
"color": "orange",
"value": 80
},
{
"color": "red",
"value": 150
}
]
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Ecart max sur la periode"
},
"properties": [
{
"id": "unit",
"value": "mvolt"
},
{
"id": "custom.cellOptions",
"value": {
"type": "color-text"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 50
},
{
"color": "orange",
"value": 150
},
{
"color": "red",
"value": 300
}
]
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Plus haute"
},
"properties": [
{
"id": "unit",
"value": "mvolt"
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 3480
},
{
"color": "orange",
"value": 3520
},
{
"color": "red",
"value": 3550
},
{
"color": "dark-red",
"value": 3600
}
]
}
},
{
"id": "custom.cellOptions",
"value": {
"type": "color-text"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Plus basse"
},
"properties": [
{
"id": "unit",
"value": "mvolt"
}
]
},
{
"matcher": {
"id": "byName",
"options": "Courant (A)"
},
"properties": [
{
"id": "unit",
"value": "amp"
},
{
"id": "decimals",
"value": 1
}
]
}
]
},
"options": {
"showHeader": true,
"cellHeight": "sm",
"footer": {
"show": false
}
}
},
{
"type": "timeseries",
"title": "Cellule par cellule — $module",
"description": "Une courbe par cellule. Une cellule saine suit exactement ses quatorze voisines ; une cellule qui a perdu de la capacite s'en detache en haut de charge ET en bas de decharge, parce qu'elle se remplit et se vide avant les autres.",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "time_series",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, 'cellule ' || lpad(cellule::text, 2, '0') AS metric,\n mv\nFROM cellule\nWHERE module = '$module' AND $__timeFilter(ts)\nORDER BY 1, 2"
}
],
"gridPos": {
"x": 0,
"y": 8,
"w": 24,
"h": 10
},
"fieldConfig": {
"defaults": {
"custom": {
"lineWidth": 1
},
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 3480
},
{
"color": "orange",
"value": 3520
},
{
"color": "red",
"value": 3550
},
{
"color": "dark-red",
"value": 3600
}
]
},
"custom.thresholdsStyle": {
"mode": "dashed"
}
}
},
"options": {
"legend": {
"displayMode": "list",
"placement": "right",
"showLegend": true,
"calcs": []
},
"tooltip": {
"mode": "multi",
"sort": "desc"
}
}
},
{
"type": "timeseries",
"title": "Le module chargeait-il ? — $module",
"description": "Positif en charge, negatif en decharge. A lire en regard du panneau au-dessus : l'ecart entre cellules s'ouvre avec le courant, et une cellule abimee ne se trahit qu'en charge.",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "time_series",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, 'courant du module' AS metric,\n courant_ma / 1000.0 AS a\nFROM cellule\nWHERE module = '$module' AND cellule = 1\n AND courant_ma IS NOT NULL AND $__timeFilter(ts)\nORDER BY 1"
}
],
"gridPos": {
"x": 0,
"y": 18,
"w": 24,
"h": 5
},
"fieldConfig": {
"defaults": {
"unit": "amp",
"color": {
"mode": "palette-classic"
},
"custom": {
"fillOpacity": 15,
"lineWidth": 1
}
},
"overrides": []
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
"calcs": []
},
"tooltip": {
"mode": "multi",
"sort": "desc"
}
}
},
{
"type": "timeseries",
"title": "Ecart entre la plus haute et la plus basse",
"description": "L'indicateur qui resume un module en une courbe. Un module sain de ce parc tient sous 20 mV ; au-dela de 150 mV le BMS commence a reduire le courant de charge de TOUT le parc.",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "time_series",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, module AS metric, max(mv) - min(mv) AS ecart\nFROM cellule WHERE $__timeFilter(ts)\n AND module IN (SELECT module FROM cellule\n GROUP BY module HAVING max(ts) > now() - interval '2 hours')\nGROUP BY ts, module ORDER BY 1"
}
],
"gridPos": {
"x": 0,
"y": 23,
"w": 12,
"h": 8
},
"fieldConfig": {
"defaults": {
"unit": "mvolt",
"color": {
"mode": "palette-classic"
},
"custom": {
"lineWidth": 2,
"fillOpacity": 8,
"showPoints": "never",
"spanNulls": true,
"axisBorderShow": false,
"gradientMode": "opacity"
}
},
"overrides": []
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
"calcs": []
},
"tooltip": {
"mode": "multi",
"sort": "desc"
}
}
},
{
"type": "timeseries",
"title": "La cellule meneuse, contre le plafond que le BMS impose",
"description": "Le plafond de charge est trace a l'echelle (20 mV par ampere) pour tenir sur le meme axe. Le 05/09 a 13:05:08 la cellule meneuse est passee de 3541 a 3555 mV ; cinq secondes plus tard le plafond tombait de 50 a 30 A. Ensuite le courant baisse, la cellule se detend, l'alarme repasse au vert — et le plafond, lui, reste bas.",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "time_series",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, module || ' — cellule meneuse' AS metric,\n max(mv) AS mv\nFROM cellule WHERE $__timeFilter(ts)\n AND module IN (SELECT module FROM cellule\n GROUP BY module HAVING max(ts) > now() - interval '2 hours')\nGROUP BY ts, module ORDER BY 1"
},
{
"refId": "B",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "time_series",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, 'plafond de charge (A)' AS metric,\n valeur * 20 AS mv\nFROM mesure\nWHERE cle = 'sensor.airtria_8_us2000c_maximum_allowed_charge_current'\n AND $__timeFilter(ts) ORDER BY 1"
}
],
"gridPos": {
"x": 12,
"y": 23,
"w": 12,
"h": 8
},
"fieldConfig": {
"defaults": {
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 3480
},
{
"color": "orange",
"value": 3520
},
{
"color": "red",
"value": 3550
},
{
"color": "dark-red",
"value": 3600
}
]
}
}
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
"calcs": []
},
"tooltip": {
"mode": "multi",
"sort": "desc"
}
}
},
{
"type": "table",
"title": "Amplitude de chaque cellule sur la periode",
"description": "Le classement qui designe les cellules a traiter. Sur un module sain les quinze amplitudes sont identiques a quelques millivolts pres. Une amplitude de trois a quatre fois celle des voisines designe une cellule qui a perdu sa capacite — et cela ne se rattrape pas par un reequilibrage.",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "table",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT cellule AS \"Cellule\",\n min(mv) AS \"Minimum\", max(mv) AS \"Maximum\",\n max(mv) - min(mv) AS \"Amplitude\"\nFROM cellule\nWHERE module = '$module' AND $__timeFilter(ts)\nGROUP BY cellule ORDER BY 4 DESC"
}
],
"gridPos": {
"x": 0,
"y": 31,
"w": 12,
"h": 10
},
"fieldConfig": {
"defaults": {
"custom": {
"align": "left",
"cellOptions": {
"type": "auto"
},
"filterable": true
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Amplitude"
},
"properties": [
{
"id": "custom.cellOptions",
"value": {
"type": "color-background"
}
},
{
"id": "unit",
"value": "mvolt"
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 250
},
{
"color": "orange",
"value": 400
},
{
"color": "red",
"value": 600
}
]
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Minimum"
},
"properties": [
{
"id": "unit",
"value": "mvolt"
}
]
},
{
"matcher": {
"id": "byName",
"options": "Maximum"
},
"properties": [
{
"id": "unit",
"value": "mvolt"
}
]
}
]
},
"options": {
"showHeader": true,
"cellHeight": "sm",
"footer": {
"show": false
}
}
},
{
"type": "timeseries",
"title": "Etat de charge du parc pendant les relevés",
"description": "Le contexte sans lequel un ecart entre cellules ne veut rien dire : l'ecart grandit avec l'etat de charge, et l'excursion de la cellule abimee grandit avec le courant. Le 05/09, a tension de parc egale, la meneuse etait a 3555 mV sous 50 A et a 3496 mV sous 30 A.",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"targets": [
{
"refId": "A",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "time_series",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, valeur AS \"SOC du parc\"\nFROM mesure WHERE cle = 'sensor.victron_battery_soc'\n AND $__timeFilter(ts) ORDER BY 1"
},
{
"refId": "B",
"datasource": {
"type": "grafana-postgresql-datasource",
"uid": "evcs-pg"
},
"format": "time_series",
"rawQuery": true,
"editorMode": "code",
"rawSql": "SELECT ts AS time, valeur AS \"Courant du parc\"\nFROM mesure WHERE cle = 'sensor.victron_battery_current'\n AND $__timeFilter(ts) ORDER BY 1"
}
],
"gridPos": {
"x": 12,
"y": 31,
"w": 12,
"h": 10
},
"fieldConfig": {
"defaults": {
"unit": "",
"color": {
"mode": "palette-classic"
},
"custom": {
"lineWidth": 2,
"fillOpacity": 8,
"showPoints": "never",
"spanNulls": true,
"axisBorderShow": false,
"gradientMode": "opacity"
}
},
"overrides": []
},
"options": {
"legend": {
"displayMode": "list",
"placement": "bottom",
"showLegend": true,
"calcs": []
},
"tooltip": {
"mode": "multi",
"sort": "desc"
}
}
}
]
}