Tableau Energie : RS 450 separe en Sud et Ouest, historique importe

This commit is contained in:
Tallagrand Thierry
2026-10-04 01:22:37 +02:00
parent c6665a786e
commit 7ec3bf37a1
3 changed files with 84 additions and 0 deletions

View File

@@ -1597,6 +1597,17 @@ des chargeurs), batterie +19,25 / -20,58, borne 9,30 (= 4,6 + 0,1 + 4,6), reseau
arriere = remettre ce fichier HA arrete, ou retirer les sources dans Parametres -> Tableaux
de bord -> Energie. ⚠️ La « consommation maison » du tableau Energie est deduite (solaire +
reseau + decharge - charge) : elle inclut la borne et les pertes de l'onduleur.
- **Sud et Ouest separes (04/10 ~01:25, proprietaire)** : le RS 450/200 est remplace dans
le tableau Energie par deux capteurs gabarits (`packages/evcs_energie_trackers.yaml`) :
`sensor.pv_rs_450_sud_production_du_jour` (trackers 1-3, 30 panneaux) et
`sensor.pv_rs_450_ouest_production_du_jour` (tracker 4, 9 panneaux), en
`total_increasing`. Sur : les quatre trackers se remettent a zero au MEME instant
(00:23 le 03/10). Historique importe depuis les stats horaires des trackers
(`recorder/import_statistics`, depuis le 28/07, script `tools/ponctuel/20261004-import-sud-ouest.js`).
Recoupement avec le compteur du chargeur : 01/10 28,6 + 3,1 = 31,7 (31,69), 02/10 26,0 +
2,8 (28,73), 03/10 27,5 + 5,3 (32,72). Sauvegarde `.storage/energy.bak-20261004-sudouest`.
⚠️ **A verifier le 04/10** : la premiere heure compilee par HA (02:00) doit prolonger la
somme importee sans saut (stats journalieres du 04/10 sud/ouest ~ production reelle).
---
*Document mis a jour le : 04/10/2026 (~01:10) — kilometrage des vehicules (km/kWh, capacite, releves de reference, agent cable 15/15) ; a verifier le 04/10 au matin : nuit du budget JEEP ; concierge : vehicule non confirme demande, heure de saisie ; Grafana vehicules en tableau ; Grafana vehicules : ZERO et Invite ajoutes, session 16:46 reetiquetee ZERO ; prevision SOC 10 h ~35 % ; concierge fiable : niveau note par le script, une ligne, dedoublonnage, simulation par drapeau ; agent : message incompris = question, bourse sur demande explicite (banc final 6/6) ; a verifier : nuit du samedi 03 au dimanche 04/10 (budget < besoin JEEP), cron orange-cloture lundi 05/10 apres 17:40, comparaison VRM / Forecast.Solar lundi 05/10*

View File

@@ -0,0 +1,32 @@
# =====================================================
# EVCS — PRODUCTION SUD / OUEST DU RS 450/200 POUR LE TABLEAU ENERGIE (04/10/2026)
# Le RS 450/200 porte le SUD (trackers 1-3, 3 strings de 10 panneaux, 35°) et
# l'OUEST (tracker 4, 9 panneaux, 45°) — MANUEL §0. Ses trackers ne publient
# qu'une production DU JOUR ; les quatre se remettent a zero au MEME instant
# (verifie le 03/10 a 00:23), donc la somme est sure en total_increasing (la
# remise a zero est vue comme un nouveau cycle de compteur, pas une baisse).
# Historique anterieur importe depuis les statistiques des trackers.
# =====================================================
template:
- sensor:
- name: "PV RS 450 Sud - production du jour"
unique_id: evcs_pv_rs450_sud_jour
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
icon: mdi:solar-panel
availability: >
{{ (1, 2, 3) | map('string') | map('regex_replace', '^', 'sensor.mppt_450_200_hq2449yr9pt_tracker_solar_')
| map('regex_replace', '$', '_yield_today') | map('states') | map('is_number') | min }}
state: >
{{ (states('sensor.mppt_450_200_hq2449yr9pt_tracker_solar_1_yield_today') | float
+ states('sensor.mppt_450_200_hq2449yr9pt_tracker_solar_2_yield_today') | float
+ states('sensor.mppt_450_200_hq2449yr9pt_tracker_solar_3_yield_today') | float) | round(2) }}
- name: "PV RS 450 Ouest - production du jour"
unique_id: evcs_pv_rs450_ouest_jour
unit_of_measurement: kWh
device_class: energy
state_class: total_increasing
icon: mdi:solar-panel
availability: "{{ states('sensor.mppt_450_200_hq2449yr9pt_tracker_solar_4_yield_today') | is_number }}"
state: "{{ states('sensor.mppt_450_200_hq2449yr9pt_tracker_solar_4_yield_today') | float | round(2) }}"

