The Trydan ESP32 WiFi stack saturates under nymea's periodic ICMP pings
(observed: latency > 14 s, Modbus timeouts, charger drops off).
Changes:
- NetworkDeviceMonitor removed entirely from setupThing() and thingRemoved().
The charger is expected to have a DHCP-reserved IP (documented in code).
Address comes from trydanThingAddressParamTypeId param — already the correct
path after the previous setup fix.
- Connectivity now derives from Modbus poll success/failure only (reachable()
from TrydanModbusTcpMaster), NOT from network ping. A ping response does
not imply Modbus usability on this hardware.
- postSetupThing() timer (30 s): if not reachable, calls connectDevice() for
reconnect; if reachable, calls update(). The 30 s period IS the backoff —
no aggressive retry loop.
- Modbus timeout: 2 s → 5 s (tolerates residual WiFi latency spikes).
- Modbus retries per read: 1 → 0 (abort fast on first timeout; full poll
sequence already aborts at first error via doNextRead).
- k_errorLimit: 5 → 3 (3 × 5 s = 15 s before marking unreachable).
- New state "statusMessage" (QString): set on disconnect with timestamp +
cause ("timeout Modbus — vérifier signal WiFi de la borne"); cleared on
successful poll. Visible in nymea-app; helps SAV without SSH access.
- "networkdevice" removed from JSON interfaces (contract broken without monitor).
Invariants preserved: Big/Big float32 decode, no block read, PauseState+Lock
mirror, PauseDynamic conflict management, writeCompleted address filtering.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
60 lines
4.0 KiB
Markdown
60 lines
4.0 KiB
Markdown
## v2c / trydan — V2C Trydan (e-charger)
|
|
|
|
**Statut : Partiel** — validé partiellement sur borne réelle, PAS encore « Supporté ».
|
|
Ne pas promettre dans la matrice beta tant que le test « VE branché » n'est pas bouclé.
|
|
|
|
| Champ | Valeur |
|
|
|---|---|
|
|
| Plugin | `powersync-plugin-v2c` (création ETM, pas un fork) |
|
|
| Interface | `evcharger` |
|
|
| Transport validé | **Modbus TCP** (port 502, unit id 1) |
|
|
| Fallback / discovery | HTTP REST (`/RealTimeData`, `/write/<param>=<val>`) |
|
|
| Borne de test | V2C Trydan, IP 192.168.1.127 |
|
|
| Firmware testé | **2.4.6** |
|
|
| Date | 2026-06-12 |
|
|
|
|
### Sources de la carte registres
|
|
- Lib officielle V2C : `github.com/V2Charge/Trydan_Modbus_TCP` (`src/v2ctrydan/modbus.py`).
|
|
- Feuille officielle « V2C - Datamanager Modbus TCP & RTU » (gid=0).
|
|
- Référence comportementale : evcc `charger/trydan.go` (HTTP) — logique enable/PauseDynamic.
|
|
|
|
### Validé sur borne réelle (192.168.1.127, fw 2.4.6)
|
|
- **Transport Modbus TCP** : répond proprement (0 timeout) une fois le lien WiFi désaturé.
|
|
- **Décodage float Big/Big** confirmé : MaxIntensity (0x0BD2/3026) lu = 20.0.
|
|
Vérif registre brut : 3026 = 16800 = 0x41A0 → float32 0x41A00000 = 20.0. Little-endian = garbage.
|
|
- **Gestion conflit Dynamic** confirmée (cœur du plugin) :
|
|
- Dynamic=1 → toute consigne Intensity est écrasée par le PID interne (consigne 10 → relue 0).
|
|
- Écriture PauseDynamic=1 → la consigne Intensity=10 **tient** (relue 10, Dynamic=0, PauseDynamic=1).
|
|
- Écriture PauseDynamic=0 → optimiseur interne rendu au client.
|
|
- `Dynamic` observé basculant seul 0→1→0 pendant la session → **relecture à chaque poll obligatoire** (confirmé empiriquement, pas seulement à l'init).
|
|
- **ChargeState** 0/1/2 = A/B/C : cohérent (0 = déconnecté observé borne au repos).
|
|
- **SlaveError** : valait 4 le matin (VE branché), repassé à 0 borne au repos → code 4 probablement
|
|
lié à l'état de charge, pas un défaut permanent. À confirmer.
|
|
|
|
### RESTE À VALIDER (jalon « VE branché »)
|
|
- **setMaxChargingCurrent régule la charge réelle** (pas seulement le registre). Sans VE, la borne
|
|
garde Intensity=0 même consigne acceptée → test impossible borne au repos.
|
|
- Comportement de `chargingEnabled` (PauseState/Lock en miroir) sous charge active.
|
|
- `ChargePower` / `currentPower` non-nul à confirmer pendant une charge.
|
|
- `sessionEnergy` (ChargeEnergy 0x0BC4) : NE PAS exposer tant que monotonie/reset non vérifiés
|
|
(cf. evcc issue #28047, ChargeRater retiré pour fiabilité firmware).
|
|
|
|
### LIMITATIONS MATÉRIELLES IMPORTANTES (à documenter pour l'installation client)
|
|
1. **WiFi sature si le cloud V2C / l'app reste actif.** Latence observée : 14 000 ms et 100% perte
|
|
avec app/cloud actifs → 0 timeout possible. Après fermeture app + déconnexion cloud : 20-143 ms,
|
|
0% perte, exploitable. **Conséquence prod : le plugin doit être le seul maître à parler à la
|
|
borne ; déconnecter la borne du cloud V2C en installation HEMS, ou timeouts généreux (≥2-3 s)
|
|
et poll espacé.** Lien radio lui-même bon (5 ms au mieux) — c'est la saturation ESP32, pas le signal.
|
|
2. **RS485 non exploitable comme transport HEMS sur ce modèle.** Le port RS485 (RJ45, pin 4=B-,
|
|
pin 5=A+) est réservé par V2C au rôle « Modbus Feeder / lecture compteur PV » pour la fonction
|
|
Dynamic (mode maître). Aucune réponse esclave obtenue sur le bus partagé (testé IDs 1/2/3 @ 9600
|
|
et 19200, 100% timeout). Le mode « commande à distance » esclave passe par TCP, pas par le RS485
|
|
physique. **→ Étape 2 (RTU) du plugin non applicable à cette borne.** Le RS485 reste pertinent
|
|
pour d'autres bornes du catalogue, pas pour la Trydan.
|
|
|
|
### Notes plugin
|
|
- Clamp courant : doit lire **MaxIntensity de la borne** (= 20 ici), PAS une constante 32 en dur
|
|
(le `qBound(6, val, 32)` actuel est à corriger — la borne plafonne à 20). [À FIXER]
|
|
- Lectures : transactions individuelles de 2 registres, float Big/Big, pas de block read.
|
|
- Logique enable : `chargingEnabled = (PauseState==0 ET Lock==0)`, écritures en miroir.
|