# -*- coding: utf-8 -*- """Page de decision : dimensionnement du parc batterie. Rejouable. Toutes les valeurs viennent des mesures du 04/09/2026 : 37 nuits completes (statistiques long terme Home Assistant, juillet-septembre) et la courbe energie/SOC etablie sur 576 paliers. """ import json, pathlib NUITS = [10.2,11,11.2,11.6,11.9,12.4,12.4,12.5,12.5,12.6,12.6,12.7,12.8,12.9, 12.9,12.9,13.1,13.1,13.2,13.4,13.4,13.5,13.6,13.7,13.7,13.7,13.9,13.9, 14.2,14.4,15,15.2,15.6,15.9,16.4,16.7,17.2] # kWh utiles par module, mesures. 1,65 dans la fenetre reelle (blocage a 94 %, # plancher ESS a 20 %) ; 1,77 si le blocage a 94 % disparait avec le vieux pack. BRIDE, LIBRE = 1.65, 1.77 ONDULEUR = 0.93 # rendement de restitution vers la maison SCENARIOS = [ ("Actuel", "7 modules actifs — un en panne, un qui faiblit", 7, BRIDE, "etat"), ("A", "Réparer le module en panne — 8 modules", 8, BRIDE, "faible"), ("B", "A + 2 neufs — 10 modules", 10, BRIDE, "bon"), ("C", "A + 4 neufs — 12 modules", 12, BRIDE, "bon"), ("D", "4 récents + 6 neufs, vieux pack retiré", 10, LIBRE, "bon"), ] TRANCHES = [("21-31", 0.097, 88), ("35-44", 0.171, 78), ("45-54", 0.169, 76), ("55-64", 0.163, 85), ("65-74", 0.171, 80), ("75-84", 0.170, 81), ("85-94", 0.169, 62)] JOURNEE = [("00",0.00,0,0,0),("01",0.00,1.88,1.57,1.30),("02",0.00,2.83,2.49,1.83), ("03",0.00,0.03,0.64,0),("04",0.00,0.02,0.69,0),("05",0.00,0.02,0.67,0), ("06",0.00,1.36,0.80,0),("07",0.02,0.72,0.67,0),("08",0.35,0.87,0.83,0), ("09",0.78,0.38,0.83,0),("10",2.18,0.16,1.23,0),("11",4.20,0.02,1.27,0), ("12",2.34,0.00,1.22,0),("13",3.51,0.00,2.99,0.96),("14",3.98,0.00,2.29,0.14), ("15",3.44,0.00,1.98,0),("16",3.59,0.00,1.87,0),("17",1.33,0.00,0.67,0), ("18",0.86,0.00,0.76,0.07),("19",0.12,0.00,0.12,0.09)] def couvre(ac): return sum(1 for n in NUITS if n <= ac + 1e-9) def calc(): out = [] for code, nom, mods, par, ton in SCENARIOS: dc = mods * par ac = dc * ONDULEUR n = couvre(ac) out.append(dict(code=code, nom=nom, mods=mods, dc=dc, ac=ac, n=n, pct=round(100 * n / len(NUITS)), ton=ton)) return out # ----------------------------------------------------------------- graphiques def histo_nuits(sc): """Repartition des 37 nuits, avec les seuils de chaque scenario.""" x0, x1, lo, hi = 74, 940, 9.5, 19.2 px = lambda v: x0 + (v - lo) / (hi - lo) * (x1 - x0) bins = {} for v in NUITS: b = int((v - lo) // 0.5) bins[b] = bins.get(b, 0) + 1 mx = max(bins.values()) base, hmax = 250, 168 s = [f''] # grille for v in range(10, 20): s.append(f'') s.append(f'{v}') s.append(f'kWh consommés par la maison, de 20 h à 9 h') for b, n in sorted(bins.items()): g = lo + b * 0.5 w = (px(g + 0.5) - px(g)) - 3 h = n / mx * hmax s.append(f'{n} nuit(s) entre ' f'{g:.1f} et {g+0.5:.1f} kWh') s.append(f'{n}') # seuils for i, r in enumerate(sc): if r['ac'] > hi or r['ac'] < lo: continue x = px(r['ac']) cl = 'seuil-etat' if r['ton'] == 'etat' else 'seuil' s.append(f'') anc = 'end' if r['ac'] > 17.4 else 'start' dx = -7 if anc == 'end' else 7 y = 34 + 15 + (i % 2) * 17 s.append(f'' f'{r["code"]} · {r["ac"]:.1f}'.replace(".", ",") + '') s.append('') return '\n'.join(s) def courbe_batterie(): x0, x1, base, hmax = 96, 940, 236, 156 n = len(TRANCHES) w = (x1 - x0) / n mx = 0.18 s = [''] for v, lab in [(0.05,'0,05'), (0.10,'0,10'), (0.15,'0,15')]: y = base - v / mx * hmax s.append(f'') s.append(f'{lab}') for i, (lab, k, np_) in enumerate(TRANCHES): h = k / mx * hmax x = x0 + i * w + 9 cl = 'barre-bas' if k < 0.12 else 'barre-haut' s.append(f'{np_} paliers mesurés') s.append(f'' f'{k:.3f}".replace"'.replace('".replace"', '').replace('.', ',')) s.append(f'{lab} %') xg = x0 + 1 * w s.append(f'') s.append(f'genou à 33 %') s.append(f'kWh délivrés par point de SOC · 576 paliers mesurés sur 8 jours') s.append('') return '\n'.join(s) def journee(): x0, x1, base, hmax = 74, 950, 226, 150 n = len(JOURNEE) w = (x1 - x0) / n mx = 4.3 s = [''] for v in (1, 2, 3, 4): y = base - v / mx * hmax s.append(f'') s.append(f'{v}') for i, (h, sol, res, mai, voi) in enumerate(JOURNEE): x = x0 + i * w bw = (w - 8) / 2 for j, (v, cl) in enumerate([(sol, 'sol'), (res, 'res')]): if v <= 0: continue ht = v / mx * hmax s.append(f'{h} h · {v} kWh') if i % 2 == 0: s.append(f'{h}') pts = ' '.join(f'{x0+i*w+w/2:.1f},{base-m/mx*hmax:.1f}' for i,(_,_,_,m,_) in enumerate(JOURNEE)) s.append(f'') for i, (h, _, _, mai, _) in enumerate(JOURNEE): y = base - mai / mx * hmax s.append(f'' f'{h} h · maison {mai} kWh') s.append(f'kWh par heure · jeudi 4 septembre 2026') s.append('') return '\n'.join(s) sc = calc() act = sc[0] b = next(r for r in sc if r['code'] == 'B') c = next(r for r in sc if r['code'] == 'C') lignes_sc = '\n'.join(f''' {r['code']} {r['nom']} {r['mods']} {r['dc']:.1f} {r['ac']:.1f} {r['n']}/37 {r['pct']} % '''.replace('.', ',').replace(',1f', '.1f') for r in sc) html = f'''Dimensionner le parc batterie

