18 KiB
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 :
NymeaEnergyVersions enregistrées : 0–8 (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 :
{ "phasePowerLimit": 25 }
0signifie 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 :
{ "phasePowerLimit": 25 }
Returns :
{ "energyError": "EnergyErrorNoError" }
Paramètres de recharge
NymeaEnergy.GetAcquisitionTolerance
Retourne le seuil de surplus nécessaire pour démarrer une recharge Eco.
Params : aucun
Returns :
{ "acquisitionTolerance": 0.5 }
Valeur entre 0.0 et 1.0. Plus la valeur est haute, plus il faut de surplus.
NymeaEnergy.SetAcquisitionTolerance
Params :
{ "acquisitionTolerance": 0.5 }
Returns :
{ "energyError": "EnergyErrorNoError" }
Retourne
EnergyErrorInvalidParametersi 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 :
{ "batteryLevelConsideration": 0.9 }
0.0 = stockage ignoré, 1.0 = surplus réduit intégralement de la puissance de charge batterie.
NymeaEnergy.SetBatteryLevelConsideration
Params :
{ "batteryLevelConsideration": 0.9 }
Returns :
{ "energyError": "EnergyErrorNoError" }
Retourne
EnergyErrorInvalidParametersi 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 :
{ "lockOnUnplug": false }
NymeaEnergy.SetLockOnUnplug
Params :
{ "lockOnUnplug": true }
Returns :
{ "energyError": "EnergyErrorNoError" }
Configuration EV
NymeaEnergy.GetChargingInfos
Retourne la configuration de recharge de toutes les bornes, ou d'une seule.
Params :
{ "o:evChargerId": "uuid-de-la-borne" }
Returns :
{
"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 :
{
"chargingInfo": {
"evChargerId": "uuid-de-la-borne",
"chargingMode": "ChargingModeEcoWithTargetTime",
"endDateTime": "2025-06-15T08:00:00+02:00",
"targetPercentage": 80
}
}
Returns :
{ "energyError": "EnergyErrorNoError" }
NymeaEnergy.GetChargingSchedules
Retourne le planning de recharge calculé (toutes les bornes, horizon ~24h).
Params : aucun
Returns :
{
"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 :
{
"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 :
{
"enabled": true,
"available": true,
"o:providerId": "5196b3cc-b2ee-46d6-b63a-7af2cf70ba67"
}
providerIdest absent sienabledestfalse.
NymeaEnergy.SetSpotMarketConfiguration
Active ou désactive le spot market et sélectionne le provider.
Params :
{
"enabled": true,
"o:providerId": "5196b3cc-b2ee-46d6-b63a-7af2cf70ba67"
}
Si
enabled: true,providerIdest obligatoire et doit être un UUID valide.
Returns :
{ "energyError": "EnergyErrorNoError" }
Retourne
EnergyErrorInvalidParametersienabled: truesansproviderId, ouproviderIdinconnu.
NymeaEnergy.GetSpotMarketScoreEntries
Retourne les cotations pondérées du provider actif. Liste vide si désactivé ou non disponible.
Params : aucun
Returns :
{
"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
{ "phasePowerLimit": 25 }
NymeaEnergy.AcquisitionToleranceChanged
{ "acquisitionTolerance": 0.5 }
NymeaEnergy.BatteryLevelConsiderationChanged
{ "batteryLevelConsideration": 0.9 }
NymeaEnergy.LockOnUnplugChanged
{ "lockOnUnplug": true }
NymeaEnergy.ChargingInfoAdded
Émis quand une nouvelle borne est détectée et sa ChargingInfo créée.
{ "chargingInfo": { ... } }
NymeaEnergy.ChargingInfoRemoved
Émis quand une borne est supprimée.
{ "evChargerThingId": "uuid-de-la-borne" }
NymeaEnergy.ChargingInfoChanged
Émis à chaque modification de la ChargingInfo (config ou état).
{ "chargingInfo": { ... } }
NymeaEnergy.ChargingSchedulesChanged
Émis à chaque recalcul du planning (cycle ~1 min).
{ "chargingSchedules": [ ... ] }
NymeaEnergy.SpotMarketConfigurationChanged
Émis quand le provider actif, l'état enabled ou l'état available change.
{
"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).
{ "enabled": true, "available": true }
NymeaEnergy.SpotMarketScoreEntriesChanged
Émis quand les cotations sont mises à jour par le provider.
{ "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, minChargingCurrent, phaseCount |
— |
rootmeter / energymeter |
currentPowerPhaseA/B/C, currentPhaseA/B/C |
— |
energystorage |
currentPower, batteryLevel |
— |
Déclencheur du cycle : signal PowerBalanceEntryAdded de nymea-experience-plugin-energy (~1 min).
Déclencheur overload : signal EnergyManager::powerBalanceChanged (temps réel, découplé du cycle).
EnergyManagerConfiguration
Paramètres de tuning chargés une seule fois au démarrage depuis un fichier JSON.
Pas de setters — un changement nécessite un redémarrage du daemon nymea.
Chemin (ordre de priorité) :
$NYMEA_ENERGY_MANAGER_CONFIG(variable d'environnement)/var/lib/nymea/energy-manager-configuration.json- Valeurs par défaut si aucun fichier trouvé
Format JSON :
{
"chargingEnabledLockDuration": 300,
"chargingCurrentLockDuration": 10,
"minimumScheduleDuration": 15,
"spotMarketChargePredictableEnergyPercentage": 0.5
}
| Paramètre | Défaut | Unité | Rôle |
|---|---|---|---|
chargingEnabledLockDuration |
300 | secondes | Anti-flapping : durée de verrouillage après changement ON/OFF |
chargingCurrentLockDuration |
10 | secondes | Anti-flapping : durée de verrouillage après changement de courant |
minimumScheduleDuration |
15 | minutes | Durée minimale d'un créneau spot market planifié |
spotMarketChargePredictableEnergyPercentage |
0.5 | ratio [0–1] | Fraction de l'énergie spot considérée "prédictible" dans le planning |
Flux interne — SmartChargingManager
Entrées de données
EnergyManager::logs()::powerBalanceEntryAdded (SampleRate1Min)
└─→ update(now) ← cycle principal ~1/min
EnergyManager::powerBalanceChanged ← temps réel
└─→ verifyOverloadProtection(now) ← safety loop immédiate, découplée du cycle
RootMeter (wraps Thing interface=rootmeter/energymeter)
├── currentPower() ← total W (négatif = surplus / export)
├── currentPowerPhaseA/B/C() ← W par phase
└── currentPhaseA/B/C() ← A par phase
ThingManager → interface "energystorage"
├── batteryLevel ← % (moyenne de tous les stockages)
└── currentPower ← W total (+ = charge, − = décharge)
EvCharger → interface "evcharger" + "electricvehicle"
├── currentPower(), maxChargingCurrent(), phaseCount()
├── meteredPhases() ← phases réelles via currentPhaseA/B/C live
└── car: batteryLevel, capacity, minChargingCurrent, phaseCount
Pipeline update() — exécuté à chaque cycle
update(currentDateTime)
│
├─ 1. updateManualSoCsWithoutMeter()
│ Estime le SoC à partir de l'énergie intégrée si pas de compteur sur le VE.
│
├─ 2. prepareInformation()
│ - Filtre les EV chargers actifs (plugged, car assignée, mode ≠ Normal)
│ - Calcule par charger : phases effectives, SoC, temps restant, phaseLimitPower
│ - Reset m_chargingActions à OFF/minCurrent pour les 3 issuers
│
├─ 3. verifyOverloadProtection()
│ - Lit rootMeter->currentPowerPhaseA/B/C()
│ - Si une phase dépasse phasePowerLimit × 230 W → throttle immédiat (issuer=OverloadProtection)
│
├─ 4. verifyOverloadProtectionRecovery()
│ - Ré-active les chargers throttlés si la marge est suffisante
│
├─ 5. planSpotMarketCharging()
│ - SpotMarketManager::scheduleChargingTime() → TimeFrames (créneaux bon marché)
│ - Remplit m_chargingSchedules + m_chargingActions[SpotMarket] = ON
│
├─ 6. planSurplusCharging()
│ - currentLoad = rootMeter->currentPower()
│ + correction batteries (fromBatteries)
│ + puissance ajoutée dans ce cycle (addedPower)
│ - allowanceInAmpere = −currentLoad / 230
│ - Si allowance ≥ minCurrent × acquisitionTolerance → chargingActions[Surplus] = ON
│
└─ 7. adjustEvChargers()
Applique la décision finale par priorité décroissante :
1. TimeRequirement → ON au max courant disponible (deadline imminente)
2. SurplusCharging → ON au courant surplus calculé
3. SpotMarketCharging → ON au courant max dans le créneau
4. EcoWithMinCurrent fallback → ON à 6 A (EcoMinChargingCurrent)
5. Idle → OFF
│
├── executeChargingAction()
│ └─→ Thing::executeAction(setChargingEnabled, setMaxChargingCurrent)
│
├── emit chargingInfoChanged() ← met à jour ChargingState (lu par JSON-RPC)
└── emit chargingSchedulesChanged() ← planning rafraîchi (lu par JSON-RPC)
Persistance des settings utilisateur
| Données | Fichier |
|---|---|
phasePowerLimit, acquisitionTolerance, batteryLevelConsideration |
EnergySettings (QSettings INI, energy.conf) |
ChargingInfo par charger (mode, endDateTime, repeatDays, etc.) |
même EnergySettings, groupe ChargingInfos/ |
lockOnUnplug |
/var/lib/nymea/energy.conf (QSettings séparé) |
SpotMarket enabled, providerId |
EnergySettings (géré par SpotMarketManager) |
Point d'injection pour powersync-optimizer
Le point naturel est entre prepareInformation() et adjustEvChargers().
L'optimizer reçoit les données de contexte (SurplusData) et retourne une ChargingAction qui remplace ou complète les actions calculées localement. Voir PowerSyncClient::requestOptimization() dans etm/.
Notes d'intégration
- Les timestamps sont des
QDateTimesérialisés ISO 8601 avec timezone. - Les puissances sont en Watts, les courants en Ampères.
phasePowerLimitest en Ampères (par phase), pas en Watts.weightingdesScoreEntry: 1.0 = créneau le moins cher, 0.0 = le plus cher.SetChargingInfoest partiel : seuls les champs présents sont appliqués, saufevChargerIdqui est toujours requis.currentPowerdu 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).