View File

@@ -0,0 +1,41 @@
// Calcule (et importe si IMPORT=1) l'historique Sud/Ouest depuis les stats horaires des trackers.
const ws = new WebSocket(process.env.HA_URL.replace(/^http/, 'ws') + '/api/websocket');
let id = 1; const pend = {};
const call = (m) => new Promise(r => { const i = id++; pend[i] = r; ws.send(JSON.stringify({ id: i, ...m })); });
const T = (i) => `sensor.mppt_450_200_hq2449yr9pt_tracker_solar_${i}_yield_today`;
ws.onmessage = async (e) => {
const m = JSON.parse(e.data);
if (m.type === 'auth_required') return ws.send(JSON.stringify({ type: 'auth', access_token: process.env.HA_TOKEN }));
if (m.type !== 'auth_ok') { if (pend[m.id]) { pend[m.id](m); delete pend[m.id]; } return; }
const fin = new Date(); fin.setMinutes(0, 0, 0);
const r = await call({ type: 'recorder/statistics_during_period', start_time: '2025-01-01T00:00:00Z',
end_time: fin.toISOString(), period: 'hour', types: ['state'], statistic_ids: [1, 2, 3, 4].map(T) });
const st = r.result;
const par = {}; // start -> {1:..,4:..}
for (const i of [1, 2, 3, 4]) for (const x of (st[T(i)] || [])) { (par[x.start] ||= {})[i] = x.state; }
const heures = Object.keys(par).map(Number).sort((a, b) => a - b);
console.log('heures', heures.length, new Date(heures[0]).toISOString(), '->', new Date(heures.at(-1)).toISOString());
const serie = (ids) => { const out = []; let prev = null, sum = 0, last = {};
for (const h of heures) {
for (const i of ids) if (par[h][i] !== undefined && par[h][i] !== null) last[i] = par[h][i];
if (!ids.every(i => last[i] !== undefined)) continue;
const v = Math.round(ids.reduce((a, i) => a + last[i], 0) * 100) / 100;
if (prev !== null) sum += v >= prev ? v - prev : v;
prev = v; out.push({ start: new Date(h).toISOString(), state: v, sum: Math.round(sum * 1000) / 1000 });
} return out; };
const sud = serie([1, 2, 3]), ouest = serie([4]);
console.log('sud', sud.length, 'total', sud.at(-1).sum, '| ouest', ouest.length, 'total', ouest.at(-1).sum);
// controle : derniere journee complete
const jour = (s, d0, d1) => { const a = s.filter(x => x.start >= d0 && x.start < d1); return a.length ? (a.at(-1).sum - (s[s.indexOf(a[0]) - 1]?.sum ?? 0)).toFixed(2) : null; };
console.log('03/10 sud', jour(sud, '2026-10-02T22', '2026-10-03T22'), 'ouest', jour(ouest, '2026-10-02T22', '2026-10-03T22'));
console.log('02/10 sud', jour(sud, '2026-10-01T22', '2026-10-02T22'), 'ouest', jour(ouest, '2026-10-01T22', '2026-10-02T22'));
if (process.env.IMPORT === '1') {
for (const [sid, nom, s] of [['sensor.pv_rs_450_sud_production_du_jour', 'PV RS 450 Sud - production du jour', sud],
['sensor.pv_rs_450_ouest_production_du_jour', 'PV RS 450 Ouest - production du jour', ouest]]) {
const res = await call({ type: 'recorder/import_statistics', metadata: { has_mean: false, has_sum: true, name: nom,
source: 'recorder', statistic_id: sid, unit_of_measurement: 'kWh' }, stats: s });
console.log('import', sid, res.success, JSON.stringify(res.error || ''));
}
}
ws.close();
};