Trois demandes du proprietaire apres usage reel. 1. SELECTEUR DE VUE. Variable « vue » en haut du tableau, dans l'esprit de VRM : Vue generale / Consommation / Reseau / Batterie / Chargeur VE. La valeur de chaque option est directement une alternative d'expression reguliere, consommee par la transformation filterFieldsByName des deux graphiques — d'ou le separateur « | ». Un seul jeu de requetes, cinq lectures. 2. PAS ADAPTATIF. L'histogramme d'energie suit desormais la periode choisie : l'heure jusqu'a 4 jours, le jour jusqu'a 70, le mois au-dela. Sans cela « 30 derniers jours » rendait 720 barres illisibles. C'est ce que fait VRM en passant de l'heure au jour puis au mois. 3. PANNEAU BATTERIE ILLISIBLE — un defaut que j'avais cree. Cinq valeurs dans huit colonnes : Grafana reduisait le texte jusqu'a l'illisible. Porte a dix colonnes avec une taille imposee, plutot que de laisser l'ajustement automatique decider. Reseau et Charges CA resserres en consequence. Ajout lie a la panne en cours : panneau « Ce que le BMS impose » — limite de courant de charge, alarme de tension de cellule, desequilibre, etat de sante. C'est ce qu'il faudra regarder cet apres-midi. Sa fenetre de lecture est de 48 h, deliberement differente des 6 h du reste : un etat d'alarme ne devient jamais indisponible, il se publie, donc sa derniere valeur EST la valeur courante meme vieille de dix heures. A l'inverse du courant reseau, dont le capteur disparait et laisse un chiffre qui ment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
520 lines
16 KiB
JSON
520 lines
16 KiB
JSON
{
|
|
"templating": {
|
|
"list": []
|
|
},
|
|
"uid": "evcs-solaire",
|
|
"title": "Le solaire",
|
|
"description": "La production mesuree n'est jamais la production disponible : sans injection, le MPPT ne produit que ce que le systeme peut absorber. Ces panneaux montrent l'ecart entre les deux.",
|
|
"tags": [
|
|
"evcs"
|
|
],
|
|
"timezone": "Europe/Paris",
|
|
"editable": true,
|
|
"schemaVersion": 39,
|
|
"version": 1,
|
|
"refresh": "1m",
|
|
"time": {
|
|
"from": "now-24h",
|
|
"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": true,
|
|
"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) ORDER BY 1"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"panels": [
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Production, maison, et ce qui reste",
|
|
"description": "L'excedent (production moins maison hors voiture) est la grandeur qui decide d'un demarrage depuis le 03/09. Le 03/09 a 19:44, la production valait 758 W — au-dessus du seuil — pour un excedent de MOINS 444 W : la voiture a vide la batterie.",
|
|
"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": "WITH par_minute AS (\n SELECT date_trunc('minute', ts) AS t,\n avg(valeur) FILTER (WHERE cle = 'sensor.victron_pv_power_system') AS Production,\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),\npaliers AS (\n SELECT t, Production, Maison, Voiture,\n count(Production) OVER (ORDER BY t) AS g_Production,\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(Production) OVER (PARTITION BY g_Production ORDER BY t) AS Production,\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 t AS time,\n Production AS \"Production\",\n Maison AS \"Maison\",\n Voiture AS \"Voiture\",\n Production - Maison AS \"Excedent\"\nFROM report ORDER BY t"
|
|
}
|
|
],
|
|
"gridPos": {
|
|
"x": 0,
|
|
"y": 0,
|
|
"w": 24,
|
|
"h": 9
|
|
},
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"unit": "watt",
|
|
"color": {
|
|
"mode": "palette-classic"
|
|
},
|
|
"custom": {
|
|
"lineWidth": 2,
|
|
"fillOpacity": 8,
|
|
"showPoints": "never",
|
|
"spanNulls": true,
|
|
"axisBorderShow": false,
|
|
"gradientMode": "opacity"
|
|
}
|
|
},
|
|
"overrides": [
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "Production"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "yellow"
|
|
}
|
|
},
|
|
{
|
|
"id": "custom.fillOpacity",
|
|
"value": 22
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "Maison"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "text"
|
|
}
|
|
},
|
|
{
|
|
"id": "custom.fillOpacity",
|
|
"value": 0
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "Voiture"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "blue"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "Excedent"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "green"
|
|
}
|
|
},
|
|
{
|
|
"id": "custom.lineWidth",
|
|
"value": 3
|
|
},
|
|
{
|
|
"id": "custom.fillOpacity",
|
|
"value": 0
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": true,
|
|
"calcs": []
|
|
},
|
|
"tooltip": {
|
|
"mode": "multi",
|
|
"sort": "desc"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "state-timeline",
|
|
"title": "Production bridee ?",
|
|
"description": "Bridee = de la ressource solaire est REFUSEE faute de preneur. Charger la voiture pendant ces heures-la ne coute rien.",
|
|
"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 ts AS time,\n CASE WHEN pv_censure THEN coalesce(motif_censure, 'bridee')\n ELSE 'libre' END AS \"Production\"\nFROM bilan\nWHERE $__timeFilter(ts)\nORDER BY 1"
|
|
}
|
|
],
|
|
"gridPos": {
|
|
"x": 0,
|
|
"y": 9,
|
|
"w": 12,
|
|
"h": 6
|
|
},
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"color": {
|
|
"mode": "continuous-GrYlRd"
|
|
},
|
|
"custom": {
|
|
"lineWidth": 0,
|
|
"fillOpacity": 80,
|
|
"insertNulls": false,
|
|
"spanNulls": true
|
|
},
|
|
"mappings": [
|
|
{
|
|
"type": "value",
|
|
"options": {
|
|
"libre": {
|
|
"color": "green",
|
|
"index": 0
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "regex",
|
|
"options": {
|
|
"pattern": ".*",
|
|
"result": {
|
|
"color": "orange",
|
|
"index": 1
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"overrides": []
|
|
},
|
|
"options": {
|
|
"showValue": "auto",
|
|
"mergeValues": true,
|
|
"alignValue": "left",
|
|
"rowHeight": 0.85,
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": false
|
|
},
|
|
"tooltip": {
|
|
"mode": "single"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "state-timeline",
|
|
"title": "Ce que les chargeurs declarent eux-memes",
|
|
"description": "mppt_active = ce chargeur donne tout ce qu'il peut. voltage_current_limited ou off = il se retient, faute de preneur. Le 03/09 ces capteurs ont bascule 24 minutes avant le drapeau du bilan — c'est le signal le plus direct dont on dispose.",
|
|
"datasource": {
|
|
"type": "influxdb",
|
|
"uid": "evcs-influx"
|
|
},
|
|
"targets": [
|
|
{
|
|
"refId": "A",
|
|
"datasource": {
|
|
"type": "influxdb",
|
|
"uid": "evcs-influx"
|
|
},
|
|
"query": "from(bucket: \"evcs\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._field == \"state\")\n |> filter(fn: (r) => r._measurement =~ /operation_mode$/)\n |> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)\n |> map(fn: (r) => ({ r with tracker:\n if r._measurement =~ /solar_1/ then \"Sud 1\"\n else if r._measurement =~ /solar_2/ then \"Sud 2\"\n else if r._measurement =~ /solar_3/ then \"Sud 3\"\n else if r._measurement =~ /solar_4/ then \"Ouest\"\n else if r._measurement =~ /mppt1/ then \"Sud-est\"\n else \"Ensemble\" }))\n |> keep(columns: [\"_time\", \"_value\", \"tracker\"])\n |> pivot(rowKey: [\"_time\"], columnKey: [\"tracker\"], valueColumn: \"_value\")"
|
|
}
|
|
],
|
|
"gridPos": {
|
|
"x": 12,
|
|
"y": 9,
|
|
"w": 12,
|
|
"h": 6
|
|
},
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"color": {
|
|
"mode": "continuous-GrYlRd"
|
|
},
|
|
"custom": {
|
|
"lineWidth": 0,
|
|
"fillOpacity": 80,
|
|
"insertNulls": false,
|
|
"spanNulls": true
|
|
},
|
|
"mappings": [
|
|
{
|
|
"type": "value",
|
|
"options": {
|
|
"mppt_active": {
|
|
"color": "green",
|
|
"index": 0
|
|
},
|
|
"voltage_current_limited": {
|
|
"color": "orange",
|
|
"index": 1
|
|
},
|
|
"off": {
|
|
"color": "dark-blue",
|
|
"index": 2
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"overrides": []
|
|
},
|
|
"options": {
|
|
"showValue": "auto",
|
|
"mergeValues": true,
|
|
"alignValue": "left",
|
|
"rowHeight": 0.85,
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": false
|
|
},
|
|
"tooltip": {
|
|
"mode": "single"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Batterie",
|
|
"description": "Le SOC n'est pas lineaire : 0,169 kWh par point au-dessus de 33 %, 0,097 en dessous (576 paliers mesures). Un point en bas d'echelle vaut la moitie d'un point en haut.",
|
|
"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 date_trunc('minute', ts) AS time, avg(valeur) AS \"SOC\"\nFROM mesure WHERE cle = 'sensor.victron_battery_soc'\n AND $__timeFilter(ts) GROUP BY 1 ORDER BY 1"
|
|
},
|
|
{
|
|
"refId": "B",
|
|
"datasource": {
|
|
"type": "grafana-postgresql-datasource",
|
|
"uid": "evcs-pg"
|
|
},
|
|
"format": "time_series",
|
|
"rawQuery": true,
|
|
"editorMode": "code",
|
|
"rawSql": "SELECT date_trunc('minute', ts) AS time, avg(valeur) AS \"Courant\"\nFROM mesure WHERE cle = 'sensor.victron_battery_current'\n AND $__timeFilter(ts) GROUP BY 1 ORDER BY 1"
|
|
}
|
|
],
|
|
"gridPos": {
|
|
"x": 0,
|
|
"y": 15,
|
|
"w": 12,
|
|
"h": 8
|
|
},
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"unit": "percent",
|
|
"color": {
|
|
"mode": "palette-classic"
|
|
},
|
|
"custom": {
|
|
"lineWidth": 2,
|
|
"fillOpacity": 8,
|
|
"showPoints": "never",
|
|
"spanNulls": true,
|
|
"axisBorderShow": false,
|
|
"gradientMode": "opacity"
|
|
},
|
|
"min": 0,
|
|
"max": 100
|
|
},
|
|
"overrides": [
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "Courant"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "unit",
|
|
"value": "amp"
|
|
},
|
|
{
|
|
"id": "custom.axisPlacement",
|
|
"value": "right"
|
|
},
|
|
{
|
|
"id": "max",
|
|
"value": null
|
|
},
|
|
{
|
|
"id": "min",
|
|
"value": null
|
|
},
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "purple"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"matcher": {
|
|
"id": "byName",
|
|
"options": "SOC"
|
|
},
|
|
"properties": [
|
|
{
|
|
"id": "color",
|
|
"value": {
|
|
"mode": "fixed",
|
|
"fixedColor": "green"
|
|
}
|
|
},
|
|
{
|
|
"id": "custom.lineWidth",
|
|
"value": 3
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"options": {
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": true,
|
|
"calcs": []
|
|
},
|
|
"tooltip": {
|
|
"mode": "multi",
|
|
"sort": "desc"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"type": "timeseries",
|
|
"title": "Le detail que PostgreSQL ne voit pas (~1 point/s)",
|
|
"description": "InfluxDB enregistre chaque changement d'etat, pas un echantillon par minute. C'est la resolution qu'il faut pour voir un transitoire de reprise du reseau (~150 s) ou une pointe de cuisson.",
|
|
"datasource": {
|
|
"type": "influxdb",
|
|
"uid": "evcs-influx"
|
|
},
|
|
"targets": [
|
|
{
|
|
"refId": "A",
|
|
"datasource": {
|
|
"type": "influxdb",
|
|
"uid": "evcs-influx"
|
|
},
|
|
"query": "from(bucket: \"evcs\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._measurement == \"W\" and r._field == \"value\")\n |> filter(fn: (r) => r.entity_id == \"victron_pv_power_system\"\n or r.entity_id == \"victron_consumption_power_l1\"\n or r.entity_id == \"victron_evcs_ac_power\"\n or r.entity_id == \"victron_grid_power_l1\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> keep(columns: [\"_time\", \"_value\", \"entity_id\"])\n |> pivot(rowKey: [\"_time\"], columnKey: [\"entity_id\"], valueColumn: \"_value\")"
|
|
}
|
|
],
|
|
"gridPos": {
|
|
"x": 12,
|
|
"y": 15,
|
|
"w": 12,
|
|
"h": 8
|
|
},
|
|
"fieldConfig": {
|
|
"defaults": {
|
|
"unit": "watt",
|
|
"color": {
|
|
"mode": "palette-classic"
|
|
},
|
|
"custom": {
|
|
"lineWidth": 1,
|
|
"fillOpacity": 5,
|
|
"showPoints": "never",
|
|
"spanNulls": true
|
|
}
|
|
},
|
|
"overrides": []
|
|
},
|
|
"options": {
|
|
"legend": {
|
|
"displayMode": "list",
|
|
"placement": "bottom",
|
|
"showLegend": true,
|
|
"calcs": []
|
|
},
|
|
"tooltip": {
|
|
"mode": "multi",
|
|
"sort": "desc"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|