From 20b21dd46d518eaa9a4a6b3ac5144683fd14f1ef Mon Sep 17 00:00:00 2001 From: Tallagrand Thierry Date: Sat, 5 Sep 2026 13:43:55 +0200 Subject: [PATCH] Un rapport vivant sur l'etat du parc batterie Genere par script pour que les mesures restent en tete du fichier et la mise en page en dessous : mettre a jour une valeur, relancer, republier. La figure centrale trace l'amplitude balayee par chaque cellule. C'est la grandeur qui separe une cellule saine d'une cellule morte sans demonter quoi que ce soit : une cellule ayant perdu sa capacite se remplit et se vide avant ses voisines, donc elle balaye une plage bien plus large a courant identique. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01KKzkkVTG6KXnGXFFC7X9XJ --- docs/mesures/batteries/202609051304-suivi.csv | 21 ++ docs/pages/rapport-batteries.html | 229 ++++++++++++ tools/gen-rapport-batteries.py | 326 ++++++++++++++++++ 3 files changed, 576 insertions(+) create mode 100644 docs/pages/rapport-batteries.html create mode 100644 tools/gen-rapport-batteries.py diff --git a/docs/mesures/batteries/202609051304-suivi.csv b/docs/mesures/batteries/202609051304-suivi.csv index 8459471..9465548 100644 --- a/docs/mesures/batteries/202609051304-suivi.csv +++ b/docs/mesures/batteries/202609051304-suivi.csv @@ -323,3 +323,24 @@ heure_reelle,etat,courant_mA,c1_mV,c2_mV,c3_mV,c4_mV,c5_mV,c6_mV,c7_mV,c8_mV,c9_ 2026-09-05T11:41:18.038Z,module1,,3385,3386,3386,3383,3388,3487,3460,3386,3388,3385,3410,3462,3388,3522,3386,139 2026-09-05T11:41:18.195Z,module2,,3416,3415,3416,3416,3416,3412,3415,3414,3416,3402,3414,3416,3416,3413,3412,14 2026-09-05T11:41:18.382Z,module3,,3394,3418,3391,3392,3392,3480,3391,3392,3394,3425,3395,3494,3392,3394,3486,103 +2026-09-05T11:41:38.528Z,module1,,3385,3387,3387,3384,3389,3486,3460,3387,3389,3386,3411,3461,3389,3522,3386,138 +2026-09-05T11:41:38.686Z,module2,,3416,3415,3416,3416,3416,3412,3415,3414,3416,3402,3414,3416,3416,3413,3412,14 +2026-09-05T11:41:38.843Z,module3,,3395,3419,3392,3393,3393,3479,3391,3393,3394,3424,3396,3492,3393,3395,3484,101 +2026-09-05T11:41:58.990Z,module1,,3385,3386,3386,3384,3388,3482,3457,3387,3389,3386,3410,3458,3389,3519,3386,135 +2026-09-05T11:41:59.147Z,module2,,3415,3413,3415,3415,3414,3410,3414,3413,3414,3400,3413,3415,3415,3412,3410,15 +2026-09-05T11:41:59.302Z,module3,,3395,3419,3392,3393,3393,3476,3392,3393,3395,3422,3396,3489,3393,3395,3481,97 +2026-09-05T11:42:19.449Z,module1,,3385,3386,3386,3383,3388,3480,3456,3387,3389,3385,3410,3456,3389,3518,3385,135 +2026-09-05T11:42:19.606Z,module2,,3415,3413,3415,3415,3415,3410,3414,3412,3414,3401,3412,3415,3415,3412,3411,14 +2026-09-05T11:42:19.761Z,module3,,3396,3420,3392,3394,3393,3474,3392,3394,3395,3420,3396,3487,3393,3395,3479,95 +2026-09-05T11:42:39.905Z,module1,,3384,3386,3386,3384,3389,3476,3454,3387,3389,3386,3409,3453,3389,3516,3386,132 +2026-09-05T11:42:40.063Z,module2,,3416,3414,3416,3416,3416,3411,3415,3414,3416,3402,3413,3416,3416,3413,3413,14 +2026-09-05T11:42:40.220Z,module3,,3396,3420,3392,3394,3393,3472,3392,3394,3395,3418,3396,3484,3394,3395,3476,92 +2026-09-05T11:43:00.363Z,module1,,3387,3388,3388,3386,3391,3478,3455,3389,3391,3388,3411,3455,3391,3518,3388,132 +2026-09-05T11:43:00.579Z,module2,,3417,3415,3417,3417,3417,3413,3416,3414,3416,3403,3415,3417,3417,3414,3413,14 +2026-09-05T11:43:00.737Z,module3,,3397,3421,3393,3395,3394,3471,3393,3395,3397,3417,3397,3482,3395,3396,3474,89 +2026-09-05T11:43:20.866Z,module1,,3388,3389,3389,3387,3392,3478,3456,3390,3392,3389,3413,3456,3392,3518,3389,131 +2026-09-05T11:43:21.022Z,module2,,3418,3416,3418,3418,3417,3413,3416,3415,3417,3403,3415,3417,3417,3414,3414,15 +2026-09-05T11:43:21.179Z,module3,,3397,3422,3393,3395,3394,3469,3394,3395,3397,3415,3397,3480,3395,3397,3473,87 +2026-09-05T11:43:41.325Z,module1,,3389,3390,3390,3388,3392,3477,3455,3391,3393,3390,3414,3454,3393,3517,3390,129 +2026-09-05T11:43:41.483Z,module2,,3418,3416,3418,3418,3417,3413,3416,3415,3417,3403,3415,3417,3417,3415,3414,15 +2026-09-05T11:43:41.640Z,module3,,3395,3418,3391,3393,3392,3464,3392,3393,3395,3408,3395,3473,3393,3395,3466,82 diff --git a/docs/pages/rapport-batteries.html b/docs/pages/rapport-batteries.html new file mode 100644 index 0000000..446b137 --- /dev/null +++ b/docs/pages/rapport-batteries.html @@ -0,0 +1,229 @@ +Les cent cinq cellules + + + + + +
+
+
Parc Pylontech · diagnostic en cours
+

