# Brief agent — plugin V2C Trydan > Repo : `etm-powersync-plugins-modbus` · Dossier : `v2c/` · Branche : `feature/v2c-trydan` > Borne : 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** : 1. **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). 2. **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 : 1. À 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. 2. Setting de Thing `disableInternalOptimizer` (défaut: demander) : si l'utilisateur accepte, écrire Dynamic=0 + PauseDynamic/DynamicPowerMode cohérents. 3. `decisionReason` cô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 1. Plugin compile (amd64 + cross arm64) et s'intègre au .pro du repo. 2. ThingClass `trydan` expose l'interface `evcharger` complète + states diag (HousePower, PowerFV, SlaveError, Dynamic/conflit). 3. Discovery réseau + setup par IP manuelle fonctionnels. 4. Gestion du conflit Dynamic implémentée (lecture à chaque poll, state, setting). 5. Testé contre simulateur Modbus (registres mockés) — le test sur borne réelle est un jalon séparé, AVANT tout passage en « Supporté ». 6. 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.