Installation Airtria · 4 septembre 2026

Dimensionner le parc batterie

Combien de stockage faut-il pour traverser la nuit sans réseau — et à partir de quel point chaque module supplémentaire cesse de servir à quelque chose.

Aujourd'hui, la batterie passe la nuit seule 1 fois sur 37.

Les 7 modules actifs délivrent {act['ac']:.1f} kWh à la maison. La nuit médiane en demande 13,2, et la plus lourde observée 17,2. Le réseau n'est pas un confort : c'est de l'arithmétique.

13,2 kWhnuit médiane, maison seule, de 20 h à 9 h
15,9 kWh9 nuits sur 10 restent en dessous
1,65 kWhdélivré par module, mesuré — pas 2,4 de plaque
37nuits complètes mesurées, juillet à septembre

Ce que la nuit demande

37 nuits complètes · voiture déduite

Chaque barre compte les nuits dont la consommation tombe dans une tranche d'un demi-kilowattheure. La distribution est serrée : les deux tiers des nuits tiennent entre 12,4 et 14,4 kWh. C'est une bonne nouvelle pour dimensionner — il n'y a pas de queue lointaine à couvrir.

Les traits verticaux marquent ce que chaque scénario sait délivrer. Tout ce qui est à gauche du trait est couvert.

Répartition des nuits, et ce que chaque scénario couvre

Consommation de la maison seule entre 20 h et 9 h, la charge du véhicule soustraite. Source : statistiques long terme de Home Assistant, fin juillet au 4 septembre 2026.

{histo_nuits(sc)}
nuits mesurées parc actuel seuil d'un scénario

Ce qu'un module délivre vraiment

576 paliers de SOC mesurés

Un US2000C annonce 2,4 kWh. Ce n'est pas le chiffre à utiliser. En intégrant la puissance sur chaque palier où le SOC descend d'un point — 576 paliers sur huit jours, en écartant ceux où le réseau apportait quoi que ce soit — la réalité de ce parc apparaît :

Énergie délivrée par point de SOC

Plate à 0,169 kWh de 33 à 93 %, sur six tranches indépendantes. Puis un genou net : en dessous de 33 %, un point de SOC ne vaut plus que 57 % de ce qu'il vaut en haut d'échelle. Signature classique d'un parc vieillissant — cohérent avec un module en panne sur huit et un autre qui faiblit.

{courbe_batterie()}