Les cent cinq cellules

+

Huit modules, quinze cellules chacun. Neuf de ces cellules + brident la charge des cent cinq autres. Voici lesquelles, comment on le sait, + et ce qu’on peut en faire.

+
Dernière mise à jour : 5 septembre 2026, 14 h
+
+ +
+
9
cellules atteintes sur 105
+
3
modules concernés sur 8
+
5 s
entre le franchissement du seuil et la coupure
+
30 A
plafond imposé au parc entier, pour 150 A nominaux
+
+ +
+

1Le verdict

+

Le parc n’est pas usé. Quatre modules sur huit sont irréprochables : +soixante cellules sans une seule anomalie, après plus de trois cents cycles. Un +cinquième l’est tout autant.

+

Trois modules portent l’ensemble du problème, et à l’intérieur de ces trois, +neuf cellules. Quand l’une d’elles atteint 3550 mV, le BMS réduit +le courant de charge — non pas de son module, mais de tout le parc. +Cinq modules sains sont bridés par neuf cellules.

+
+ +
+
200 mV400 mV600 mV0322pack ancien · adresse 11182217831784178517765487371818191791017911182126911317814251151780319pack ancien · adresse 31184252131874186518363187185818691871047311187124451318614189154240324isolée (BAT3) · adresse 4113821243138413751396132713481429143101351113612137131281413515683
+
+ saine + décalée + gravement atteinte + terminale +
+
Amplitude balayée par chaque cellule entre sa tension minimale et + sa tension maximale sur la période d’observation. Une cellule saine suit ses + voisines à quelques millivolts près. Une cellule qui a perdu de la capacité se + remplit et se vide avant elles, donc elle balaye une plage bien plus large à + courant identique — c’est le signe qui ne trompe pas, et il ne demande aucun + démontage.
+
+ +
+

