Patrick Schurig 122df17a98 docs(sunspec): écrire la dépendance à l'ordre de lecture des SF là où elle porte
Le relevé du 2026-08-26 a montré DCW_SF passant de -2 à -1 entre une batterie à
l'arrêt et une batterie en charge, sur le même onduleur, à quelques secondes
d'intervalle. Un DCW brut de 20000 vaut 200,0 W avec le premier facteur et
2000,0 W avec le second.

Ce que ça casserait est de la même famille que d08cf50 mais plus discret : pas
de dénormal, pas d'erreur Modbus, un appareil qui se déclare connected, et une
puissance simplement dix fois fausse. La propriété tient aujourd'hui parce que
libnymea-sunspec lit les 90 registres du modèle 160 en une transaction et relit
les facteurs du bloc fixe AVANT les blocs répétés — deux propriétés qui vivent
en amont, que rien dans le compilateur ne tient, et qu'une optimisation de la
lecture ferait sauter sans aucun signe extérieur.

Le commentaire est donc à l'endroit qui en dépend : au-dessus de
storageModuleReadings(), qui consomme dcPower(), avec un pointeur au site de
readBlockData() et sur le champ ModuleReading::dcPower.

Le README documente en outre le côté exploitation de D-9 : un onduleur qui
publie le 124 sans le 160 porte energystorage avec un currentPower figé à zéro,
avec les deux lignes de journal exactes à chercher et la commande pour les
trouver.
2026-08-26 15:45:40 +02:00

85 lines
3.0 KiB
Markdown

# SunSpec
Connect nymea to SunSpec devices over Modbus TCP
## Supported Things
* SunSpec Inverter
* Model ID 101 & 111 Single phase inverter
* Model ID 102 & 112 Split phase inverter
* Model ID 103 & 113 Three phase inverter
* SunSpec Meter
* Model ID 201 & 211 Single phase meter
* Model ID 202 & 212 Split phase meter
* Model ID 203 & 213 Three phase meter
* SunSpec Storage
* Model ID 124 (state of charge, status, setpoints)
* Model ID 160 (instantaneous power, `StCha` / `StDisCha` blocks)
* Model ID 120 (rated capacity, `WHRtg`)
## Tested connections
* SolarEdge (with custom battery)
## Requirements
* The package 'nymea-plugin-sunspec' must be installed.
* The SunSpec device must support SunSpec over modbus TCP
## More
https://sunspec.org
---
## Exploitation — batterie visible mais non mesurable
Depuis `1.15.2+etm10`, la thingClass `SunSpec Storage` déclare l'interface
**`energystorage`**. C'est ce qui la rend visible au bilan de puissance de nymea
(`currentPowerStorage`), à la réserve de recharge du véhicule, et à la réserve du
waterfall. Avant, elle ne déclarait que `battery` et **aucun des trois ne la
trouvait**.
L'état `currentPower` se lit dans le **modèle 160**, pas dans le modèle 124 qui
n'a aucun registre de puissance. Conséquence à connaître avant de diagnostiquer
une batterie « à zéro » :
> **Un onduleur SunSpec qui publie le modèle 124 sans modèle 160 porte
> l'interface `energystorage` avec un `currentPower` qui ne bougera jamais de
> zéro.** C'est le cas des appareils SunSpec génériques. La batterie apparaît
> alors dans le bilan, comptée pour 0 W — ce qui se lit « ni charge ni
> décharge », et non « je ne sais pas ».
Ce cas est **annoncé une fois par thing** dans le journal de `nymead`, au
démarrage ou au premier relevé qui suit la découverte. Deux formulations, selon
la cause :
```
W | SunSpec: Storage "<nom>" has no model 160 on its connection: currentPower
has no register to read and will stay at 0. This storage is visible to the
energy balance but not measurable.
W | SunSpec: Storage "<nom>" has a model 160 but no StCha/StDisCha block:
currentPower has nothing to read and will stay at 0.
```
La seconde forme est le cas d'un onduleur hybride **sans batterie câblée** : il
publie `N = 2` (les deux strings PV) et aucun bloc batterie.
À vérifier en premier sur un site où `currentPowerStorage` reste à zéro :
```bash
journalctl -u nymead | grep -i "will stay at 0"
```
Si la ligne est là, le défaut est dans ce que l'appareil publie, pas dans nymea.
Si elle est absente, la batterie est mesurée et le zéro est une vraie mesure.
L'état `capacity` (kWh) vient de `WHRtg` du modèle 120. Quand la plaque
signalétique ne l'implémente pas, l'état est **laissé tel quel** plutôt que remis
à zéro : un zéro se lirait comme une mesure. Aucune règle du moteur ne lit
`capacity` à ce jour.
Détail du raisonnement, de la mesure du signe et de l'écart assumé :
`DIVERGENCES.md`, entrée **D-9**.