docs: add INTERFACE.md with complete NymeaEnergy JSON-RPC API

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Schurig 2026-06-06 08:00:07 +02:00
parent 74c94161cd
commit 2931d295bc

513
INTERFACE.md Normal file
View File

@ -0,0 +1,513 @@
# INTERFACE.md — API JSON-RPC du plugin `nymea-energy-plugin-nymea`
> Ce fichier fait autorité sur l'interface exposée par le plugin.
> Mettre à jour ce fichier à chaque modification de l'API.
>
> **Namespace :** `NymeaEnergy`
> **Versions enregistrées :** 08 (`registerExperienceHandler(..., 0, 8)`)
> **Transport :** WebSocket JSON-RPC 2.0, port 4444 (nymea standard)
---
## Enums
### `ChargingMode`
| Valeur | Description |
|---|---|
| `ChargingModeNormal` | Recharge immédiate au maximum disponible |
| `ChargingModeEco` | Recharge sur surplus solaire uniquement |
| `ChargingModeEcoWithTargetTime` | Eco + deadline de fin (`endDateTime` + `targetPercentage`) |
| `ChargingModeEcoWithMinCurrent` | Eco + courant minimum garanti (6 A) si pas de surplus |
| `ChargingModeEcoMinWithTargetTime` | Eco + courant minimum + deadline |
### `ChargingState` (lecture seule — calculé par le manager)
| Valeur | Description |
|---|---|
| `ChargingStateIdle` | Pas de recharge active |
| `ChargingStateSurplusCharging` | Recharge sur surplus solaire en cours |
| `ChargingStateSpotMarketCharging` | Recharge sur créneau spot market en cours |
| `ChargingStateTimeRequirement` | Recharge forcée pour atteindre la deadline |
### `ChargingActionIssuer`
| Valeur | Description |
|---|---|
| `ChargingActionIssuerUnknown` | Émetteur non identifié |
| `ChargingActionIssuerSurplusCharging` | Action émise par le surplus manager |
| `ChargingActionIssuerSpotMarketCharging` | Action émise par le spot market manager |
| `ChargingActionIssuerTimeRequirement` | Action émise pour honorer la deadline |
| `ChargingActionIssuerOverloadProtection` | Action émise par la protection surcharge |
### `EnergyError`
| Valeur | Description |
|---|---|
| `EnergyErrorNoError` | Succès |
| `EnergyErrorMissingParameter` | Paramètre obligatoire absent |
| `EnergyErrorInvalidParameter` | Valeur de paramètre invalide |
---
## Types
### `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.
| 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) |
| `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é |
### `ChargingAction`
Action envoyée au charger physique (présente dans les schedules).
| Champ | Type | Description |
|---|---|---|
| `chargingEnabled` | `Bool` | Activer/désactiver la recharge |
| `maxChargingCurrent` | `Double` | Courant max en Ampères |
| `desiredPhaseCount` | `Uint` | Nombre de phases souhaitées (1 ou 3) |
| `issuer` | `ChargingActionIssuer` | Origine de la décision |
### `ChargingSchedule`
Créneau de recharge planifié (résultat du calcul du manager).
| Champ | Type | Description |
|---|---|---|
| `evChargerId` | `Uuid` | Borne concernée |
| `startDateTime` | `DateTime` | Début du créneau |
| `endDateTime` | `DateTime` | Fin du créneau |
| `action` | `ChargingAction` | Action prévue sur ce créneau |
### `ScoreEntry`
Entrée de cotation horaire du spot market, avec pondération relative.
| Champ | Type | Description |
|---|---|---|
| `startDateTime` | `DateTime` | Début du créneau tarifaire |
| `endDateTime` | `DateTime` | Fin du créneau tarifaire |
| `value` | `Float` | Prix brut (€/MWh, selon provider) |
| `weighting` | `Float` | Pondération relative : 0.0 = le plus cher, 1.0 = le moins cher |
### `SpotMarketProviderInfo`
Fournisseur de données spot market disponible.
| Champ | Type | Description |
|---|---|---|
| `providerId` | `Uuid` | Identifiant du provider |
| `name` | `String` | Nom affiché |
| `country` | `Uint` | Pays (`QLocale::Country`) |
| `website` | `String` | URL du site du provider |
**Providers enregistrés :**
| Nom | `providerId` |
|---|---|
| aWATTar AT | `5196b3cc-b2ee-46d6-b63a-7af2cf70ba67` |
| aWATTar DE | `0ca6ad88-e243-438d-a0f8-986cecf61834` |
---
## Méthodes
> Notation : `o:` = paramètre optionnel. Tous les appels requièrent un token d'auth nymea.
---
### Overload protection
#### `NymeaEnergy.GetPhasePowerLimit`
Retourne la limite de courant par phase configurée.
**Params :** aucun
**Returns :**
```json
{ "phasePowerLimit": 25 }
```
> `0` signifie non configuré — tout le smart charging est désactivé.
---
#### `NymeaEnergy.SetPhasePowerLimit`
Définit la limite de courant par phase (en Ampères). `0` désactive le smart charging.
**Params :**
```json
{ "phasePowerLimit": 25 }
```
**Returns :**
```json
{ "energyError": "EnergyErrorNoError" }
```
---
### Paramètres de recharge
#### `NymeaEnergy.GetAcquisitionTolerance`
Retourne le seuil de surplus nécessaire pour démarrer une recharge Eco.
**Params :** aucun
**Returns :**
```json
{ "acquisitionTolerance": 0.5 }
```
> Valeur entre 0.0 et 1.0. Plus la valeur est haute, plus il faut de surplus.
---
#### `NymeaEnergy.SetAcquisitionTolerance`
**Params :**
```json
{ "acquisitionTolerance": 0.5 }
```
**Returns :**
```json
{ "energyError": "EnergyErrorNoError" }
```
> Retourne `EnergyErrorInvalidParameter` si hors de `[0.0, 1.0]`.
---
#### `NymeaEnergy.GetBatteryLevelConsideration`
Retourne le facteur de prise en compte du stockage batterie dans le calcul du surplus.
**Params :** aucun
**Returns :**
```json
{ "batteryLevelConsideration": 0.9 }
```
> 0.0 = stockage ignoré, 1.0 = surplus réduit intégralement de la puissance de charge batterie.
---
#### `NymeaEnergy.SetBatteryLevelConsideration`
**Params :**
```json
{ "batteryLevelConsideration": 0.9 }
```
**Returns :**
```json
{ "energyError": "EnergyErrorNoError" }
```
> Retourne `EnergyErrorInvalidParameter` si hors de `[0.0, 1.0]`.
---
#### `NymeaEnergy.GetLockOnUnplug`
Retourne si la borne doit être verrouillée à la déconnexion du véhicule.
**Params :** aucun
**Returns :**
```json
{ "lockOnUnplug": false }
```
---
#### `NymeaEnergy.SetLockOnUnplug`
**Params :**
```json
{ "lockOnUnplug": true }
```
**Returns :**
```json
{ "energyError": "EnergyErrorNoError" }
```
---
### Configuration EV
#### `NymeaEnergy.GetChargingInfos`
Retourne la configuration de recharge de toutes les bornes, ou d'une seule.
**Params :**
```json
{ "o:evChargerId": "uuid-de-la-borne" }
```
**Returns :**
```json
{
"chargingInfos": [
{
"evChargerId": "uuid-de-la-borne",
"assignedCarId": "uuid-du-car",
"chargingMode": "ChargingModeEco",
"chargingState": "ChargingStateSurplusCharging",
"endDateTime": "2025-06-15T08:00:00+02:00",
"repeatDays": [1, 2, 3, 4, 5],
"targetPercentage": 80,
"spotMarketChargingEnabled": false,
"dailySpotMarketPercentage": 0
}
]
}
```
---
#### `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.
**Params :**
```json
{
"chargingInfo": {
"evChargerId": "uuid-de-la-borne",
"chargingMode": "ChargingModeEcoWithTargetTime",
"endDateTime": "2025-06-15T08:00:00+02:00",
"targetPercentage": 80
}
}
```
**Returns :**
```json
{ "energyError": "EnergyErrorNoError" }
```
---
#### `NymeaEnergy.GetChargingSchedules`
Retourne le planning de recharge calculé (toutes les bornes, horizon ~24h).
**Params :** aucun
**Returns :**
```json
{
"chargingSchedules": [
{
"evChargerId": "uuid-de-la-borne",
"startDateTime": "2025-06-15T02:00:00+02:00",
"endDateTime": "2025-06-15T04:30:00+02:00",
"action": {
"chargingEnabled": true,
"maxChargingCurrent": 16.0,
"desiredPhaseCount": 1,
"issuer": "ChargingActionIssuerSpotMarketCharging"
}
}
]
}
```
---
### Spot market
#### `NymeaEnergy.GetAvailableSpotMarketProviders`
Retourne la liste des providers spot market disponibles.
**Params :** aucun
**Returns :**
```json
{
"providers": [
{
"providerId": "5196b3cc-b2ee-46d6-b63a-7af2cf70ba67",
"name": "aWATTar AT",
"country": 14,
"website": "https://www.awattar.at"
},
{
"providerId": "0ca6ad88-e243-438d-a0f8-986cecf61834",
"name": "aWATTar DE",
"country": 82,
"website": "https://www.awattar.de"
}
]
}
```
---
#### `NymeaEnergy.GetSpotMarketConfiguration`
Retourne la configuration spot market courante.
**Params :** aucun
**Returns :**
```json
{
"enabled": true,
"available": true,
"o:providerId": "5196b3cc-b2ee-46d6-b63a-7af2cf70ba67"
}
```
> `providerId` est absent si `enabled` est `false`.
---
#### `NymeaEnergy.SetSpotMarketConfiguration`
Active ou désactive le spot market et sélectionne le provider.
**Params :**
```json
{
"enabled": true,
"o:providerId": "5196b3cc-b2ee-46d6-b63a-7af2cf70ba67"
}
```
> Si `enabled: true`, `providerId` est obligatoire et doit être un UUID valide.
**Returns :**
```json
{ "energyError": "EnergyErrorNoError" }
```
> Retourne `EnergyErrorInvalidParameter` si `enabled: true` sans `providerId`, ou `providerId` inconnu.
---
#### `NymeaEnergy.GetSpotMarketScoreEntries`
Retourne les cotations pondérées du provider actif. Liste vide si désactivé ou non disponible.
**Params :** aucun
**Returns :**
```json
{
"spotMarketScoreEntries": [
{
"startDateTime": "2025-06-15T00:00:00+02:00",
"endDateTime": "2025-06-15T01:00:00+02:00",
"value": 45.2,
"weighting": 0.85
}
]
}
```
---
## Notifications
S'abonner via `JSONRPC.SetNotificationStatus` avec le namespace `"NymeaEnergy"`.
---
### `NymeaEnergy.PhasePowerLimitChanged`
```json
{ "phasePowerLimit": 25 }
```
---
### `NymeaEnergy.AcquisitionToleranceChanged`
```json
{ "acquisitionTolerance": 0.5 }
```
---
### `NymeaEnergy.BatteryLevelConsiderationChanged`
```json
{ "batteryLevelConsideration": 0.9 }
```
---
### `NymeaEnergy.LockOnUnplugChanged`
```json
{ "lockOnUnplug": true }
```
---
### `NymeaEnergy.ChargingInfoAdded`
Émis quand une nouvelle borne est détectée et sa `ChargingInfo` créée.
```json
{ "chargingInfo": { ... } }
```
---
### `NymeaEnergy.ChargingInfoRemoved`
Émis quand une borne est supprimée.
```json
{ "evChargerThingId": "uuid-de-la-borne" }
```
---
### `NymeaEnergy.ChargingInfoChanged`
Émis à chaque modification de la `ChargingInfo` (config ou état).
```json
{ "chargingInfo": { ... } }
```
---
### `NymeaEnergy.ChargingSchedulesChanged`
Émis à chaque recalcul du planning (cycle ~1 min).
```json
{ "chargingSchedules": [ ... ] }
```
---
### `NymeaEnergy.SpotMarketConfigurationChanged`
Émis quand le provider actif, l'état enabled ou l'état available change.
```json
{
"enabled": true,
"available": true,
"o:providerId": "5196b3cc-b2ee-46d6-b63a-7af2cf70ba67"
}
```
---
### `NymeaEnergy.SpotMarketStatusChanged`
Émis quand `enabled` ou `available` change (sans les détails du provider).
```json
{ "enabled": true, "available": true }
```
---
### `NymeaEnergy.SpotMarketScoreEntriesChanged`
Émis quand les cotations sont mises à jour par le provider.
```json
{ "spotMarketScoreEntries": [ ... ] }
```
---
## Interfaces nymea consommées
Le plugin détecte les appareils **par interface**, jamais par ThingClassId.
| Interface | États lus | Actions envoyées |
|---|---|---|
| `evcharger` | `chargingEnabled`, `maxChargingCurrent`, `pluggedIn`, `charging`, `currentPhaseA/B/C`, `currentPowerPhaseA/B/C` | `setChargingEnabled`, `setMaxChargingCurrent` |
| `electricvehicle` | `batteryLevel`, `maxChargingCurrent`, `capacity` | — |
| `rootmeter` / `energymeter` | `currentPowerPhaseA/B/C`, `currentPhaseA/B/C` | — |
| `energystorage` | `currentPower`, `batteryLevel` | — |
**Déclencheur du cycle :** signal `PowerBalanceEntryAdded` de `nymea-experience-plugin-energy` (~1 min).
---
## Notes d'intégration
- Les timestamps sont des `QDateTime` sérialisés ISO 8601 avec timezone.
- 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.
- Le plugin fonctionne sans `powersync-optimizer` (mode Community, dégradé proprement).