2Le parc, module par module

+

L’identité d’un module est son code-barres, jamais son adresse : chaque +chaîne renumérote ses modules à partir de 1, il existe donc deux « module +1 » dans cette installation.

+
+ +
+ + + +
Code-barresPackAdr.Cellules atteintesLesquellesSurtensionsSous-tensions
K220803C30160322ancien136 · 7 · 1249886en service
—ancien20—00en service
K220803C30160319ancien352 · 6 · 10 · 12 · 15416179en service
K220803C30160324ancien41152959isolée
Y230202C30371426récent10—11en service
Y230202C30371425récent20—11en service
Y230202C30371431récent30—11en service
Y230202C30371427récent40—10en service
+ +
+

Le contraste est net : 498 surtensions pour le premier +module contre 1 pour chacun des quatre modules du pack récent, +qui ont pourtant encaissé dix fois plus de cycles.

+ +

3Le déclenchement, chronométré

+

Le 5 septembre, la console a été branchée sur les trois modules du pack ancien +pendant que l’alarme montait. Ce qui suit est le relevé, à la seconde.

+
+ +
+ + +
HeureCe qui se passe
13:04:48cellule 7 du module …0322 à 3526 mV, cellule 6 du module …0319 à 3541sous le seuil
13:05:08les mêmes à 3555 et 3575 mVniveau 3 franchi
13:05:13le BMS abaisse le courant de charge autorisé de 50 à 30 Acinq secondes plus tard
13:15:10les cellules redescendent à 3499 et 3522 mV, l’alarme repasse au vertle plafond, lui, reste à 30 A
13:22:40plafond 30 → 40 Aaprès 7 min 31 s
13:26:39plafond 40 → 35 A, meneuses à 3563 et 3548 mVil redéclenche
13:38:10plafond 35 → 40 Aaprès 11 min 31 s
+ +
+
+

La découverte la plus utile de la journée tient dans la +quatrième ligne : l’alarme repasse au vert bien avant que le plafond ne +remonte. Chercher l’alarme dans les journaux fait donc manquer l’essentiel du +phénomène — elle dure quelques minutes, le bridage dure des heures.

+
+ +

Les seuils ne sont pas des valeurs choisies : ce sont ceux que le +matériel déclare lui-même.

+
  • 3480 mV niveau 1
  • 3520 mV niveau 2
  • 3550 mV niveau 3 — le courant se réduit
  • 3600 mV niveau 4
+ +

4Ce qui a été essayé

+

La consigne de tension de charge a été abaissée de 51,3 +à 51,0 V pour voir si le contournement suffisait à ne +plus jamais déclencher.

+

Il ne suffit pas. À 92 % de charge, les cellules meneuses +ont atteint 3563 et 3548 mV malgré la consigne abaissée, et le plafond a +recommencé à osciller entre 35 et 40 A. Le système ne reste pas « bloqué » +à une valeur : il cherche en permanence le courant maximal que la cellule la +plus faible tolère.

+

Une mesure explique pourquoi la tension seule ne peut pas régler la question. +À tension de parc identique, la cellule meneuse était à 3555 mV +sous 50 A et à 3496 mV sous 30 A. Son excursion +est donc largement produite par sa résistance interne multipliée par le courant, +et pas seulement par son état de charge.

+ +

5D’où viennent les dégâts

+

Pas de l’usure. Le pack récent a encaissé trois cent quarante cycles en un an +et ses soixante cellules sont intactes : cycler n’abîme pas ces modules.

+

Les deux cellules terminales du parc sont descendues à +2953 et 2939 mV, sous le seuil +d’alarme basse. Un accumulateur au lithium-fer-phosphate mené là sous charge perd +de la capacité de façon irréversible. Ces cellules n’ont pas vieilli, +elles ont été vidées trop bas.

