La fenetre de lecture depend du comportement de l'entite au repos
« No data » sur le panneau Chargeur PV a 03:20 : la production avait ete ecrite pour la derniere fois au coucher du soleil, 370 minutes plus tot, et ma fenetre etait de 6 h. La valeur zero etait pourtant exacte et connue. C'est la seconde erreur sur ce meme reglage, en sens inverse de la premiere : - trop LARGE partout (7 jours), le panneau Reseau affichait un courant vieux de quatorze heures, parce que ces capteurs passent en `unavailable` quand AC-IN s'ouvre au lieu de tomber a zero ; - trop ETROITE partout (6 heures), les entites qui publient un vrai zero au repos disparaissent de l'ecran alors que leur derniere valeur reste juste. Il n'y a donc pas de bonne valeur unique. Regle inscrite dans le generateur : fenetre LARGE (24 h) pour ce qui publie un vrai zero — production PV, borne a l'arret, trackers ; fenetre COURTE (6 h) pour ce qui disparait, c'est-a-dire les seules grandeurs du reseau. Consigne au passage dans le manuel : le proprietaire possede une troisieme monture, une moto electrique Zero Motorcycles SR/F, a ajouter au selecteur fin septembre. Avec la remarque qui compte : sa batterie et son chargeur embarque etant bien plus petits, elle sera peut-etre le premier vehicule du foyer electriquement distinguable des deux autres. 53/53 requetes verifiees. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
This commit is contained in:
@@ -242,7 +242,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Consommation\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_consumption_power_l1\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Consommation\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "B",
|
"refId": "B",
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Frequence\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\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: [\"_value\"])\n |> rename(columns: {_value: \"Frequence\"})"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"gridPos": {
|
"gridPos": {
|
||||||
@@ -343,7 +343,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Charge\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"%\" and r.entity_id == \"victron_battery_soc\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Charge\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "B",
|
"refId": "B",
|
||||||
@@ -351,7 +351,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Puissance\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_battery_power\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Puissance\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "C",
|
"refId": "C",
|
||||||
@@ -359,7 +359,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Tension\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"V\" and r.entity_id == \"victron_battery_voltage\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Tension\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "D",
|
"refId": "D",
|
||||||
@@ -367,7 +367,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Courant\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_battery_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Courant\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "E",
|
"refId": "E",
|
||||||
@@ -375,7 +375,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Temperature\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"°C\" and r.entity_id == \"victron_battery_temperature\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Temperature\"})"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"gridPos": {
|
"gridPos": {
|
||||||
@@ -544,7 +544,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Puissance\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_evcs_ac_power\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Puissance\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "B",
|
"refId": "B",
|
||||||
@@ -552,7 +552,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Courant\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_evcs_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Courant\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "C",
|
"refId": "C",
|
||||||
@@ -560,7 +560,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Consigne\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"A\" and r.entity_id == \"victron_evcs_set_current\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Consigne\"})"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"gridPos": {
|
"gridPos": {
|
||||||
@@ -669,7 +669,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Production\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\n |> filter(fn: (r) => r._measurement == \"W\" and r.entity_id == \"victron_pv_power_system\" and r._field == \"value\")\n |> last()\n |> keep(columns: [\"_value\"])\n |> rename(columns: {_value: \"Production\"})"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"refId": "B",
|
"refId": "B",
|
||||||
@@ -677,7 +677,7 @@
|
|||||||
"type": "influxdb",
|
"type": "influxdb",
|
||||||
"uid": "evcs-influx"
|
"uid": "evcs-influx"
|
||||||
},
|
},
|
||||||
"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: [\"_value\"])\n |> rename(columns: {_value: \"Moyenne 10 min\"})"
|
"query": "from(bucket: \"evcs\")\n |> range(start: -24h)\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: [\"_value\"])\n |> rename(columns: {_value: \"Moyenne 10 min\"})"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"gridPos": {
|
"gridPos": {
|
||||||
|
|||||||
@@ -125,6 +125,32 @@ de Home Assistant peut l'annuler (constate le 04/09 a 19:44, cf. HANDOFF §47).
|
|||||||
L'heure de **debranchement** confirme a posteriori, les deux vehicules partant
|
L'heure de **debranchement** confirme a posteriori, les deux vehicules partant
|
||||||
a des heures differentes (JEEP ~06:30, VW ~08:50).
|
a des heures differentes (JEEP ~06:30, VW ~08:50).
|
||||||
|
|
||||||
|
### Un TROISIEME vehicule a venir : la moto
|
||||||
|
|
||||||
|
Le proprietaire possede une **moto electrique Zero Motorcycles SR/F**. Elle
|
||||||
|
n'est pas chargee actuellement — il s'est ecrase le majeur de la main droite
|
||||||
|
avec une betonneuse et enfiler un gant est difficile — et il pense reconduire
|
||||||
|
**fin septembre 2026**.
|
||||||
|
|
||||||
|
A faire a ce moment-la, et rien avant :
|
||||||
|
1. ajouter `ZERO` aux options de `input_select.victron_evcs_vehicle`
|
||||||
|
(paquet `victron_evcs_vehicles.yaml`, puis rechargement des entrees) ;
|
||||||
|
2. creer son heure de depart si elle differe
|
||||||
|
(`input_datetime.victron_evcs_departure_time_zero`) et l'ajouter au choix
|
||||||
|
de `departureTimeMin` dans `INPUT_PARSE.js`, a cote de VW et JEEP ;
|
||||||
|
3. la table `session_charge` n'a rien a changer : elle enregistre la valeur du
|
||||||
|
selecteur, quelle qu'elle soit.
|
||||||
|
|
||||||
|
⚠️ Une moto a une batterie bien plus petite qu'une voiture (une SR/F est de
|
||||||
|
l'ordre de 14 a 17 kWh) et un chargeur embarque plus faible. **C'est donc
|
||||||
|
peut-etre le premier vehicule du foyer qui soit electriquement distinguable
|
||||||
|
des deux autres** — a verifier le moment venu, en comparant son plateau de
|
||||||
|
puissance a consigne elevee aux 3 655 / 3 680 W de la JEEP et de la VW.
|
||||||
|
|
||||||
|
NB : un ancien `input_select.victron_evcs_target_vehicle` (None/Jeep/Zero)
|
||||||
|
existe encore, cree par l'interface et cable nulle part. Ne pas le confondre
|
||||||
|
avec le selecteur en service, ni le reutiliser.
|
||||||
|
|
||||||
### Consommation de la maison — pilotee par les repas, pas par une courbe lisse
|
### Consommation de la maison — pilotee par les repas, pas par une courbe lisse
|
||||||
> Donne par le proprietaire le 03/09/2026. **A ne pas redecouvrir.**
|
> Donne par le proprietaire le 03/09/2026. **A ne pas redecouvrir.**
|
||||||
|
|
||||||
|
|||||||
@@ -620,35 +620,24 @@ telephone = dashboard("evcs-telephone", "Sur le telephone", (
|
|||||||
# variation de -373 kWh sur une heure. Integrer la puissance ignore
|
# variation de -373 kWh sur une heure. Integrer la puissance ignore
|
||||||
# completement ce probleme.
|
# completement ce probleme.
|
||||||
|
|
||||||
def flux_dernier(refid, mesure, entite, libelle, champ="value", fenetre="6h"):
|
def flux_dernier(refid, mesure, entite, libelle, champ="value", fenetre="24h"):
|
||||||
"""Derniere valeur connue d'une entite, renommee pour l'affichage."""
|
"""Derniere valeur connue d'une entite, renommee pour l'affichage."""
|
||||||
# Fenetre de 6 HEURES : un compromis, et il merite d'etre explique.
|
# LA FENETRE DEPEND DU COMPORTEMENT DE L'ENTITE AU REPOS, pas d'un
|
||||||
|
# compromis unique. C'est la lecon de deux erreurs successives :
|
||||||
#
|
#
|
||||||
# Trop large (7 jours, premiere version), le panneau Reseau affichait le
|
# - trop LARGE partout (7 jours) : le panneau Reseau affichait le 05/09 a
|
||||||
# 05/09 a minuit « Courant 2,2 A » — une valeur ecrite QUATORZE HEURES plus
|
# minuit « Courant 2,2 A », valeur ecrite quatorze heures plus tot. Les
|
||||||
# tot, du temps ou le contacteur etait ferme. Les capteurs du reseau
|
# capteurs du reseau passent en `unavailable` quand AC-IN disparait ;
|
||||||
# passent en `unavailable` quand AC-IN disparait ; ils ne tombent pas a
|
# ils ne tombent pas a zero, et leur derniere valeur numerique ment.
|
||||||
# zero. Leur derniere valeur numerique reste donc celle d'avant, et elle
|
|
||||||
# ment.
|
|
||||||
#
|
#
|
||||||
# Trop etroite (30 minutes), on efface des valeurs JUSTES : la production
|
# - trop ETROITE partout (6 heures) : a 03:20 le panneau PV affichait
|
||||||
# nulle de la nuit est ecrite une fois au coucher du soleil et reste vraie
|
# « No data » alors que la production est nulle et connue — sa derniere
|
||||||
# jusqu'a l'aube.
|
# ecriture datait du coucher du soleil, 370 minutes plus tot.
|
||||||
#
|
#
|
||||||
# Six heures couvre une nuit sans soleil et une borne au repos, tout en
|
# Regle : une entite qui publie un VRAI zero au repos (production PV, borne
|
||||||
# ecartant une lecture vieille de quatorze heures. Au-dela, la case affiche
|
# a l'arret, trackers) supporte une fenetre large, sa derniere valeur restant
|
||||||
# un tiret — « aucune mesure recente », jamais un chiffre invente.
|
# exacte. Une entite qui DISPARAIT au repos exige une fenetre courte — c'est
|
||||||
# Ancien commentaire :
|
# le cas des seules grandeurs du reseau, qui passent donc 6h en argument.
|
||||||
# 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,
|
return flux(refid,
|
||||||
f'from(bucket: "evcs")\n'
|
f'from(bucket: "evcs")\n'
|
||||||
f' |> range(start: -{fenetre})\n'
|
f' |> range(start: -{fenetre})\n'
|
||||||
@@ -804,9 +793,11 @@ systeme = dashboard("evcs-systeme", "Le systeme", (
|
|||||||
frm="now-24h", refresh="30s", variables=[VARIABLE_VUE], panels=[
|
frm="now-24h", refresh="30s", variables=[VARIABLE_VUE], panels=[
|
||||||
|
|
||||||
stat("Reseau", [
|
stat("Reseau", [
|
||||||
flux_dernier("A", "W", "victron_grid_power_l1", "Puissance"),
|
# 6 h et non 24 : ces trois capteurs DISPARAISSENT quand AC-IN s'ouvre,
|
||||||
flux_dernier("B", "V", "airtria_mpii_v1_input_voltage_l1", "Tension"),
|
# laissant derriere eux une valeur qui ne vaut plus rien.
|
||||||
flux_dernier("C", "A", "gx_device_grid_current_l1", "Courant")],
|
flux_dernier("A", "W", "victron_grid_power_l1", "Puissance", fenetre="6h"),
|
||||||
|
flux_dernier("B", "V", "airtria_mpii_v1_input_voltage_l1", "Tension", fenetre="6h"),
|
||||||
|
flux_dernier("C", "A", "gx_device_grid_current_l1", "Courant", fenetre="6h")],
|
||||||
IN, 0, 0, 5, 5,
|
IN, 0, 0, 5, 5,
|
||||||
"Positif : le reseau alimente la maison. Le contacteur EDF est pilote par "
|
"Positif : le reseau alimente la maison. Le contacteur EDF est pilote par "
|
||||||
"le workflow d'hysteresis, pas depuis ici.",
|
"le workflow d'hysteresis, pas depuis ici.",
|
||||||
|
|||||||
Reference in New Issue
Block a user