Une courbe sans ses evenements ne s interprete pas. Le service voit passer les etats toutes les minutes : autant qu il en tire les conclusions plutot que d attendre que quelqu un y pense. Douze etats DISCRETS suivis — contacteur EDF, session reseau de nuit, verrou hysteresis, vehicule branche, strategie, vehicule selectionne, etat BatteryLife, mode de l Auto Charge Manager, reseau necessaire, vigilance orage, production bridee. Les grandeurs continues restent dans mesure et les decisions dans decision : un evenement qui double une autre table est du bruit. Une lecture unavailable n est pas une transition mais une absence de lecture, elle n est pas consignee. Le redemarrage de Home Assistant est detecte sans capteur d uptime, qui n existe pas ici : au redemarrage HA restaure ses helpers et leur pose un last_changed neuf. Le 04/09 a 07:28:49, 352 entites partageaient la seconde du redemarrage dont 183 input_number. Le service prend donc le mode des last_changed des input_number — aucune entite codee en dur, et l estimation se corrige d elle-meme puisque entre deux redemarrages seuls les helpers reellement ecrits s ecartent du mode. Sous dix helpers d accord, la signature est jugee trop faible et rien n est affirme. Un episode d indisponibilite de Home Assistant est journalise AU RETOUR avec sa duree : au moment de la panne, la base n est peut-etre pas joignable non plus. Au premier cycle l etat est enregistre SANS rien journaliser, sinon chaque redemarrage du service produirait douze fausses transitions ; seul le demarrage du service est consigne. Verifie de bout en bout en conditions reelles et non seulement a blanc : essai a blanc avec cycle court, bascule reelle du selecteur de vehicule puis restauration. Amorcage sans fausse transition, cycle sans changement a zero evenement, les deux bascules relevees, etat restaure. Documente aussi le GRANT INSERT sur la seule table evenement pour le role d analyse — insert seulement, ni update ni delete : on ajoute une annotation, jamais on ne reecrit ni n efface les precedentes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ
172 lines
7.1 KiB
Markdown
172 lines
7.1 KiB
Markdown
# Mémoire de mesures EVCS
|
|
|
|
Deux bases sur **10.10.10.22**, décidées le 04/09/2026 : on met les deux en
|
|
service et on décide à l'usage s'il faut garder les deux.
|
|
|
|
| | rôle | source | résolution |
|
|
|---|---|---|---|
|
|
| **PostgreSQL** | ce que n8n **calcule** — bilan, décisions, prévisions publiées | workflows n8n | cadence des workflows |
|
|
| **InfluxDB** | ce que Home Assistant **observe** — tous les états du périmètre énergie | intégration HA | chaque changement d'état |
|
|
|
|
Le raisonnement complet et le comparatif : `HANDOFF.md` §42 et suivantes.
|
|
|
|
## Pourquoi pas sur 10.10.10.17
|
|
|
|
Cette machine porte déjà Home Assistant, n8n, openclaw et open-webui. Une
|
|
mémoire hébergée par la machine dont elle documente les pannes ne survit pas à
|
|
celles-ci. Le volume n'est pas l'argument : les deux Synology ont des téraoctets
|
|
libres.
|
|
|
|
## Mise en service
|
|
|
|
### 1. Les deux bases (à faire sur 10.10.10.22)
|
|
|
|
```sh
|
|
cd /volume2/projects/EVCS/EVCS/deploy/historisation
|
|
bash preparer-env.sh # génère .env avec des secrets aléatoires
|
|
docker compose up -d
|
|
docker compose logs -f
|
|
```
|
|
|
|
### D'où viennent les secrets
|
|
|
|
| secret | origine |
|
|
|---|---|
|
|
| `HA_TOKEN` | **existe déjà** — repris du `.env` à la racine du dépôt |
|
|
| `POSTGRES_PASSWORD` | **créé ici** — la base n'existe pas encore, ce fichier décide de son mot de passe |
|
|
| `DOCKER_INFLUXDB_INIT_PASSWORD` | **créé ici**, idem (InfluxDB exige au moins 8 caractères) |
|
|
| `DOCKER_INFLUXDB_INIT_ADMIN_TOKEN` | **créé ici** — c'est le jeton que Home Assistant utilisera pour écrire |
|
|
|
|
Aucun ne s'obtient auprès de quelqu'un, et aucun ne doit être choisi à la main :
|
|
personne ne les tape jamais — les conteneurs les lisent dans `.env`, et Home
|
|
Assistant lit le jeton dans son propre `secrets.yaml`. Une phrase inventée est
|
|
plus courte et plus devinable qu'elle n'en a l'air ; `openssl rand` ne l'est pas.
|
|
|
|
`preparer-env.sh` refuse d'écraser un `.env` existant : régénérer les mots de
|
|
passe d'une base déjà créée la rendrait inaccessible, puisqu'elle continuerait
|
|
d'attendre les anciens.
|
|
|
|
Vérifications :
|
|
|
|
```sh
|
|
docker compose exec postgres psql -U evcs -d evcs -c '\dt'
|
|
curl -s http://10.10.10.22:8086/health
|
|
docker compose logs historisation --tail 5
|
|
```
|
|
|
|
### Ports : 5433, et pas 5432
|
|
|
|
DSM fait tourner **son propre PostgreSQL sur 5432**, pour ses services internes.
|
|
Notre base est donc publiée sur **5433**. Ce port ne sert qu'à l'analyse depuis
|
|
un poste de travail :
|
|
|
|
```sh
|
|
psql -h 10.10.10.22 -p 5433 -U evcs -d evcs
|
|
```
|
|
|
|
Les trois conteneurs, eux, se parlent par le réseau interne du compose et par
|
|
nom de service (`postgres:5432`) — ni adresse IP en dur, ni dépendance au port
|
|
publié. Vérifier ce qui occupe un port avant de conclure :
|
|
|
|
```sh
|
|
sudo ss -lntp | grep -E '5432|5433|8086'
|
|
```
|
|
|
|
Le schéma (`schema.sql`) est appliqué **une seule fois**, à la création de la
|
|
base. Pour le faire évoluer ensuite, écrire une migration et la passer à `psql` :
|
|
recréer le volume effacerait l'historique, ce qui est précisément ce qu'on
|
|
cherche à ne plus faire.
|
|
|
|
### 2. Brancher Home Assistant sur InfluxDB
|
|
|
|
⚠️ **Demande un redémarrage de Home Assistant**, pendant lequel le contrôleur
|
|
EVCS ne décide plus rien. **Jamais entre 01:24 et 07:24**, ni pendant une charge.
|
|
Le bon créneau est le milieu de matinée.
|
|
|
|
1. mettre le jeton dans `secrets.yaml` sous la clé `influxdb_token` ;
|
|
2. coller le bloc de `ha-influxdb.yaml` dans `configuration.yaml` ;
|
|
3. `homeassistant.check_config`, puis redémarrer.
|
|
|
|
### 3. Alimenter PostgreSQL depuis n8n
|
|
|
|
À faire après l'étape 1 — n8n a besoin que la base existe pour qu'on y crée
|
|
l'identifiant de connexion.
|
|
|
|
## Événements : détectés par le service, annotés à la main
|
|
|
|
La table `evenement` existe parce qu'une courbe sans ses événements ne
|
|
s'interprète pas : « le rendement a changé le 12 novembre » ne veut rien dire
|
|
sans la ligne qui dit qu'un pack a été rebranché ce jour-là.
|
|
|
|
**Le service consigne seul ce qu'il peut constater** — il voit passer les états
|
|
toutes les minutes, autant qu'il en tire les conclusions plutôt que d'attendre
|
|
que quelqu'un y pense :
|
|
|
|
| genre | ce qui est consigné |
|
|
|---|---|
|
|
| `systeme` | démarrage du service, redémarrage de Home Assistant, épisode d'indisponibilité avec sa durée |
|
|
| `reseau` | contacteur EDF, session réseau de nuit, reprise nuit, verrou hystérésis |
|
|
| `vehicule` | véhicule branché ou débranché |
|
|
| `intervention` | changement de stratégie ou de véhicule sélectionné |
|
|
| `ess` | état BatteryLife, mode de l'Auto Charge Manager |
|
|
| `bilan` | réseau nécessaire, vigilance orage, production bridée |
|
|
|
|
On suit des états **discrets** dont chaque changement mérite une ligne. Les
|
|
grandeurs continues sont dans `mesure`, les décisions du contrôleur dans
|
|
`decision` : un événement qui double une autre table est du bruit. Une lecture
|
|
`unavailable` n'est pas une transition mais une absence de lecture — elle n'est
|
|
pas consignée.
|
|
|
|
Le redémarrage de Home Assistant est detecté **sans capteur d'uptime**, qui
|
|
n'existe pas sur cette installation : au redémarrage HA restaure ses helpers et
|
|
leur pose un `last_changed` neuf. Le 04/09, 352 entités partageaient la seconde
|
|
du redémarrage, dont 183 `input_number`. Le service prend donc le **mode** des
|
|
`last_changed` des `input_number` — aucune entité codée en dur, et l'estimation
|
|
se corrige d'elle-même.
|
|
|
|
**Les annotations qu'aucun service ne peut deviner** — « pack rebranché »,
|
|
« correctif déployé » — s'écrivent à la main. Pour cela le rôle d'analyse a
|
|
besoin d'un `INSERT` sur cette seule table :
|
|
|
|
```sh
|
|
sudo docker compose exec -T postgres psql -U evcs -d evcs -c \
|
|
"GRANT INSERT ON evenement TO evcs_lecture;
|
|
GRANT USAGE, SELECT ON SEQUENCE evenement_id_seq TO evcs_lecture;"
|
|
```
|
|
|
|
`INSERT` seulement : ni `UPDATE`, ni `DELETE`. On peut ajouter une annotation,
|
|
jamais réécrire ni effacer les précédentes — y compris les siennes. C'est ce
|
|
qu'on attend d'un journal, et ça laisse les tables de mesure hors de portée.
|
|
|
|
## Accès en lecture pour l'analyse
|
|
|
|
```sh
|
|
sudo bash creer-role-lecture.sh
|
|
```
|
|
|
|
Crée le rôle `evcs_lecture` en **lecture seule** et dépose son mot de passe dans
|
|
le `.env` à la racine du dépôt. Le mot de passe est généré, jamais choisi, et
|
|
**n'est pas affiché** : il va du générateur au fichier, donc rien à recopier et
|
|
rien à exposer dans une capture.
|
|
|
|
Deux raisons de ne pas analyser avec le compte `evcs` : une mémoire dont tout
|
|
l'intérêt est de ne pas être réécrite ne se consulte pas avec un compte qui peut
|
|
écrire, et un mot de passe rangé dans un fichier lisible ne doit pas être celui
|
|
qui gouverne la base.
|
|
|
|
Le script est rejouable : si le rôle existe déjà et que son mot de passe est
|
|
dans le `.env`, il ne fait rien.
|
|
|
|
## Ce qu'aucune des deux ne fait
|
|
|
|
Elles ne remontent pas dans le passé. La mémoire commence le jour où on les
|
|
branche : c'est un argument pour les mettre en service vite, pas pour les
|
|
mettre en service parfaitement.
|
|
|
|
## Sauvegarde
|
|
|
|
Les deux bases vivent dans des volumes Docker nommés, donc **hors du dépôt et
|
|
hors des sauvegardes Home Assistant**. Une mémoire non sauvegardée est une
|
|
mémoire qu'on perdra une fois — voir `HANDOFF.md` §34, qui raconte la même
|
|
histoire pour Home Assistant.
|