From 50dc3cc4891d3bfbd4dba3bfcba7148b4212cdc3 Mon Sep 17 00:00:00 2001 From: Patrick Schurig Date: Thu, 27 Aug 2026 10:10:31 +0200 Subject: [PATCH] =?UTF-8?q?docs(interface):=20SetChargingInfo=20n'est=20pa?= =?UTF-8?q?s=20partiel,=20et=20repeatDays=20va=20de=201=20=C3=A0=207?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deux écarts entre le contrat écrit et le code, dans le même type. Le premier accompagne le correctif de la description publiée : INTERFACE.md répétait la promesse fausse à trois endroits, dont une note d'intégration qui la formulait en toutes lettres (« seuls les champs présents sont appliqués »). La table des défauts obtenus est désormais donnée, ainsi que le geste correct. Le second n'avait pas de correctif de code parce que le code a raison : `repeatDays` était documenté « 0=Lun … 6=Dim » alors que setChargingInfo() refuse tout ce qui sort de [1, 7] — un client qui suit la documentation reçoit EnergyErrorInvalidParameter sur le lundi. Les bornes de `targetPercentage` sont documentées au passage, pour la même raison. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_017TVywtayEeoRJ2yWUW4iZj --- INTERFACE.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/INTERFACE.md b/INTERFACE.md index 625b249..b071e0e 100644 --- a/INTERFACE.md +++ b/INTERFACE.md @@ -51,14 +51,17 @@ ### `ChargingInfo` Configuration d'une borne EV. Seuls les champs marqués `(writable)` peuvent être modifiés via `SetChargingInfo` — les autres sont ignorés ou read-only. +> ⚠️ **`SetChargingInfo` REMPLACE l'objet entier.** Un champ writable absent de l'appel n'est pas +> préservé : il retombe sur son **défaut** (colonne ci-dessous). Voir `NymeaEnergy.SetChargingInfo`. + | Champ | Type | Writable | Description | |---|---|---|---| | `evChargerId` | `Uuid` | — | Identifiant de la borne (obligatoire dans SetChargingInfo) | | `assignedCarId` | `Uuid` | ✓ | Véhicule associé (optionnel) | | `chargingMode` | `ChargingMode` | ✓ | Mode de recharge | | `endDateTime` | `DateTime` | ✓ | Deadline cible (EcoWithTargetTime / EcoMinWithTargetTime) | -| `repeatDays` | `[Int]` | ✓ | Jours de répétition (0=Lun … 6=Dim, liste vide = pas de répétition) | -| `targetPercentage` | `Uint` | ✓ | Niveau batterie cible en % (défaut : 80) | +| `repeatDays` | `[Int]` | ✓ | Jours de répétition (**1=Lun … 7=Dim** ; hors [1, 7] → `EnergyErrorInvalidParameter`). Défaut : liste vide (pas de répétition) | +| `targetPercentage` | `Uint` | ✓ | Niveau batterie cible en %. Défaut : **80** ; > 100 → `EnergyErrorInvalidParameter` | | `chargingState` | `ChargingState` | — | État calculé (lecture seule) | | `spotMarketChargingEnabled` | `Bool` | ✓ | Activer la recharge sur spot market | | `dailySpotMarketPercentage` | `Uint` | ✓ | % de la charge quotidienne à faire en heures spot bon marché | @@ -260,7 +263,28 @@ Retourne la configuration de recharge de toutes les bornes, ou d'une seule. --- #### `NymeaEnergy.SetChargingInfo` -Met à jour la configuration d'une borne. Seuls les champs `USER true` sont modifiables (voir type `ChargingInfo`). Les autres champs sont ignorés. +Met à jour la configuration d'une borne. Seuls les champs `USER true` sont modifiables (voir type `ChargingInfo`) ; les autres (`chargingState`) sont ignorés. + +⚠️ **L'objet donné REMPLACE le stocké — l'appel n'est pas partiel.** Un champ writable omis +**retombe sur son défaut**, il n'est pas préservé : + +| Champ omis | Valeur obtenue | +|---|---| +| `assignedCarId` | aucune (null) | +| `chargingMode` | `ChargingModeNormal` | +| `endDateTime` | aucune | +| `repeatDays` | liste vide | +| `targetPercentage` | **80** | +| `spotMarketChargingEnabled` | `false` | +| `dailySpotMarketPercentage` | `0` | + +Et l'appel réussit : `EnergyErrorNoError`. Rien ne signale la perte. +**Constaté sur le banc `.75` le 2026-08-26** : un appel ne portant que `chargingMode` a porté +`targetPercentage` de 0 à 80. + +**Le geste correct est lire → modifier → renvoyer complet** : `GetChargingInfos`, changer le +champ voulu, réémettre l'objet entier. Le renvoyer tel quel est sûr — `chargingState`, en lecture +seule, est ignoré. **Params :** ```json @@ -956,6 +980,6 @@ L'optimizer reçoit les données de contexte (`SurplusData`) et retourne une `Ch - Les puissances sont en **Watts**, les courants en **Ampères**. - `phasePowerLimit` est en **Ampères** (par phase), pas en Watts. - `weighting` des `ScoreEntry` : 1.0 = créneau le moins cher, 0.0 = le plus cher. -- `SetChargingInfo` est partiel : seuls les champs présents sont appliqués, sauf `evChargerId` qui est toujours requis. +- `SetChargingInfo` **n'est PAS partiel** : l'objet remplace le stocké, et tout champ writable omis retombe sur son défaut (`targetPercentage` → 80, `repeatDays` → vide, …), sans erreur. Lire avec `GetChargingInfos`, modifier, renvoyer complet. `evChargerId` est toujours requis. - `currentPower` du root meter est **négatif** quand il y a surplus solaire (export réseau). - Le plugin fonctionne sans `powersync-optimizer` (mode Community, dégradé proprement).