Dans la fenêtre réellement exploitée — le blocage de charge à 94 % en haut, le plancher ESS à 20 % en bas — les 7 modules actifs contiennent 11,6 kWh, soit 1,65 kWh par module. Après restitution par l'onduleur, {act['ac']:.1f} kWh arrivent à la maison.

Les scénarios

colonne décisive : le nombre de nuits couvertes

{lignes_sc}
ScénarioModules Utile DCLivré AC NuitsCouverture

Le saut décisif est entre A et B : réparer le module en panne ne fait passer la couverture que de 1 à 5 nuits sur 37. Deux modules de plus la portent à 32. Réparer seul ne résout rien.

Le scénario D mérite un regard : mêmes 10 modules que B, mais le vieux groupe retiré. Le blocage de charge à 94 % disparaît avec lui, et la même quantité de matériel délivre 1,1 kWh de plus.

Le plafond que personne ne mentionne

au-delà de la nuit, le stockage ne tourne plus

Du stockage au-delà de la consommation nocturne ne cycle pas. Il se remplit, il attend, et le lendemain midi il est déjà plein — donc il n'absorbe rien. La nuit demande 13 à 17 kWh : au-delà d'environ douze modules, en été, chaque module supplémentaire est un investissement qui dort.

La journée du 4 septembre le montre bien. Le réseau se tait à midi et ne revient jamais ; la production dépasse largement la maison tout l'après-midi ; et pourtant la batterie sature avant 18 h.

Une journée entière — jeudi 4 septembre

Le réseau n'intervient qu'avant midi, pendant les heures creuses et la reprise du plancher ESS. À partir de 11 h la production dépasse la maison de plusieurs kilowattheures par heure. Le surplus de l'après-midi n'a nulle part où aller.

{journee()}
production solaire réseau importé maison

Le lendemain est annoncé à 57,4 kWh. En face : une maison à 30, une batterie qui peut en prendre 8, et pas de voiture — elle part à 8 h 50. Une trentaine de kilowattheures seront refusés, et même douze modules n'y changeraient presque rien.

Le surplus de milieu de journée n'est pas un problème de stockage. C'est un problème de preneur. La voiture absorbe déjà 9,8 kWh par jour en médiane : c'est le meilleur rendement de la liste, et il ne coûte rien.

Le point dur : les quatre vieux modules

là où se joue vraiment la décision

Un module mort, un autre qui faiblit, et un pack qui bloque la charge à 94 % — tous dans le groupe le plus ancien. Or dans un groupe Pylontech en parallèle, le BMS gouverne l'ensemble : le pack faible impose sa loi aux modules neufs.

Ajouter des modules neufs derrière quatre modules fatigués, c'est les faire vieillir au rythme des anciens et hériter du plafond de 94 %. L'observation du propriétaire va dans le même sens : rebrancher le module isolé ferait peut-être descendre le blocage à 85 %.

Ce n'est pas un module à récupérer. C'est un groupe à trancher.

Réparation, garantie, reprise

à confirmer auprès du distributeur

Ce que je ferais

dans cet ordre, sans tout décider aujourd'hui

  1. Faire lire les logs des quatre vieux modules, pas seulement celui en panne. Vous saurez si vous avez un module à remplacer ou un groupe à retirer — et cela ne coûte rien.
  2. Brancher le second véhicule les jours de forte production. Vous saurez en une journée combien de kilowattheures un second preneur absorbe réellement, et ce chiffre déplace le dimensionnement.
  3. Viser 10 à 12 modules équivalents neufs, soit 16 à 20 kWh utiles. C'est la plage qui couvre 85 à 100 % des nuits d'été et qui cycle tous les jours.
  4. Si les logs condamnent le vieux groupe, ne pas rafistoler. Un parc homogène neuf donne la même capacité en moins d'unités, avec une garantie neuve et un plafond de charge qui ne vous suit plus.

Ces chiffres sont tous d'été. Les compteurs exploitables ne remontent qu'à fin juillet. L'hiver, la nuit dure 17 heures au lieu de 13 et la production ne recharge pas : aucun dimensionnement raisonnable ne fera passer un hiver breton sans réseau, et la stratégie des deux charges en heures creuses restera la bonne.

Dimensionnez pour vos nuits d'été, pas contre l'hiver. C'est en été que le stockage travaille tous les jours, et c'est en été que chaque kilowattheure stocké est gratuit.

''' p = pathlib.Path('docs/pages/dimensionnement-batteries.html') p.write_text(html, encoding='utf-8') print(f"{p} — {len(html)} caracteres") for r in sc: print(f" {r['code']:<12} {r['mods']:>2} modules {r['dc']:>5.1f} DC {r['ac']:>5.1f} AC {r['n']:>2}/37 {r['pct']:>3} %")