+
+

Et il y a une boucle à rompre. La jauge d’état de charge du parc suit la +cellule la plus faible. Quand le système croit toucher son plancher de sécurité +à 22 %, cette cellule est déjà bien plus bas que le chiffre ne le laisse +croire. Le plancher est exprimé dans une grandeur que la cellule +endommagée fausse elle-même : il ne protège pas ce qu’il croit +protéger, et rien n’empêche le même mécanisme d’atteindre le pack sain.

+
+ +

6Ce qui vient

+

Une alimentation stabilisée permettra de reprendre le rééquilibrage au banc, +en commençant par le module isolé : il n’a qu’une cellule à traiter, il est +hors service, et rien de ce qu’on y tentera ne peut nuire au parc.

+

Une limite à garder en tête : un rééquilibrage corrige un décalage +de charge, pas une perte de capacité. Les cellules modérément décalées +sont de bonnes candidates. Les deux cellules terminales le sont beaucoup moins — +et c’est précisément ce que l’essai sur le module isolé dira, sans risque.

+
+ +
Relevés faits sur la console série des BMS Pylontech, que ni Home +Assistant ni le GX Victron n’exposent : le système ne publie que l’agrégat +du parc. Ce rapport évolue au fil des travaux.
+
diff --git a/tools/gen-rapport-batteries.py b/tools/gen-rapport-batteries.py new file mode 100644 index 0000000..8fe17e1 --- /dev/null +++ b/tools/gen-rapport-batteries.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +"""Genere le rapport sur l'etat du parc batterie. + +Rejouable : les mesures vivent dans les constantes en tete, la mise en page +en dessous. Mettre a jour une mesure, relancer, republier. +""" +import pathlib, datetime + +MAJ = "5 septembre 2026, 14 h" + +# Amplitude min->max de chaque cellule, relevee sur l'historique du BMS. +# C'est LA grandeur qui separe une cellule saine d'une cellule morte : une +# cellule qui a perdu sa capacite se remplit et se vide avant ses voisines, +# donc elle balaye une plage bien plus large a courant identique. +MODULES = [ + ("K220803C30160322", "pack ancien · adresse 1", "1681 relevés, 14/08 → 05/09", [ + 182,178,178,178,177,548,371,181,179,179,182,691,178,251,178]), + ("K220803C30160319", "pack ancien · adresse 3", "1798 relevés, 30/07 → 05/09", [ + 184,521,187,186,183,318,185,186,187,473,187,445,186,189,424]), + ("K220803C30160324", "isolée (BAT3) · adresse 4", "322 relevés, 23/07 → 05/09", [ + 138,124,138,137,139,132,134,142,143,135,136,137,128,135,683]), +] + +PARC = [ + ("K220803C30160322", "ancien", "1", "3", "6 · 7 · 12", 498, 86, "en service"), + ("—", "ancien", "2", "0", "—", 0, 0, "en service"), + ("K220803C30160319", "ancien", "3", "5", "2 · 6 · 10 · 12 · 15", 416, 179, "en service"), + ("K220803C30160324", "ancien", "4", "1", "15", 29, 59, "isolée"), + ("Y230202C30371426", "récent", "1", "0", "—", 1, 1, "en service"), + ("Y230202C30371425", "récent", "2", "0", "—", 1, 1, "en service"), + ("Y230202C30371431", "récent", "3", "0", "—", 1, 1, "en service"), + ("Y230202C30371427", "récent", "4", "0", "—", 1, 0, "en service"), +] + +CHRONO = [ + ("13:04:48", "cellule 7 du module …0322 à 3526 mV, cellule 6 du module …0319 à 3541", "sous le seuil"), + ("13:05:08", "les mêmes à 3555 et 3575 mV", "niveau 3 franchi"), + ("13:05:13", "le BMS abaisse le courant de charge autorisé de 50 à 30 A", "cinq secondes plus tard"), + ("13:15:10", "les cellules redescendent à 3499 et 3522 mV, l’alarme repasse au vert", "le plafond, lui, reste à 30 A"), + ("13:22:40", "plafond 30 → 40 A", "après 7 min 31 s"), + ("13:26:39", "plafond 40 → 35 A, meneuses à 3563 et 3548 mV", "il redéclenche"), + ("13:38:10", "plafond 35 → 40 A", "après 11 min 31 s"), +] + +SEUILS = [(3480, "niveau 1"), (3520, "niveau 2"), (3550, "niveau 3 — le courant se réduit"), (3600, "niveau 4")] + +def couleur(a): + if a >= 600: return "var(--mort)" + if a >= 400: return "var(--grave)" + if a >= 250: return "var(--attention)" + return "var(--sain)" + +def figure(): + """Barres horizontales : amplitude de chaque cellule, par module.""" + LARG, LIGNE, GAUCHE, HAUT = 760, 15, 96, 26 + ech = 0.86 # px par mV + out, y = [], 0 + for code, place, _n, amps in MODULES: + out.append(f'{code[-4:]}' + f'{place}') + y += HAUT + for i, a in enumerate(amps, 1): + larg = a * ech + out.append( + f'{i}' + f'' + f'{a}') + y += LIGNE + y += 14 + reperes = [] + for mv in (200, 400, 600): + x = GAUCHE + mv * ech + reperes.append(f'' + f'{mv} mV') + return (f'' + + "".join(reperes) + "".join(out) + '') + +lignes_parc = "".join( + f'{c}{p}' + f'{a}{n}{d}' + f'{hv}{ov}{e}' + for c, p, a, n, d, hv, ov, e in PARC) + +lignes_chrono = "".join( + f'{h}{q}{n}' + for h, q, n in CHRONO) + +lignes_seuils = "".join( + f'
  • {mv} mV {nom}
  • ' for mv, nom in SEUILS) + +HTML = f"""Les cent cinq cellules + + + + + +
    +
    +
    Parc Pylontech · diagnostic en cours
    +

    Les cent cinq cellules

    +

    Huit modules, quinze cellules chacun. Neuf de ces cellules + brident la charge des cent cinq autres. Voici lesquelles, comment on le sait, + et ce qu’on peut en faire.

    +
    Dernière mise à jour : {MAJ}
    +
    + +
    +
    9
    cellules atteintes sur 105
    +
    3
    modules concernés sur 8
    +
    5 s
    entre le franchissement du seuil et la coupure
    +
    30 A
    plafond imposé au parc entier, pour 150 A nominaux
    +
    + +
    +

    1Le verdict

    +

    Le parc n’est pas usé. Quatre modules sur huit sont irréprochables : +soixante cellules sans une seule anomalie, après plus de trois cents cycles. Un +cinquième l’est tout autant.

    +

    Trois modules portent l’ensemble du problème, et à l’intérieur de ces trois, +neuf cellules. Quand l’une d’elles atteint 3550 mV, le BMS réduit +le courant de charge — non pas de son module, mais de tout le parc. +Cinq modules sains sont bridés par neuf cellules.

    +
    + +
    +
    {figure()}
    +
    + saine + décalée + gravement atteinte + terminale +
    +
    Amplitude balayée par chaque cellule entre sa tension minimale et + sa tension maximale sur la période d’observation. Une cellule saine suit ses + voisines à quelques millivolts près. Une cellule qui a perdu de la capacité se + remplit et se vide avant elles, donc elle balaye une plage bien plus large à + courant identique — c’est le signe qui ne trompe pas, et il ne demande aucun + démontage.
    +
    + +
    +

    2Le parc, module par module

    +

    L’identité d’un module est son code-barres, jamais son adresse : chaque +chaîne renumérote ses modules à partir de 1, il existe donc deux « module +1 » dans cette installation.

    +
    + +
    + + +{lignes_parc} +
    Code-barresPackAdr.Cellules atteintesLesquellesSurtensionsSous-tensions
    + +
    +

    Le contraste est net : 498 surtensions pour le premier +module contre 1 pour chacun des quatre modules du pack récent, +qui ont pourtant encaissé dix fois plus de cycles.

    + +

    3Le déclenchement, chronométré

    +

    Le 5 septembre, la console a été branchée sur les trois modules du pack ancien +pendant que l’alarme montait. Ce qui suit est le relevé, à la seconde.

    +
    + +
    + +{lignes_chrono} +
    HeureCe qui se passe
    + +
    +
    +

    La découverte la plus utile de la journée tient dans la +quatrième ligne : l’alarme repasse au vert bien avant que le plafond ne +remonte. Chercher l’alarme dans les journaux fait donc manquer l’essentiel du +phénomène — elle dure quelques minutes, le bridage dure des heures.

    +
    + +

    Les seuils ne sont pas des valeurs choisies : ce sont ceux que le +matériel déclare lui-même.

    +
      {lignes_seuils}
    + +

    4Ce qui a été essayé

    +

    La consigne de tension de charge a été abaissée de 51,3 +à 51,0 V pour voir si le contournement suffisait à ne +plus jamais déclencher.

    +

    Il ne suffit pas. À 92 % de charge, les cellules meneuses +ont atteint 3563 et 3548 mV malgré la consigne abaissée, et le plafond a +recommencé à osciller entre 35 et 40 A. Le système ne reste pas « bloqué » +à une valeur : il cherche en permanence le courant maximal que la cellule la +plus faible tolère.

    +

    Une mesure explique pourquoi la tension seule ne peut pas régler la question. +À tension de parc identique, la cellule meneuse était à 3555 mV +sous 50 A et à 3496 mV sous 30 A. Son excursion +est donc largement produite par sa résistance interne multipliée par le courant, +et pas seulement par son état de charge.

    + +

    5D’où viennent les dégâts

    +

    Pas de l’usure. Le pack récent a encaissé trois cent quarante cycles en un an +et ses soixante cellules sont intactes : cycler n’abîme pas ces modules.

    +

    Les deux cellules terminales du parc sont descendues à +2953 et 2939 mV, sous le seuil +d’alarme basse. Un accumulateur au lithium-fer-phosphate mené là sous charge perd +de la capacité de façon irréversible. Ces cellules n’ont pas vieilli, +elles ont été vidées trop bas.

    +
    +

    Et il y a une boucle à rompre. La jauge d’état de charge du parc suit la +cellule la plus faible. Quand le système croit toucher son plancher de sécurité +à 22 %, cette cellule est déjà bien plus bas que le chiffre ne le laisse +croire. Le plancher est exprimé dans une grandeur que la cellule +endommagée fausse elle-même : il ne protège pas ce qu’il croit +protéger, et rien n’empêche le même mécanisme d’atteindre le pack sain.

    +
    + +

    6Ce qui vient

    +

    Une alimentation stabilisée permettra de reprendre le rééquilibrage au banc, +en commençant par le module isolé : il n’a qu’une cellule à traiter, il est +hors service, et rien de ce qu’on y tentera ne peut nuire au parc.

    +

    Une limite à garder en tête : un rééquilibrage corrige un décalage +de charge, pas une perte de capacité. Les cellules modérément décalées +sont de bonnes candidates. Les deux cellules terminales le sont beaucoup moins — +et c’est précisément ce que l’essai sur le module isolé dira, sans risque.

    +
    + + +
    +""" + +p = pathlib.Path("docs/pages/rapport-batteries.html") +p.parent.mkdir(parents=True, exist_ok=True) +p.write_text(HTML, encoding="utf-8") +print(f"{p} {len(HTML)} caracteres")