6.8 KiB
Brief agent — plugin V2C Trydan
Repo :
etm-powersync-plugins-modbus· Dossier :v2c/· Branche :feature/v2c-trydanBorne : V2C Trydan / Trydan Pro (monophasée·triphasée, ES). Comm locale : Modbus TCP (port 502) + HTTP REST. Statut cible : Partiel (comme Keba) — PAS dans la matrice beta validée. Ne pas promettre tant que non testé sur borne réelle.
RÔLE
Créer le plugin nymea v2c dans etm-powersync-plugins-modbus, sur le modèle des plugins
existants du repo (abbterra pour la structure evcharger Modbus TCP, eastron pour le pattern
registres). ThingClass trydan implémentant l'interface evcharger — c'est elle que le
moteur energy-etm consomme (states chargingEnabled, maxChargingCurrent, pluggedIn,
charging, currentPower ; actions setChargingEnabled, setMaxChargingCurrent).
TRANSPORT — décision d'architecture
Modbus TCP = transport principal (port 502, unit id 1). C'est le bus du repo, l'outillage
(nymea-modbus-cli, libnymea-modbus) existe, et le polling périodique colle au cycle du moteur.
HTTP = complément, deux usages :
- Découverte : la Trydan est en WiFi/LAN, pas de discovery Modbus.
GET /RealTimeData(JSON) sert de probe d'identification pendant le setup (NetworkDeviceDiscovery + test HTTP). - Fallback diagnostic : si un champ manque en Modbus, le compléter par HTTP est permis, mais le chemin de contrôle (pause, intensité) reste Modbus.
Ne PAS implémenter deux ThingClasses (une Modbus, une HTTP) — une seule, transport hybride interne.
CARTE REGISTRES (source : lib officielle V2Charge/Trydan_Modbus_TCP)
Lecture : holding registers, 2 registres par valeur, décodage float 32 bits big-endian (byte ET word order Big). Écriture : write_register simple (uint16).
Lecture (0x0BC2…)
| Reg | Nom | Note |
|---|---|---|
| 0x0BC2 | ChargeState | 0=déconnecté, 1=connecté sans charge, 2=en charge (à confirmer sur borne) |
| 0x0BC3 | ChargePower | W |
| 0x0BC4 | ChargeEnergy | kWh session |
| 0x0BC5 | SlaveError | code erreur |
| 0x0BC6 | ChargeTime | s |
| 0x0BC7 | ValuePWM | duty CP |
| 0x0BC8 | HousePower | W — pince CT maison (si installée) |
| 0x0BC9 | PowerFV | W — production PV vue par la borne (si configurée) |
| 0x0BCA | PauseState | |
| 0x0BCB | Lock | |
| 0x0BCC | Program(Promgram) | |
| 0x0BCD | Intensity | A courante |
| 0x0BCE | Dynamic | mode dynamique V2C on/off |
| 0x0BCF | Payment | |
| 0x0BD0 | OCPP | |
| 0x0BD1 | MinIntensity | A |
| 0x0BD2 | MaxIntensity | A |
| 0x0BD3 | PauseDynamic | |
| 0x0BD4 | DynamicPowerMode | |
| 0x0BD5 | ContractedPower | W |
Écriture (0x177A…)
| Reg | Nom | Usage HEMS |
|---|---|---|
| 0x177A | PauseState | setChargingEnabled (pause=1 → désactivé) |
| 0x177B | Lock | verrouillage |
| 0x177C | Program | timer interne — ne pas utiliser (conflit moteur) |
| 0x177D | Intensity | setMaxChargingCurrent (A) |
| 0x177E | Dynamic | voir CONFLIT ci-dessous |
| 0x177F | Payment | hors scope |
| 0x1780 | OCPP | hors scope |
| 0x1781 | MinIntensity | borne basse (6 A) |
| 0x1782 | MaxIntensity | borne haute (bug historique V2C corrigé upstream — vérifier firmware) |
| 0x1783 | PauseDynamic | voir CONFLIT |
| 0x1784 | DynamicPowerMode | voir CONFLIT |
| 0x1785 | ContractedPower | protection abonnement interne borne |
Vérifier la carte contre la feuille officielle V2C (lien dans le README du repo V2Charge/Trydan_Modbus_TCP, gid=0) avant d'écrire les paramRegisters JSON.
⚠️ CONFLIT D'OPTIMISEURS — le piège central de cette borne
La Trydan embarque SON PROPRE pilotage solaire (« Dynamic », pince CT + lecture onduleur, PID interne). Deux cerveaux ne doivent pas piloter la même borne :
- Dynamic V2C ACTIF (0x0BCE=1) → la borne s'autopilote au surplus ; toute écriture Intensity du moteur sera combattue par le PID interne. Oscillations garanties.
- Mode HEMS (le nôtre) → exiger Dynamic=0 ; le moteur energy-etm décide, la borne obéit.
Comportement du plugin :
- À l'init, LIRE 0x0BCE. Si Dynamic=1, exposer un state
conflictDetected(ou équivalent) et logger un avertissement explicite — ne PAS désactiver silencieusement le mode du client. - Setting de Thing
disableInternalOptimizer(défaut: demander) : si l'utilisateur accepte, écrire Dynamic=0 + PauseDynamic/DynamicPowerMode cohérents. decisionReasoncôté moteur doit pouvoir refléter « borne en autopilotage V2C — pilotage HEMS suspendu » si Dynamic revient à 1 (l'app V2C du client peut le réactiver à tout moment → re-lire à chaque poll, pas seulement à l'init).
C'est le même problème que la PV-Edition Keba : une borne « intelligente » à neutraliser proprement pour que l'arbitrage central reste l'unique décideur.
SÉCURITÉ / ROBUSTESSE
- Anti-flapping : respecter les verrous du moteur (chargingEnabledLockDuration etc.) — le plugin n'introduit PAS sa propre cadence d'écriture ; il applique ce que le moteur envoie.
- Connexion Modbus perdue → states
connected=false, pas de retry agressif (backoff). - Écritures idempotentes : ne réécrire Intensity que si la valeur cible change réellement (la borne journalise chaque write ; éviter l'usure flash et le spam).
- Min 6 A (IEC 61851). Clamper toute consigne < 6 A à pause plutôt qu'à une valeur illégale.
- Float decode : 2 registres, Big/Big. NE PAS supposer du uint16 sur les lectures.
INTERDIT
- Toucher aux plugins publiés du repo (eastron, abbb2x, abbterra, waveshare-relay-d8).
- Promettre la borne dans la doc/matrice beta (statut Partiel, non testé matériel).
- Dépendance à un service privé ETM — plugin 100% GPL, parle à la borne en direct.
- Implémenter OCPP/Payment/RFID — hors scope HEMS.
DEFINITION OF DONE
- Plugin compile (amd64 + cross arm64) et s'intègre au .pro du repo.
- ThingClass
trydanexpose l'interfaceevchargercomplète + states diag (HousePower, PowerFV, SlaveError, Dynamic/conflit). - Discovery réseau + setup par IP manuelle fonctionnels.
- Gestion du conflit Dynamic implémentée (lecture à chaque poll, state, setting).
- Testé contre simulateur Modbus (registres mockés) — le test sur borne réelle est un jalon séparé, AVANT tout passage en « Supporté ».
- Entrée PORTING_STATUS_modbus.md : statut Partiel, source de la carte registres notée.
RÉFÉRENCES
- Lib officielle : github.com/V2Charge/Trydan_Modbus_TCP (carte registres + décodage float)
- API HTTP : feuille V2C (gid=1147522182) + github.com/V2Charge/API-doc-v2c — à vérifier, endpoints probables /RealTimeData (lecture JSON) et /write/=
- Dans le repo : abbterra (structure evcharger Modbus TCP), PORTING_STATUS_modbus.md
- Firmware : les updates V2C mentionnent des fixes Modbus (Max/MinIntensity) — documenter la version firmware minimale constatée lors du test réel.