La borne annonce "charge" apres deux minutes, on ne la croit plus
Le 07/09 a 14:28:18 la borne a declare le statut 3 apres 2 min 42 s de charge et 0,10 kWh livre. Le controleur l'a cru, a latche day_vehicle_full_idle, et la JEEP est restee immobile deux heures en plein soleil alors qu'elle pouvait charger : elle a repris a 16:30 et tenu. La premiere idee etait de distinguer une vraie fin de charge d'une interruption par la forme de la coupure. La mesure a la seconde l'a tuee : les deux courbes sont superposables (VW 06/09, vraie fin : 1534 -> 550 -> 82 -> 11 -> 0 W ; JEEP 07/09, faux positif : 1626 -> 741 -> 100 -> 13 -> 0 W). Aucun signal electrique instantane ne separe les deux cas. Seule la duree de session les distingue, et le systeme porte deja la grandeur qui dit ce qu'est une charge etablie : min_run_minutes, 29 min en production. Trois formes de "charged", une seule est refusee : energie de session nulle -> vehicule plein a l'arrivee, on latche (P10) energie > 0, session < min_run -> charge INTERROMPUE, on ne latche pas energie > 0, session >= min_run -> charge menee a terme, on latche Aucune constante nouvelle. Pas d'oscillateur : une session interrompue redemarre a energie nulle, donc un second "charged" immediat retombe dans le premier cas et latche. Confirmation independante le meme jour : Uconnect a envoye a 14:29 un courriel "RECHARGE ELECTRIQUE INTERROMPUE" invitant a controler la borne et le connecteur. Le vehicule qualifie donc l'evenement d'interruption. Le releve de la boite montre que c'est chronique depuis au moins decembre 2025 (12 interruptions et 6 echecs entre le 31/12 et le 08/03) : nos automates n'ont pas cree le defaut, ils en ont augmente le cout. Golden 80 -> 84, dont le releve reel et ses deux contrefactuels (duree et energie). Trois mutations tombent chacune sur un jeu different ; celle qui rend le cas "energie nulle" non credible fait echouer trois scenarios existants (P10, Fix D, Fix E). Corrige au passage le HANDOFF du 06/09 : last_session_energy ne decrit pas la derniere session terminee, il suit la session en cours (verifie dans InfluxDB). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GwpFpy2aQ2rJok6tNQSbVj
This commit is contained in:
483
HANDOFF.md
483
HANDOFF.md
@@ -4627,13 +4627,20 @@ de dix minutes) :
|
||||
| 06 01:25-02:44 | 4,24 kWh | 4,200 | 1 % |
|
||||
| 06 13:32-13:42 | 0,34 kWh | 4,200 | **1135 %** |
|
||||
|
||||
⚠️ **La semantique de `last_session_energy` n'etait pas etablie** — le capteur
|
||||
n'etait pas historise, donc aucune serie ne permettait de trancher entre
|
||||
« derniere session terminee » et « session en cours avec reinitialisation
|
||||
tardive ». Deux indices concordants recueillis apres coup : au moment de la
|
||||
reparation il lisait 0,3 kWh et `..._last_session_time` 11 min, soit exactement
|
||||
la session de midi. Il decrit donc la derniere session TERMINEE, et le lire
|
||||
PENDANT une session donne la precedente.
|
||||
⚠️ **CORRECTION du 07/09/2026 — la semantique affirmee ici etait FAUSSE.**
|
||||
J'avais conclu que le capteur decrit la « derniere session TERMINEE » et que le
|
||||
lire pendant une session donne la precedente. La serie InfluxDB, disponible
|
||||
depuis le 06/09, montre l'inverse sans ambiguite : **il suit la session EN
|
||||
COURS**, au pas de 0,1 kWh —
|
||||
`0 (14:25:12) -> 0,1 (14:27:52)`, remise a zero a `16:28:31`, puis
|
||||
`0,1 -> 0,2 -> 0,3 ... -> 1,1` pendant la charge. `_last_session_time` fait de
|
||||
meme en minutes. Le nom du capteur est trompeur.
|
||||
Le correctif applique le 06/09 (compteur cumulatif `total_energy`) reste le bon
|
||||
choix, et le `GREATEST` reste bien le coupable du double comptage : la remise a
|
||||
zero est simplement TARDIVE en debut de session, si bien que le premier
|
||||
echantillon porte encore le total de la session precedente et que l'operateur
|
||||
monotone le verrouille. C'est le mecanisme qui etait mal decrit, pas la
|
||||
conclusion pratique.
|
||||
|
||||
Correctif (`tools/historise-evcs.mjs`) :
|
||||
1. **Le compteur CUMULATIF de la borne** (`..._total_energy`, ~3 780 kWh)
|
||||
@@ -4969,16 +4976,250 @@ ARCHIVE_1_VIDEO.hbk` et **reussit** : l'hote de destination va bien, c'est le
|
||||
dossier qui a disparu.
|
||||
|
||||
Anciennete : dix notifications d'echec retrouvees, **zero reussite**, la plus
|
||||
ancienne du **06/06/2026**. Les photos 2008-2015 de ARCHIVE (10.10.10.50) n'ont
|
||||
donc aucune sauvegarde depuis au moins trois mois, et l'alerte quotidienne
|
||||
partait dans une boite a 17 600 messages non lus.
|
||||
ancienne du **06/06/2026**. ⚠️ Chiffre corrige apres lecture du journal
|
||||
Hyper Backup (voir plus bas) : la derniere sauvegarde reussie date du
|
||||
**24/08/2025**, soit **plus d'un an**, et non trois mois — les courriels
|
||||
conserves ne remontaient simplement pas plus loin. L'alerte quotidienne partait
|
||||
dans une boite a 17 600 messages non lus.
|
||||
|
||||
⚠️ Non corrige : 10.10.10.50 n'accepte pas ma cle SSH, et recreer un partage
|
||||
puis reconfigurer Hyper Backup est une decision qui appartient au proprietaire.
|
||||
Deux voies : recreer un dossier partage `ARCHIVEFAMILLE` sur 10.10.10.22, ou
|
||||
repointer la tache vers un partage existant (`NetBackup` est le nom
|
||||
conventionnel). Dans les deux cas il faudra une sauvegarde COMPLETE au premier
|
||||
passage, le `.hbk` n'existant pas.
|
||||
⚠️ **Acces SSH a 10.10.10.50 (ARCHIVE), etat au 06/09/2026.** Le compte est
|
||||
**`thierry`** (donne par le proprietaire, et confirme par l'entree
|
||||
`synology_dsm` de Home Assistant : hote 10.10.10.50, port DSM **5002**,
|
||||
utilisateur `thierry` — les deux autres NAS utilisent `TMZF5455`). Le port SSH
|
||||
22 repond, mais l'authentification par cle est refusee (`Permission denied
|
||||
(publickey,password)`) pour tous les comptes essayes, alors que le
|
||||
proprietaire dit avoir ajoute la cle. Causes DSM habituelles, dans l'ordre de
|
||||
probabilite : le repertoire personnel est en 0777 (DSM le cree ainsi) et
|
||||
`StrictModes` de sshd le refuse ; le compte n'appartient pas au groupe
|
||||
**administrators**, seul autorise a ouvrir une session SSH sur DSM ; le service
|
||||
**Repertoire personnel** (User Home) est desactive donc `~` n'existe pas.
|
||||
Verification et reparation, a lancer par le proprietaire depuis son terminal :
|
||||
|
||||
```
|
||||
ssh thierry@10.10.10.50 'mkdir -p ~/.ssh; \
|
||||
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHWfzf2109Rsv9jt2P592NgcK+7qR5teFULPgQNleoHj tmzf5455@yd-5CD8345759" >> ~/.ssh/authorized_keys; \
|
||||
chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys; chmod 755 "$HOME"; \
|
||||
id; ls -ld "$HOME" ~/.ssh ~/.ssh/authorized_keys'
|
||||
```
|
||||
|
||||
Le `chmod 755` sur le repertoire personnel est le point le plus souvent oublie :
|
||||
sans lui sshd ignore silencieusement le fichier de cles, ce qui explique
|
||||
exactement le symptome « j'ai ajoute la cle et ca ne marche pas ».
|
||||
|
||||
### La tache « Synology NAS 1 », lue dans sa configuration (06/09/2026)
|
||||
|
||||
Acces SSH a 10.10.10.50 obtenu (voir ci-dessus), `/usr/syno/etc/synobackup.conf`
|
||||
lu directement. Les trois taches de ce NAS :
|
||||
|
||||
| tache | source (sur .50) | destination (sur .22) | depot | etat |
|
||||
|---|---|---|---|---|
|
||||
| WEB petit sino vers gros | `/web` | partage `web` | `ARCHIVE_2.hbk` | depot fige au **25/12/2019** |
|
||||
| **Synology NAS 1** | **`/photo`, 399 Go** | partage **`ARCHIVEFAMILLE`** | `ARCHIVE_1_PHOTOS_2008_2015.hbk` | **echoue depuis ≥ 06/06/2026** |
|
||||
| Synology NAS 2 | `/video` | partage `video` | `ARCHIVE_1_VIDEO.hbk` | reussit, depot du jour |
|
||||
|
||||
Details de la tache en echec : creee le **26/08/2018**, compte `TMZF5455`,
|
||||
port **6281**, `trans_type=image_remote`, rotation activee, chiffrement
|
||||
desactive.
|
||||
|
||||
**Le partage `ARCHIVEFAMILLE` n'existe pas sur 10.10.10.22** — verifie a la
|
||||
racine des deux volumes. Et **aucun depot de photos n'existe nulle part** sur
|
||||
ce NAS : `find /volume* -name "*.hbk"` ne rend que les trois depots ci-dessus,
|
||||
dont aucun n'est celui des photos. La duree d'execution nulle relevee dans le
|
||||
courriel d'echec s'explique entierement : Hyper Backup ne trouve pas le partage
|
||||
de destination et s'arrete avant d'ouvrir le depot.
|
||||
|
||||
**Correction retenue : recreer un dossier partage nomme exactement
|
||||
`ARCHIVEFAMILLE` sur 10.10.10.22, sur `/volume2`.** La tache existante repart
|
||||
alors sans etre touchee — c'est la voie la moins invasive, DSM 7 ne permettant
|
||||
pas de changer la destination d'une tache Hyper Backup existante (il faudrait
|
||||
la recreer, et perdre son historique de versions).
|
||||
|
||||
Place : `/volume2` a **9,8 To libres** sur 11, `/volume1` seulement 850 Go sur
|
||||
1,8 To. Les 399 Go du premier passage tiennent dans les deux, mais `/volume2`
|
||||
laisse de la marge pour la rotation des versions.
|
||||
|
||||
⚠️ Le premier passage sera une sauvegarde **COMPLETE** de 399 Go, le depot
|
||||
n'existant plus. Prevoir plusieurs heures.
|
||||
|
||||
### CORRECTION — recreer le partage etait necessaire, PAS suffisant
|
||||
|
||||
`sudo` libre obtenu sur 10.10.10.50 (procedure ci-dessous), donc
|
||||
`/var/log/synolog/synobackup.log` enfin lisible. Il corrige deux choses que
|
||||
j'avais affirmees.
|
||||
|
||||
**1. L'echec ne date pas de trois mois mais de PLUS D'UN AN.** Les courriels
|
||||
d'alerte ne remontaient qu'a juin 2026 ; le journal, lui, donne :
|
||||
|
||||
| date | evenement |
|
||||
|---|---|
|
||||
| **24/08/2025 03:06** | **derniere sauvegarde REUSSIE** — 112 818 fichiers |
|
||||
| 06/09/2025 | premier echec, « The network connection is closed. » |
|
||||
| 01/03/2026 | dernier echec de ce type |
|
||||
| **07/03/2026** | l'erreur change : « The backup destination does not exist. [Path: ARCHIVEFAMILLE] » |
|
||||
|
||||
**109 echecs enregistres.** L'enchainement se lit tout seul : la connexion a
|
||||
casse d'abord (septembre 2025), et le partage `ARCHIVEFAMILLE` a ete supprime
|
||||
plus tard, vers debut mars 2026 — ce qui repond a la question ouverte du
|
||||
paragraphe suivant.
|
||||
|
||||
**2. Recreer le partage ne suffit pas a faire repartir la tache.** Apres
|
||||
creation du partage, l'erreur a bien change — preuve que la destination est
|
||||
desormais jointe et authentifiee :
|
||||
|
||||
```
|
||||
16:15:52 Failed to start backup task. (The destination file does not exist.)
|
||||
[Path: /volume2/ARCHIVEFAMILLE/ARCHIVE_1_PHOTOS_2008_2015.hbk/Config/version_info.db not exist]
|
||||
```
|
||||
|
||||
Une tache Hyper Backup existante **exige de retrouver son depot** et refuse de
|
||||
le recreer : elle cherche `<depot>.hbk/Config/version_info.db`. Le depot ayant
|
||||
disparu avec le partage, la tache est **irrecuperable en l'etat**. Mon
|
||||
affirmation « la tache existante repart telle quelle » etait fausse.
|
||||
|
||||
**Marche a suivre reelle** : creer une NOUVELLE tache dans Hyper Backup sur
|
||||
10.10.10.50 — Sauvegarde de donnees → serveur Synology distant → `10.10.10.22`,
|
||||
compte `TMZF5455`, partage `ARCHIVEFAMILLE`, depot
|
||||
`ARCHIVE_1_PHOTOS_2008_2015`, source = dossier partage `photo` (399 Go) — puis
|
||||
supprimer l'ancienne tache « Synology NAS 1 ». La creation d'une tache Hyper
|
||||
Backup n'a pas d'equivalent en ligne de commande : elle se fait dans DSM.
|
||||
L'historique de versions est perdu de toute facon, le depot n'existant plus.
|
||||
|
||||
⚠️ **Piege a retenir** : `synobackup --backup <id> --type image` rend
|
||||
**code 0 et une sortie vide meme quand il echoue**, en root comme en simple
|
||||
utilisateur. Le seul retour exploitable est
|
||||
`/var/log/synolog/synobackup.log`.
|
||||
|
||||
### Seconde tache cassee, decouverte au passage : « WEB petit sino vers gros »
|
||||
|
||||
Elle echoue **tous les jours a 03:00**, avec « The network connection is
|
||||
closed. » — et `enable_notify=true`, donc elle alerte elle aussi. Configuration :
|
||||
source `/web` du .50, destination `10.10.10.22` partage `web`, depot
|
||||
`ARCHIVE_2.hbk`, **port 873** (rsync en clair) la ou les deux autres taches
|
||||
utilisent 6281.
|
||||
|
||||
Ce n'est PAS un probleme de port : depuis le .50, **873 et 6281 repondent tous
|
||||
les deux**, et sur le .22 `netstat` montre `rsync` en ecoute sur 873 et
|
||||
`img_backupd` sur 6281. Le depot `/volume1/web/ARCHIVE_2.hbk` est fige au
|
||||
**25/12/2019**. Cause a instruire separement (authentification rsync, ou depot
|
||||
inutilisable).
|
||||
|
||||
### RESOLU le 06/09/2026 a 22:53 — nouvelle tache, sauvegarde en cours
|
||||
|
||||
Journal Hyper Backup du .50 :
|
||||
|
||||
```
|
||||
18:54:20 thierry: Backup task [Synology NAS 1] was removed.
|
||||
20:59:51 thierry: Backup task [WEB petit sino vers gros] was removed.
|
||||
22:53:04 thierry: Setting of backup task [Synology NAS 1 ARCHIVE FAMILLE] was created
|
||||
to backup to [TMZF5455@10.10.10.22::ARCHIVEFAMILLE/ARCHIVE_1_PHOTOS_2008_2015.hbk]
|
||||
22:53:32 SYSTEM: [Synology NAS 1 ARCHIVE FAMILLE] Backup task started.
|
||||
```
|
||||
|
||||
Verifie cote destination : le depot
|
||||
`/volume2/ARCHIVEFAMILLE/ARCHIVE_1_PHOTOS_2008_2015.hbk` existe, appartient a
|
||||
`TMZF5455`, et **grossit** (395 Mo puis 604 Mo a une minute d'intervalle).
|
||||
Aucune erreur depuis le demarrage. La seconde tache cassee
|
||||
(« WEB petit sino vers gros ») a ete supprimee plutot que reparee — decision du
|
||||
proprietaire ; le depot `/volume1/web/ARCHIVE_2.hbk` de 2019 reste sur le .22
|
||||
et peut etre efface si `/web` n'a plus de valeur.
|
||||
|
||||
Ne restent donc que deux taches sur le .50 : `task_3` (« Synology NAS 2 »,
|
||||
`/video` → partage `video`) et `task_4` (la nouvelle).
|
||||
|
||||
⚠️ **La nouvelle tache sauvegarde `["/photo","/video"]`**, alors que l'ancienne
|
||||
ne prenait que `/photo`. `/video` est deja sauvegarde par « Synology NAS 2 »
|
||||
dans un depot de **455 Go** sur `/volume1/video` du .22. Le premier passage
|
||||
copiera donc ~399 Go de photos **plus ~455 Go de videos en double**, soit
|
||||
~854 Go. L'espace ne manque pas (9,8 To libres sur `/volume2`) mais c'est
|
||||
plusieurs heures et un demi-tera pour rien si l'inclusion de `/video` etait une
|
||||
case cochee par erreur. A trancher par le proprietaire — se corrige dans les
|
||||
parametres de la tache.
|
||||
|
||||
### Partage recree le 06/09/2026 a 16:14
|
||||
|
||||
`/volume2/ARCHIVEFAMILLE` existe. Verifie, cote destination :
|
||||
- chemin et type conformes (`synoshare --get`) ;
|
||||
- ACL **identique a celle du partage `video` dont la tache reussit** :
|
||||
`group:administrators:allow:rwxpdDaARWc--` — et le compte de la tache,
|
||||
`TMZF5455`, est administrateur. Les droits ne bloqueront pas ;
|
||||
- port **6281 joignable depuis 10.10.10.50** (teste) ;
|
||||
- 9,8 To libres sur `/volume2`.
|
||||
|
||||
⚠️ **Le lancement en ligne de commande ne fonctionne PAS depuis mon acces.**
|
||||
`/usr/syno/bin/synobackup --backup 2 --type image` rend **code 0 et une sortie
|
||||
vide, sans rien demarrer** : aucun processus, `--is-backup-restore-running`
|
||||
repond « pas en cours », et le depot n'apparait pas cote destination. La
|
||||
commande exige root et echoue silencieusement — piege a connaitre, le code de
|
||||
retour ne signale rien.
|
||||
|
||||
⚠️ **`sudo` demande un mot de passe sur 10.10.10.50**, contrairement a
|
||||
10.10.10.22 ou il est libre. Consequence : ni le lancement de la tache ni la
|
||||
lecture de `/var/log/synolog/` et `/var/log/messages` ne me sont accessibles
|
||||
sur ce NAS.
|
||||
|
||||
Lancement a faire par le proprietaire : **Hyper Backup → tache « Synology
|
||||
NAS 1 » → Sauvegarder maintenant**, qui donne en prime la progression des
|
||||
399 Go.
|
||||
|
||||
### Pourquoi `sudo` est libre sur 10.10.10.22 et pas sur 10.10.10.50
|
||||
|
||||
Les deux NAS ne tournent pas la meme version : **10.10.10.22 est en DSM 7.3.2**,
|
||||
**10.10.10.50 en DSM 6.2.4** (fin de support Synology). Sur le .22,
|
||||
`/etc/sudoers` porte en ligne 11 `%administrators ALL=NOPASSWD: ALL`, ce que
|
||||
DSM 6 ne pose pas.
|
||||
|
||||
⚠️ **`visudo` n'existe nulle part sur 10.10.10.50** (verifie par `find`), alors
|
||||
que `sudo` lui-meme est en 1.9.5p2. Il n'y a donc **aucune validation
|
||||
syntaxique possible avant d'appliquer**, et une erreur dans `sudoers` verrouille
|
||||
`sudo` entierement. Garder une session root ouverte pendant la manipulation
|
||||
n'est pas une precaution de style, c'est le seul filet.
|
||||
|
||||
Procedure (a lancer par le proprietaire, DSM 6.2.4) :
|
||||
|
||||
```
|
||||
# terminal 1 — NE PAS FERMER avant la validation
|
||||
ssh thierry@10.10.10.50
|
||||
sudo -i # mot de passe DSM
|
||||
|
||||
cp -a /etc/sudoers /etc/sudoers.bak.$(date +%Y%m%d-%H%M%S)
|
||||
grep -c '^#includedir /etc/sudoers.d' /etc/sudoers
|
||||
```
|
||||
|
||||
Si la reponse est `1` (repertoire inclus, a preferer : le fichier survit aux
|
||||
mises a jour DSM) :
|
||||
|
||||
```
|
||||
echo 'thierry ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/thierry-nopasswd
|
||||
chown root:root /etc/sudoers.d/thierry-nopasswd
|
||||
chmod 0440 /etc/sudoers.d/thierry-nopasswd
|
||||
```
|
||||
|
||||
Si la reponse est `0` :
|
||||
|
||||
```
|
||||
echo 'thierry ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
|
||||
```
|
||||
|
||||
Validation depuis un **second** terminal, la session root toujours ouverte :
|
||||
|
||||
```
|
||||
ssh thierry@10.10.10.50 'sudo -n id' # doit rendre uid=0(root)
|
||||
```
|
||||
|
||||
En cas d'erreur de syntaxe, revenir au terminal 1 (toujours root) :
|
||||
`rm -f /etc/sudoers.d/thierry-nopasswd` et/ou restaurer la sauvegarde
|
||||
`/etc/sudoers.bak.*`.
|
||||
|
||||
Portee retenue : la regle ne vise que `thierry`, pas tout le groupe
|
||||
`administrators` — plus etroit que ce qui est en place sur le .22. Contrepartie
|
||||
assumee, identique a celle deja acceptee sur le .22 : toute cle SSH installee
|
||||
pour ce compte devient root sans obstacle.
|
||||
|
||||
⚠️ Question ouverte : pourquoi ce partage a disparu de 10.10.10.22. Il existait
|
||||
forcement en 2018 puisque la tache a tourne. A rapprocher d'une eventuelle
|
||||
reorganisation des volumes — `/volume2/video_1/ARCHIVE_1_VIDEO.hbk` (fige au
|
||||
05/03/2026) est un depot double de celui de `/volume1/video`, ce qui ressemble
|
||||
a une migration de volume laissee en plan.
|
||||
|
||||
### Les annotations Grafana etaient devenues illisibles
|
||||
Sept jours d'historique produisaient une foret de pointilles orange masquant les
|
||||
@@ -5028,3 +5269,213 @@ tous a sa charge. Sur un parc de quatre modules (7,1 kWh utiles de 100 a 22 %),
|
||||
|
||||
---
|
||||
*Document mis a jour le : 06/09/2026 (~13:10) — relachement du contacteur sur une duree gagee sur le bilan, golden-hysteresis 20/20, deploye*
|
||||
|
||||
|
||||
## 58. Session du 07/09/2026 — La borne annonce « charge terminee » apres 0,10 kWh
|
||||
|
||||
### Symptome
|
||||
JEEP branchee a 14:26, immobile jusqu'a 16:29 en plein soleil. Le controleur
|
||||
affichait `day_vehicle_full_idle` (P10, « vehicule plein en journee »), source
|
||||
`Bloque`.
|
||||
|
||||
### Ce que la borne a reellement declare
|
||||
`sensor.evcs_hq2239dnt7p_status`, entree dans l'historisation InfluxDB la veille
|
||||
— c'est ce capteur qui tranche, et il n'etait pas lisible avant le 06/09 :
|
||||
|
||||
```
|
||||
14:25:12 waiting_for_start
|
||||
14:25:32 start_charging
|
||||
14:25:36 charging -> 1239 puis 1577 W, 6 -> 8 A
|
||||
14:28:18 charged <-- apres 2 min 42 s et 0,10 kWh
|
||||
14:28:30 waiting_for_start
|
||||
(deux heures d'immobilite : l'etat collant tient, comme concu)
|
||||
16:29:02 disconnected <-- cable branche, liaison perdue
|
||||
16:29:06 waiting_for_start
|
||||
16:29:31 start_charging
|
||||
16:29:35 charged <-- QUATRE SECONDES apres le demarrage
|
||||
16:29:55 disconnected
|
||||
16:29:59 waiting_for_start
|
||||
16:30:03 start_charging
|
||||
16:30:07 charging -> tient, 1947 W a 10 A, en montee
|
||||
```
|
||||
|
||||
**Le controleur n'a rien bloque : il a cru la borne.** Fix D (§17) et P10 (§22)
|
||||
traitent `status == charged` + puissance nulle comme une fin de charge, et
|
||||
latchent un etat collant jusqu'au debranchement. C'est exactement ce qui a ete
|
||||
demande. Le signal d'entree, lui, etait faux.
|
||||
|
||||
Un `charged` quatre secondes apres `start_charging` ne peut pas etre vrai. Et
|
||||
les deux `disconnected` cable branche designent une rupture du signal pilote —
|
||||
**piste materielle a instruire en premier** : connecteur cote vehicule et cote
|
||||
borne, verrouillage de la prise, cable. Aucune alarme n'est publiee par la
|
||||
borne, aucune alarme VE.Bus active.
|
||||
|
||||
### Ce qui a leve le collant : PAS le selecteur de vehicule
|
||||
Le proprietaire a change `input_select.victron_evcs_vehicle` de VW a JEEP a
|
||||
16:28:32, et la charge est repartie 90 s plus tard. **Coincidence, pas cause** :
|
||||
`dayVehicleFullIdle` exige `parsed.evcsVehicleConnected`, et c'est le
|
||||
`disconnected` de 16:29:02 qui a fait tomber cette condition. Le rythme des
|
||||
transitions qui suivent (4 s, 20 s) exclut une manipulation humaine.
|
||||
⚠️ Ne pas en conclure que corriger le selecteur debloque une charge.
|
||||
|
||||
### Comparaison avec la veille (VW, 06/09) — le phenomene n'est pas tout neuf
|
||||
La VW a subi deux interruptions (`waiting_for_start` a 15:20:35 et 15:52:35)
|
||||
mais elle est repartie **seule en une trentaine de secondes** a chaque fois, et
|
||||
a livre 4,30 kWh ; son `charged` de 16:06:42 est arrive apres 1 h 32 de charge,
|
||||
donc legitime. Les interruptions existaient donc deja ; ce qui est nouveau
|
||||
aujourd'hui, c'est le `charged` premature qui verrouille le systeme derriere.
|
||||
|
||||
### Defaut de conception a corriger (PROPOSE, non deploye)
|
||||
Le controleur traite identiquement trois situations que l'energie de session
|
||||
separe sans ambiguite :
|
||||
|
||||
| situation | energie livree | duree | verdict |
|
||||
|---|---:|---:|---|
|
||||
| vehicule plein rebranche | 0 kWh | — | `charged` legitime, collant justifie |
|
||||
| **interruption anormale** | **0,10 kWh** | **2-4 min** | **doit etre reessaye** |
|
||||
| vraie fin de charge | 4,30 kWh | 1 h 32 | `charged` legitime |
|
||||
|
||||
La distinction ne demande aucune constante inventee : la borne publie
|
||||
`sensor.evcs_hq2239dnt7p_last_session_energy` et `_last_session_time`, toutes
|
||||
deux historisees depuis le 06/09. Un `charged` qui suit une charge REELLE mais
|
||||
dont la session n'a livre qu'une energie derisoire n'est pas une fin de charge,
|
||||
c'est une interruption — et le collant ne doit pas se poser.
|
||||
⚠️ Le cas « 0 kWh livre » doit rester collant : c'est le cas P10 d'origine
|
||||
(VW pleine rebranchee, 09/08).
|
||||
|
||||
### Cout de l'episode
|
||||
Deux heures d'immobilite (14:28 → 16:29) un jour a 2,5 kW de production
|
||||
disponible et batterie a 96-97 %, donc sur de la ressource qui etait de toute
|
||||
facon refusee. Le cout n'est pas en energie achetee mais en energie solaire
|
||||
non captee par le vehicule.
|
||||
|
||||
---
|
||||
*Document mis a jour le : 07/09/2026 — `charged` premature de la borne, piste materielle a instruire, correctif controleur propose*
|
||||
|
||||
|
||||
## 59. Session du 07/09/2026 — Fix H : un statut « charged » doit etre credible
|
||||
|
||||
### La mesure qui a decide de la conception
|
||||
Premiere idee : distinguer une vraie fin de charge d'une interruption par la
|
||||
FORME de la coupure — une batterie qui se remplit decroit, une interruption
|
||||
coupe net. **Mesure a la seconde des deux cas, elle est morte sur place :**
|
||||
|
||||
| | T-4 s | T-3 s | T-2 s | T-1 s | T |
|
||||
|---|---:|---:|---:|---:|---:|
|
||||
| VW 06/09 16:06:42, **vraie fin** (4,30 kWh, 1 h 32) | 1534 W | 550 | 82 | 11 | 0 |
|
||||
| JEEP 07/09 14:28:18, **faux positif** (0,10 kWh, 2 min 42 s) | 1626 W | 741 | 100 | 13 | 0 |
|
||||
|
||||
Les deux courbes sont superposables. **Aucun signal electrique instantane ne
|
||||
separe les deux cas** — ni la puissance, ni sa pente. Ne pas reessayer cette
|
||||
piste.
|
||||
|
||||
Ce qui les separe est la DUREE de la session. Et le systeme porte deja la
|
||||
grandeur qui dit ce qu'est une charge etablie : **`min_run_minutes`, qui vaut
|
||||
29 minutes en production** (le `3` qu'on lit dans `INPUT_PARSE.js` n'est que le
|
||||
repli du code — meme piege qu'au 24/08 avec les seuils 22/35 de l'hysteresis).
|
||||
|
||||
### Le correctif
|
||||
Dans `WINDOWS_SOURCEV2.js`, `evcsStatusCharged` gagne une condition de
|
||||
credibilite. Trois formes de « charged », dont une seule est refusee :
|
||||
|
||||
| energie livree par la session | duree | verdict |
|
||||
|---|---|---|
|
||||
| **nulle** | — | vehicule plein a l'arrivee → collant (cas P10 d'origine) |
|
||||
| > 0 et session **< `min_run_minutes`** | courte | **charge INTERROMPUE → on ne latche pas** |
|
||||
| > 0 et session **>= `min_run_minutes`** | longue | charge menee a terme → collant |
|
||||
|
||||
Aucune constante nouvelle : `min_run_minutes` existe, et l'energie de session
|
||||
est publiee par la borne.
|
||||
|
||||
**Pas d'oscillateur** : une session interrompue redemarre a energie nulle, donc
|
||||
un second « charged » immediat retombe dans le premier cas et latche. La
|
||||
convergence est garantie en une tentative supplementaire.
|
||||
|
||||
### Chaine technique
|
||||
- `HA_SNAPSHOT_TEMPLATE` : `+evcs_session_energy_kwh` ←
|
||||
`sensor.evcs_hq2239dnt7p_last_session_energy` (gabarit re-rendu contre HA :
|
||||
**198 champs, JSON valide, aucun null**) ;
|
||||
- `INPUT_PARSE` : `parsed.evcsSessionEnergyKwh` ;
|
||||
- `WINDOWS_SOURCEV2` : `chargedSessionEnergyKwh`, `chargedSessionEstablished`,
|
||||
`chargedCredible`, tous trois exportes pour la tracabilite.
|
||||
|
||||
**Repli** : capteur absent → energie 0 → credible → comportement d'avant. C'est
|
||||
pourquoi les 80 scenarios existants sont inchanges (leur fixture ne porte pas
|
||||
le champ).
|
||||
|
||||
### Golden 80 → 84
|
||||
`charged-interrompu-ne-latche-pas` (le releve du 07/09 : 2 min 42 s, 0,10 kWh →
|
||||
la charge CONTINUE a 7 A au lieu de se bloquer) · `charged-session-etablie-latche`
|
||||
(contrefactuel de duree : 1 h 32, 4,30 kWh → collant) ·
|
||||
`charged-energie-nulle-latche` (contrefactuel d'energie : 0 kWh → collant, cas
|
||||
P10 preserve) · `night-charged-interrompu-ne-latche-pas` (la meme garde en
|
||||
fenetre HC : la charge reseau continue).
|
||||
|
||||
Preuve par mutation, trois directions, **chacune tombant sur un jeu different** :
|
||||
garde retiree → les 2 scenarios « interrompu » ; cas energie nulle rendu non
|
||||
credible → 4 scenarios dont **3 EXISTANTS** (`day-vw-pleine-statut3`,
|
||||
`night-vw-statut-charged`, `night-charged-en-session-active`) ; duree ignoree →
|
||||
le scenario « session etablie ». Restauration → 84/84.
|
||||
|
||||
### Confirmation independante par le constructeur (Gmail, 07/09)
|
||||
|
||||
Le vehicule dispose de sa propre telematique (Uconnect) qui envoie un courriel
|
||||
depuis `uconnectservices@jeep.com`. Le 07/09 a **14:29**, soit **une minute
|
||||
apres** le `charged` de la borne de 14:28:18 :
|
||||
|
||||
> « RECHARGE ELECTRIQUE INTERROMPUE — Nous avons detecte que la recharge de
|
||||
> votre Jeep a ete **interrompue**. Nous vous invitons a controler votre borne
|
||||
> et le connecteur de recharge, et a reessayer. »
|
||||
|
||||
**Le vehicule qualifie l'evenement d'INTERRUPTION, pas de fin de charge.** Fix H
|
||||
traite donc le bon probleme, et la piste materielle est celle que le
|
||||
constructeur designe lui-meme (« votre borne et le connecteur »).
|
||||
|
||||
⚠️ **Jeep distingue QUATRE evenements la ou la borne n'a qu'un statut** :
|
||||
« RECHARGE ELECTRIQUE COMMENCEE » · « VOUS VOILA CHARGE A BLOC » (fin normale) ·
|
||||
« RECHARGE ELECTRIQUE INTERROMPUE » · « RECHARGE INFRUCTUEUSE » (echec au
|
||||
demarrage). C'est exactement l'information qui manque au controleur.
|
||||
|
||||
### Le defaut est CHRONIQUE, et anterieur a tout notre outillage
|
||||
Releve dans la boite de reception, decembre 2025 → mars 2026 : au moins
|
||||
**12 « interrompue »** (31/12, 04/01 ×2, 05/01, 14/01, 17/01, 23/01, 29/01,
|
||||
15/02, 20/02, 08/03 ×2) et **6 « infructueuse »** (17/01, 23/01, 27/01, 28/01,
|
||||
23/02, 08/03). Deux journees typiques :
|
||||
|
||||
| 08/03/2026 | 23/01/2026 |
|
||||
|---|---|
|
||||
| 08:24 infructueuse | 12:53 commencee |
|
||||
| 11:44 commencee | 13:15 infructueuse |
|
||||
| **11:59 interrompue (15 min)** | 14:01 commencee |
|
||||
| 15:12 commencee | **15:34 interrompue** |
|
||||
| 17:11 interrompue | |
|
||||
|
||||
Ce n'est donc pas une consequence de nos correctifs ni de la borne en
|
||||
firmware 2.08 : le vehicule signale des interruptions depuis au moins neuf
|
||||
mois. Ce que nos automates ont change, c'est le COUT d'une interruption (deux
|
||||
heures de blocage au lieu d'une reprise).
|
||||
|
||||
⚠️ **Aucun courriel Jeep entre le 18/03/2026 et le 07/09/2026** dans l'index de
|
||||
recherche, alors que l'index couvre bien les jours recents (le rapport de nuit
|
||||
de 06:47 y figure). Trois lectures possibles, non tranchees : notifications
|
||||
Uconnect desactivees puis reactivees, JEEP non chargee a la maison sur cette
|
||||
periode, ou trou d'indexation. A verifier avec le proprietaire.
|
||||
|
||||
### Piste : faire du courriel Jeep un signal du systeme (PROPOSE)
|
||||
Ces courriels arrivent ~1 minute apres l'evenement et portent la qualification
|
||||
que la borne ne sait pas donner. Chaine possible : filtre Gmail → transfert vers
|
||||
un webhook n8n → `input_text.victron_evcs_jeep_last_event` → lu par
|
||||
`WINDOWS_SOURCEV2` (« interrompue » ⇒ ne jamais latcher le collant).
|
||||
⚠️ **Signal d'appoint, jamais de securite** : latence de deux cycles, dependance
|
||||
a Internet (or les coupures d'orage sont frequentes ici) et a un service cloud
|
||||
tiers. Fix H doit rester la garde principale, qui elle est locale.
|
||||
|
||||
### Ce que le correctif ne traite PAS
|
||||
La cause premiere reste materielle et n'est pas instruite : deux
|
||||
`disconnected` cable branche le 07/09 a 16:29:02 et 16:29:55, et un « charged »
|
||||
quatre secondes apres `start_charging`. Fix H **borne le cout** d'un signal
|
||||
faux ; il ne repare pas le signal. Connecteur, verrouillage et cable restent a
|
||||
inspecter.
|
||||
|
||||
---
|
||||
*Document mis a jour le : 07/09/2026 — Fix H prepare (golden 84/84, gabarit valide contre HA), en attente de validation avant PUT*
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"evcs_current_a": states("sensor.victron_evcs_current"),
|
||||
"evcs_ac_power_w": states("sensor.victron_evcs_ac_power"),
|
||||
"evcs_charging_time": states("sensor.victron_evcs_charging_time"),
|
||||
"evcs_session_energy_kwh": states("sensor.evcs_hq2239dnt7p_last_session_energy"),
|
||||
"evcs_charging_switch": states("switch.victron_evcs_charging"),
|
||||
"evcs_auto_start_switch": states("switch.victron_evcs_auto_start"),
|
||||
|
||||
|
||||
@@ -328,6 +328,11 @@ const parsed = {
|
||||
|
||||
evcsAcPowerW: Math.max(0, num(input.evcs_ac_power_w, 0)),
|
||||
evcsChargingTimeSec: parseChargingTimeToSec(input.evcs_charging_time),
|
||||
// Energie deja livree par la session EN COURS (kWh). Le capteur de la borne
|
||||
// s'appelle "last_session_energy" mais il suit la session courante et repart
|
||||
// de zero a chaque nouvelle connexion (verifie le 07/09/2026 : 0 -> 0,1 -> 0,2
|
||||
// ... pendant la charge). Sert a juger la credibilite d'un statut "charged".
|
||||
evcsSessionEnergyKwh: Math.max(0, num(input.evcs_session_energy_kwh, 0)),
|
||||
evcsChargingSwitchOn: low(input.evcs_charging_switch || 'off') === 'on',
|
||||
evcsAutoStartSwitchOn: low(input.evcs_auto_start_switch || 'off') === 'on',
|
||||
|
||||
|
||||
@@ -430,10 +430,36 @@ const sessionFresh =
|
||||
// collant écrit par DECISION pendant la session (voir Fix E DECISION).
|
||||
// P11 : sur une session neuve, on ignore aussi un éventuel statut 3 résiduel
|
||||
// (le temps que la borne renégocie avec le nouveau véhicule).
|
||||
// Fix H (07/09/2026) : un statut "charged" n'est pas cru sur parole.
|
||||
// La borne l'a annonce le 07/09 a 14:28:18 apres 2 min 42 s de charge et
|
||||
// 0,10 kWh livre, ce qui a latche `day_vehicle_full_idle` pour deux heures
|
||||
// alors que le vehicule pouvait charger (il a repris a 16:30 et tenu).
|
||||
//
|
||||
// Aucun signal ELECTRIQUE instantane ne separe une vraie fin de charge d'une
|
||||
// interruption : mesure a la seconde des deux coupures, elles sont
|
||||
// superposables (VW 06/09, vraie fin : 1534 -> 550 -> 82 -> 11 -> 0 W ;
|
||||
// JEEP 07/09, faux positif : 1626 -> 741 -> 100 -> 13 -> 0 W). Seule la
|
||||
// DUREE de la session les distingue, et le systeme porte deja la grandeur qui
|
||||
// dit ce qu'est une charge etablie : min_run_minutes (29 min en production).
|
||||
//
|
||||
// Deux formes de "charged" sont credibles, et une seule ne l'est pas :
|
||||
// energie de session nulle -> le vehicule etait plein en arrivant (P10)
|
||||
// session >= min_run_minutes -> charge menee a son terme
|
||||
// entre les deux -> charge INTERROMPUE : on ne latche pas
|
||||
// Convergence : une session interrompue redemarre a energie nulle, donc un
|
||||
// second "charged" immediat retombe dans le premier cas et latche.
|
||||
const chargedSessionEnergyKwh = Math.max(0, parsed.evcsSessionEnergyKwh || 0);
|
||||
const chargedSessionEstablished =
|
||||
Number.isFinite(parsed.evcsChargingTimeSec) &&
|
||||
parsed.evcsChargingTimeSec >= params.minRunMinutes * 60;
|
||||
const chargedCredible =
|
||||
chargedSessionEnergyKwh <= 0 || chargedSessionEstablished;
|
||||
|
||||
const evcsStatusCharged =
|
||||
!sessionFresh &&
|
||||
Number.parseFloat(parsed.evcsStatusRaw) === 3 &&
|
||||
Math.max(0, parsed.evcsAcPowerW || 0) <= 300;
|
||||
Math.max(0, parsed.evcsAcPowerW || 0) <= 300 &&
|
||||
chargedCredible;
|
||||
|
||||
const vehicleChargeCompleted =
|
||||
nightSessionActive &&
|
||||
@@ -1043,6 +1069,9 @@ return [{
|
||||
|
||||
// P11
|
||||
sessionFresh,
|
||||
chargedSessionEnergyKwh,
|
||||
chargedSessionEstablished,
|
||||
chargedCredible,
|
||||
}
|
||||
}
|
||||
}];
|
||||
|
||||
@@ -317,6 +317,139 @@ export const scenarios = [
|
||||
// Incident 09/08 09:49 : VW pleine, le surplus solaire retentait une charge
|
||||
// toutes les ~15 min (statut "Charged", 0 W) → usure relais. Désormais
|
||||
// collant jusqu'au débranchement, avec héritage des états done de la nuit.
|
||||
// ===== Fix H (07/09/2026) : credibilite du statut "charged" =====
|
||||
// Releve reel : la borne a annonce "charged" a 14:28:18 apres 2 min 42 s de
|
||||
// charge et 0,10 kWh livre, ce qui a bloque le vehicule deux heures. Les deux
|
||||
// coupures (vraie fin de charge et interruption) sont ELECTRIQUEMENT
|
||||
// identiques, mesurees a la seconde : seule la duree de session les separe.
|
||||
{
|
||||
id: 'charged-interrompu-ne-latche-pas',
|
||||
label: 'Statut 3 apres 2 min 42 s et 0,10 kWh livre (releve 07/09) -> interruption, PAS de collant',
|
||||
time: AFTERNOON,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
soc_percent: '96', pv_power_w: '2600', pv_power_10m_avg_w: '2500',
|
||||
pv_trend_w: '0', battery_current_a: '2',
|
||||
house_ac_power_w: '2100', vebus_ac_out_l1_power_w: '2100',
|
||||
evcs_charging_switch: 'on',
|
||||
charge_permission_now: 'on',
|
||||
control_latch: 'on',
|
||||
evcs_current_a: '0',
|
||||
evcs_ac_power_w: '0',
|
||||
evcs_status_raw: '3',
|
||||
evcs_charging_time: '2m 42s',
|
||||
evcs_session_energy_kwh: '0.1',
|
||||
prev_surplus_state: 'charging_hold',
|
||||
},
|
||||
expect: {
|
||||
profile: 'outside_window',
|
||||
sourceMode: 'solar_only',
|
||||
state: 'charging_step_up_battery',
|
||||
decision: 'step_up',
|
||||
desiredCharging: true,
|
||||
currentA: 7,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: 'turn_off',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'charged-session-etablie-latche',
|
||||
label: 'CONTREFACTUEL : meme statut 3 apres 1 h 32 et 4,30 kWh (releve VW 06/09) -> vraie fin, collant',
|
||||
time: AFTERNOON,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
soc_percent: '96', pv_power_w: '2600', pv_power_10m_avg_w: '2500',
|
||||
pv_trend_w: '0', battery_current_a: '2',
|
||||
house_ac_power_w: '2100', vebus_ac_out_l1_power_w: '2100',
|
||||
evcs_charging_switch: 'on',
|
||||
charge_permission_now: 'on',
|
||||
control_latch: 'on',
|
||||
evcs_current_a: '0',
|
||||
evcs_ac_power_w: '0',
|
||||
evcs_status_raw: '3',
|
||||
evcs_charging_time: '1h 32m 0s',
|
||||
evcs_session_energy_kwh: '4.3',
|
||||
prev_surplus_state: 'charging_hold',
|
||||
},
|
||||
expect: {
|
||||
profile: 'outside_window',
|
||||
sourceMode: 'blocked',
|
||||
state: 'day_vehicle_full_idle',
|
||||
decision: 'stop_vehicle_full_or_paused',
|
||||
desiredCharging: false,
|
||||
currentA: 6,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: 'turn_off',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'charged-energie-nulle-latche',
|
||||
label: 'CONTREFACTUEL : statut 3 avec ZERO kWh livre (vehicule plein a l arrivee, cas P10) -> collant',
|
||||
time: AFTERNOON,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
soc_percent: '96', pv_power_w: '2600', pv_power_10m_avg_w: '2500',
|
||||
pv_trend_w: '0', battery_current_a: '2',
|
||||
house_ac_power_w: '2100', vebus_ac_out_l1_power_w: '2100',
|
||||
evcs_charging_switch: 'on',
|
||||
charge_permission_now: 'on',
|
||||
control_latch: 'on',
|
||||
evcs_current_a: '0',
|
||||
evcs_ac_power_w: '0',
|
||||
evcs_status_raw: '3',
|
||||
evcs_charging_time: '3m 20s',
|
||||
evcs_session_energy_kwh: '0',
|
||||
prev_surplus_state: 'charging_hold',
|
||||
},
|
||||
expect: {
|
||||
profile: 'outside_window',
|
||||
sourceMode: 'blocked',
|
||||
state: 'day_vehicle_full_idle',
|
||||
decision: 'stop_vehicle_full_or_paused',
|
||||
desiredCharging: false,
|
||||
currentA: 6,
|
||||
takeoverNeeded: false,
|
||||
edfOnAction: false,
|
||||
takeoverHelperService: 'turn_off',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'night-charged-interrompu-ne-latche-pas',
|
||||
label: 'Nuit HC : statut 3 apres 3 min et 0,10 kWh -> interruption, la charge HC continue',
|
||||
time: NIGHT,
|
||||
overrides: {
|
||||
evcs_vehicle_connected: 'on', evcs_device_connected: 'on',
|
||||
night_session_active: 'on',
|
||||
allow_grid_hc_night: 'on',
|
||||
soc_percent: '55', pv_power_w: '0', pv_power_10m_avg_w: '0',
|
||||
pv_trend_w: '0', battery_current_a: '0',
|
||||
house_ac_power_w: '800', vebus_ac_out_l1_power_w: '800',
|
||||
evcs_charging_switch: 'on',
|
||||
charge_permission_now: 'on',
|
||||
control_latch: 'on',
|
||||
grid_switch: 'on',
|
||||
acin1_available: '1',
|
||||
evcs_current_a: '0',
|
||||
evcs_ac_power_w: '0',
|
||||
evcs_status_raw: '3',
|
||||
evcs_charging_time: '3m 0s',
|
||||
evcs_session_energy_kwh: '0.1',
|
||||
prev_surplus_state: 'charging_step_up_grid_hc',
|
||||
},
|
||||
expect: {
|
||||
profile: 'night_hc',
|
||||
sourceMode: 'grid_hc_allowed',
|
||||
state: 'night_wait_grid_takeover_runtime',
|
||||
decision: 'hold',
|
||||
desiredCharging: false,
|
||||
currentA: 6,
|
||||
takeoverNeeded: true,
|
||||
edfOnAction: true,
|
||||
takeoverHelperService: 'turn_on',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'day-vw-pleine-statut3',
|
||||
label: 'Matin PV fort, session armée 0 W, statut 3 → day_vehicle_full_idle collant (stop propre, plus de solaire)',
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user