🔧
Manuel installateur
RĂ©vision 1 — Avril 2026 ← Retour au tableau de bord

Manuel installateur SCADA V18

Ce manuel s'adresse aux installateurs et techniciens qui mettent en service, configurent et maintiennent une installation SCADA V18. Pour l'utilisation quotidienne par les opérateurs, voir le manuel utilisateur.

1. Architecture V18

Capteurs / Actionneurs (4-20 mA, TOR, vannes, pompes)
   │ cñblage physique
   ▌
Cartes I/O Beckhoff BK9000 (coupleurs Modbus TCP + modules KL)
   │ Modbus TCP (switch ethernet)
   ▌
Mini PC industriel Linux (IPC)
   ├── Runtime (G1)  — boucle asyncio, pymodbus, port 8765
   └── Serveur (G2)  — FastAPI + WebSockets, port 8000
   │ HTTP + HTTPS (Tailscale)
   ▌
Clients navigateur / PWA mobile

Points clés V18 :

  • Pas d'OpenPLC — le runtime Python parle directement Modbus TCP aux coupleurs
  • Deux process sĂ©parĂ©s : Runtime (G1) + Serveur (G2) — communicants via WebSocket interne
  • Deux bases SQLite : scada_v18.db (runtime, donnĂ©es live + historique) et serre.db cĂŽtĂ© serveur (config, bureaux, alarmes, courbes)
  • Mode WAL activĂ© sur les 2 bases — lecteurs/Ă©crivains concurrents
  • Frontend JS vanilla (pas de framework), widgets autonomes

Adresses Modbus

Les adresses Modbus de chaque canal sont calculĂ©es automatiquement selon la position physique des modules KL sur le rail Beckhoff. Vous n'avez pas Ă  les saisir manuellement — il suffit de dĂ©clarer les modules dans le bon ordre.

2. AccĂšs super utilisateur

Le panneau d'administration n'est pas accessible via un menu visible. Il faut entrer la combinaison clavier :

Ctrl + Alt + 2 + 2

Ce panneau contient les onglets :

OngletContenu
⚙ GĂ©nĂ©ralConfiguration IA (provider + clĂ©)
đŸ§© WidgetsActiver/dĂ©sactiver les widgets dans le menu d'ajout
🔌 Runtime (G1)Statut runtime, cycle, chemin DB
🌐 Serveur (G2)Statut serveur, port, clients connectĂ©s, taille DB
🔧 Config matĂ©rielArmoires, coupleurs, modules KL, attribution canaux, wizard installation, fonctionnalitĂ©s
🔑 LicenceÉtat licence, renouvellement, import token
đŸŽ« SupportSoumettre un ticket revendeur
🔒 VPNConfiguration Tailscale (super utilisateur)
Toutes les actions de ce panneau peuvent affecter le fonctionnement de l'installation. Vérifiez les modifications avant de cliquer sur Appliquer.

3. Premier déploiement

IPC neuf (Debian 13)

Un script setup_ipc.sh automatise toute l'installation sur un IPC vierge :

git clone https://github.com/Fkruger22/serre-v17-openplc.git /opt/scada
cd /opt/scada/v18
sudo bash setup_ipc.sh

Le script installe :

  • Python 3.11 + dĂ©pendances (FastAPI, pymodbus 3.x, aiosqlite, pywebpush
)
  • Service systemd scada-runtime (G1) + scada-serveur (G2)
  • Certificats VAPID pour Web Push
  • Permissions sudo restreintes pour Tailscale

Mise Ă  jour depuis Windows (poste dev)

Depuis le PC de développement Windows :

cd f:\scada+plc
bash deploy_v18.sh

Le script effectue : push GitHub → pull IPC → restart services → vĂ©rification statut.

4. Coupleurs Beckhoff BK9000

Le SCADA V18 communique avec des coupleurs Beckhoff BK9000 en Modbus TCP. Chaque coupleur supporte jusqu'à 64 modules KL (entrées/sorties).

Configuration du coupleur

  • Adresse IP fixe Ă  attribuer (ex: 192.168.1.3)
  • Port Modbus TCP : 502 (par dĂ©faut)
  • Unit ID : 0 (par dĂ©faut)
  • Mode compact : pas de bits de statut dans le registre de donnĂ©es
  • DĂ©tection fil coupĂ© : valeur > 32767 (bit de signe)
  • Registre statut : 0x100C — K-bus, configuration, watchdog
  • Plage AI : 0–32767 (mode compact)

Watchdog

Configurez le watchdog Beckhoff sur chaque coupleur. Si le runtime SCADA plante ou se dĂ©connecte plus de N secondes, le coupleur coupe ses sorties — sĂ©curitĂ© critique pour les actionneurs.

5. Armoires & coupleurs

Onglet armoires

Ctrl+Alt+22 → Config matĂ©riel → Armoires

Une armoire regroupe un ou plusieurs coupleurs Modbus. Elle correspond physiquement à une armoire électrique de la serre.

Créer une armoire

  1. Onglet Config matĂ©riel → bouton  Armoire
  2. Saisissez le nom (ex: Armoire 1) et une description
  3. L'armoire apparaĂźt dans l'arborescence

Ajouter un coupleur Modbus

  1. SĂ©lectionnez l'armoire → bouton  Coupleur
  2. Saisissez l'IP (ex: 192.168.1.3) et le port (502 par défaut)
  3. Le runtime tente la connexion — pastille verte si OK, rouge si timeout

Insertion entre coupleurs

Glissez-déposez un coupleur entre deux séparateurs animés pour l'insérer à une position précise. L'ordre dans l'arborescence reflÚte l'organisation physique du rail.

6. Modules KL

Drag & drop modules KL

Catalogue KL replié + zone de drop entre séparateurs

Les modules KL Beckhoff sont les briques d'I/O insérées sur le rail à cÎté du coupleur. Le SCADA fournit un catalogue intégré.

Catalogue intégré

RéférenceTypeCanauxFC Modbus
KL1104DI (entrée digitale)4FC02
KL1408DI8FC02
KL1809DI16FC02
KL2404DO (sortie digitale)4FC01
KL2408DO8FC01
KL2809DO16FC01
KL3054 / 3404 / 3458 / 3468AI 4-20mA / 0-10V4-8FC04
KL3202 / 3204AI PT1002-4FC04
KL3312AI Thermocouple2FC04
KL4404 / 4408AO 4-20mA / 0-10V4-8FC03

Pour ajouter un nouveau modÚle non listé, modifier v18/runtime/kl_library.py.

Ajouter un module Ă  un coupleur

  1. Cliquez sur un coupleur dans l'arborescence — la zone modules s'affiche à droite
  2. Le catalogue KL est repliĂ© par dĂ©faut — cliquez pour dĂ©plier les sections (DI / DO / AI / AO)
  3. Glissez la référence souhaitée vers la zone de drop entre les séparateurs animés
  4. Le module est inséré à la position voulue, les adresses Modbus sont recalculées automatiquement

Suppression

Survolez un module → bouton ✕ rouge avec hover. Si le module a des canaux cĂąblĂ©s Ă  des variables, un message dĂ©taillĂ© liste les variables impactĂ©es avant la suppression.

7. Attribution canaux

Attribution canaux

Attribution variable physique ↔ canal Modbus

Une fois les modules KL déclarés, il faut cùbler logiquement chaque variable physique de l'installation à un canal Modbus.

Workflow

  1. Créez d'abord l'arborescence des équipements via le wizard d'installation
  2. Onglet Config matĂ©riel → Attribution canaux
  3. Liste de gauche : variables physiques de l'installation (sondes, sorties, contacts) — non cĂąblĂ©es en haut, cĂąblĂ©es en bas
  4. Liste de droite : canaux disponibles, groupés par module KL
  5. Glissez une variable de gauche sur un canal de droite
  6. Pour les analogiques (AI/AO) : configurez le scaling (raw_min/raw_max → val_min/val_max) + filtre Ă©ventuel
  7. Pour les digitaux (DI/DO) : pas de scaling, juste l'attribution

Scaling des entrées/sorties analogiques

val_physique = val_min + (raw - raw_min) × (val_max - val_min) / (raw_max - raw_min)

Exemple : sonde 4-20mA mesurant 0-50°C →

  • raw_min = 0, raw_max = 32767 (pleine Ă©chelle BK9000 mode compact)
  • val_min = -10, val_max = 60 (selon la sonde)
  • Le runtime applique automatiquement la conversion Ă  chaque cycle

Filtres

Filtres disponibles par variable (configurables dans Attribution canaux) : moyenne mobile, médiane, butterworth, plage de validité.

Les variables physiques non cĂąblĂ©es ne sont pas exposĂ©es au runtime — elles n'apparaissent pas dans le snapshot WebSocket. Cela Ă©vite les variables fantĂŽmes qui gĂ©nĂ©reraient de fausses alarmes.

8. Wizard installation — Étape 1 : Domaines

Wizard étape 1

Wizard installation — sĂ©lection des domaines

Le wizard d'installation crĂ©e l'arborescence des Ă©quipements logiques. Accessible depuis Config matĂ©riel → bouton Nouvelle installation ou Modifier installation.

Sélection des domaines

Cochez les domaines présents dans votre serre :

  • đŸŒ€ïž MĂ©tĂ©o — station mĂ©tĂ©o
  • đŸŒĄïž Climat — compartiments
  • đŸ”„ Énergie — chaudiĂšres, ballons stratifiĂ©s, collecteurs chaleur/CO₂
  • 💧 Irrigation — stations, groupes, vannes, rĂ©servoirs
  • ⚙ SystĂšme — gestionnaire alarmes, coupleurs (auto)

Décocher un domaine purge ses quantités et son arbre des étapes suivantes.

9. Wizard — Étape 2 : QuantitĂ©s

Pour chaque domaine activé, saisissez le nombre d'équipements de chaque type :

  • Climat : nombre de compartiments
  • Énergie : nombre de chaudiĂšres, ballons, collecteurs
  • Irrigation : nombre de stations d'irrigation, rĂ©servoirs eau claire/drainage
  • MĂ©tĂ©o : 0 ou 1 station

Les quantités sont utilisées à l'étape suivante pour générer l'arborescence par défaut.

10. Wizard — Étape 3 : Arborescence

Wizard étape 3

Arborescence éditable des équipements

L'arbre des équipements est généré automatiquement à partir des quantités. Vous pouvez :

  • Renommer chaque Ă©quipement (clic sur le nom)
  • Ajouter des enfants optionnels (briques) — ex: ajouter une 2ᔉ sonde temperature Ă  un compartiment
  • Supprimer un Ă©quipement non obligatoire (✕)
  • CĂŽtĂ© ouvrant : sĂ©lectionner Gauche / Droite (alterne par dĂ©faut)

Auto-nommage

Les noms par défaut sont générés selon la position dans la fratrie : "Compartiment 1", "Compartiment 2"
 Le flag nom_auto=1 en DB indique qu'un nom est auto-généré et donc retraduisible quand la langue change. Renommer manuellement bascule en nom_auto=0 (nom figé).

Enfants obligatoires

Le catalogue dĂ©clare des enfants obligatoires (ex: chaudiĂšre → 1 brĂ»leur). Ces enfants sont créés automatiquement et marquĂ©s obligatoires (couleur bleue, pas de bouton ✕).

11. Wizard — Étape 4 : Liens

Wizard étape 4

DĂ©finition des liens entre Ă©quipements (chaleur, CO₂)

Les liens définissent les relations entre équipements de domaines différents. Deux types :

Chaleur (rĂšgle stricte)

Chaque collecteur chaleur doit recevoir des chaudiÚres/ballons et alimenter des circuits HT/BT. Exclusivité : une chaudiÚre ne peut alimenter qu'un seul collecteur. Les chaudiÚres/ballons/circuits non assignés sont grisés et bloquants.

CO₂ (rùgle souple)

  • Chaque vanne CO₂ doit ĂȘtre attribuĂ©e Ă  un collecteur CO₂
  • Chaque collecteur CO₂ doit avoir au moins une source (chaudiĂšre fumĂ©es OU source CO₂ liquide)
  • Pas d'exclusivitĂ© sur les sources — une chaudiĂšre peut alimenter plusieurs collecteurs CO₂
Le bouton Suivant est bloqué tant que les rÚgles strictes ne sont pas satisfaites. Les warnings sont affichés en haut de l'étape.

12. Wizard — Étape 5 : Validation

Récapitulatif de l'installation avant application :

  • Nombre d'Ă©quipements par domaine
  • Liens chaleur / CO₂ Ă©tablis
  • Variables physiques Ă  cĂąbler ensuite via Attribution canaux

Cliquez sur Appliquer au runtime :

  1. Le serveur valide la cohérence (enfants obligatoires, liens, variables physiques cablees)
  2. Les équipements sont insérés en DB
  3. Le runtime est rechargé (lit la nouvelle config sans redémarrer le process)
  4. Vous repassez à l'étape Attribution canaux pour cùbler les variables physiques
Modifier l'installation peut perdre des historiques si vous supprimez des équipements. Sauvegardez la config avant via Export config.

13. Domaine Météo

Une seule station météo par installation. Variables physiques :

  • Sondes : temperature, humidite, rayonnement (W/mÂČ), vitesse_vent, direction_vent
  • Capteur de pluie (DI)
  • Optionnel : co2_ext

Variables calculées

  • sunrise_min / sunset_min — calculĂ©es par calculer_soleil selon date + latitude
  • rayonnement_cumul — intĂ©grale journaliĂšre (MJ)
  • securite_vent, securite_pluie, securite_gel — flags pilotĂ©s par controler_meteo_securite

14. Domaine Climat

Compartiments — la chaüne de chauffage est : compartiment → circuit HT/BT → collecteur → chaudiùre.

Briques sous compartiment

  • sonde_temperature (1 ou plus — rĂ©gulation + contrĂŽle dĂ©rive)
  • sonde_humidite
  • sonde_co2
  • moteur Ă©cran thermique / ombrage
  • vanne_co2
  • brumisateur, deshumidificateur, eclairage (sorties)
  • ouvrant (cĂŽtĂ© gauche / droit, mode coefficient ou limitation vitesse vent)

Fonctionnalités activables

Onglet Fonctionnalités du compartiment :

  • Chauffage (intrinsĂšque) — PID + bornes chauffage_kp/ki/kd
  • AĂ©ration — PID
  • HumiditĂ© — brumisation et dĂ©shumidification
  • CO₂ — enrichissement
  • Écran — Ă©nergĂ©tique nuit + ombrage jour selon rayonnement
  • Éclairage — DLI cible
  • Ouvrant vent / abritĂ© — sĂ©curitĂ© vent + bornes ouverture min/max par cĂŽtĂ©
Les fonctionnalitĂ©s sont filtrĂ©es par prĂ©requis : si la sonde CO₂ n'est pas cĂąblĂ©e, la fonction CO₂ n'apparaĂźt pas dans la liste.

15. Domaine Énergie

Domaine introduit en V18. Regroupe :

  • ChaudiĂšres — avec brĂ»leur 2 allures OU modulant (exclusif)
  • Ballons stratifiĂ©s (open buffer)
  • Collecteurs chaleur — agrĂšgent demande circuits, distribuent vers chaudiĂšres/ballons
  • Collecteurs CO₂ — distribution CO₂ vers vannes compartiment
  • Source CO₂ liquide — alternative aux fumĂ©es chaudiĂšre
  • Source externe (chauffage importĂ©, ex: cogĂ©nĂ©ration)

Régulation chaudiÚre

Bornes temp_mini / temp_maxi :

  • BrĂ»leur dĂ©marre quand temp_depart < temp_mini
  • BrĂ»leur s'arrĂȘte quand temp_depart >= temp_maxi
  • temp_maxi_alarme dĂ©clenche l'alarme surchauffe
  • Anti-cycles via devi_min_s (TON) sur la chaudiĂšre

Brûleur 2 allures

Bascule petite/grande allure selon écart consigne avec hystérésis :

  • delta_grande_allure (3 °C) — passage en grande allure
  • delta_petite_allure (1 °C) — retour en petite allure
  • allure_min_s (60 s) — temps min entre bascules

Brûleur modulant

PID autour de consigne → demande_bruleur 0–100 %. La modulation 0 % ≠ 0 kW (plage min→max kW selon brĂ»leur).

V3V chaudiĂšre (anticondensation)

RĂ©gulation proportionnelle temp_retour_min = temp_depart × coeff_anticond (par dĂ©faut 0.8). Maintient le retour au-dessus de cette valeur pour Ă©viter la condensation dans le corps de chauffe.

16. Domaine Irrigation

HiĂ©rarchie : Station → Groupe → Vanne.

Station d'irrigation

  • Pompe — dĂ©bit cible
  • Doseurs EC A/B/C/D — ratio configurable + cycle PWM
  • Doseur pH — mode acide (pH-) OU base (pH+) (jamais les 2)
  • Sondes EC/pH — sonde 1 (rĂ©gulation) + sonde 2 optionnelle (dĂ©tection dĂ©rive)
  • RĂ©servoirs liĂ©s (eau claire + drainage)

Groupe d'irrigation

Un groupe regroupe plusieurs vannes simultanées. ParamÚtres :

  • 4 pĂ©riodes actives (P1-P4) — dĂ©but/fin en minutes
  • 4 dĂ©clencheurs (D1-D4) — type (heure fixe / cyclique / joules) + paramĂštres associĂ©s
  • Vannes simultanĂ©es par pĂ©riode

Vanne d'arrosage

  • Mode arrĂȘt : 0=Temps, 1=Litres, 2=cc/goutteur
  • QuantitĂ© cible, nombre de goutteurs, vol/goutteur
  • Confirmation_s — dĂ©lai avant alarme si dĂ©bit ne monte pas

17. Domaine SystĂšme

Domaine technique pour la gestion globale.

Coupleurs Modbus (auto-créés)

Pour chaque coupleur déclaré dans Config matériel, un équipement coupleur_modbus est créé automatiquement sous SystÚme. Il expose :

  • connecte (boolĂ©en)
  • adresse_ip, port
  • alm_defaut_coupleur (alarme K-bus / config / watchdog)

Gestionnaire d'alarmes (auto-créé)

Voir section Gestionnaire d'alarmes.

18. Régulation PID

Tous les contrÎleurs (chauffage, aération, V3V, brûleur modulant) utilisent un PID standard avec gains kp / ki / kd configurables par équipement.

Réglages typiques

Régulationkpkikd
Chauffage compartiment2 – 40.05 – 0.20 – 0.5
AĂ©ration compartiment2 – 40.05 – 0.20 – 0.5
V3V circuit5 – 100 – 0.10 – 0.5

Les gains sont stockĂ©s en consigne et modifiables Ă  chaud — la prochaine itĂ©ration du PID utilise les nouveaux gains.

Anti-windup

Le PID intÚgre un saturateur d'intégrale pour éviter le wind-up quand la sortie est saturée (ex: V3V à 100 %).

19. Sécurités météo

Trois sécurités pilotées par controler_meteo_securite :

Vent fort

  • seuil_vent_fort (typiquement 8-12 m/s)
  • confirm_vent_s — durĂ©e min au-dessus du seuil pour activer
  • seuil_vent_ok — hystĂ©rĂ©sis pour lever la sĂ©curitĂ©
  • retour_vent_s — durĂ©e min sous le seuil pour rĂ©ouverture
  • Action : ferme tous les ouvrants Ă  0 %

Pluie

  • Capteur DI pluie
  • confirm_pluie_s — dĂ©lai de confirmation (filtre les fausses dĂ©tections)
  • retour_pluie_s — dĂ©lai aprĂšs arrĂȘt avant rĂ©ouverture

Gel

  • seuil_gel (typiquement 2 °C)
  • Action : ferme ouvrants + active chauffage antigel

20. Gestionnaire d'alarmes

Le gestionnaire d'alarmes agrÚge toutes les alarmes en 3 sorties DO classifiées :

  • alm_climat_global — agrĂ©gation des alarmes compartiment / mĂ©tĂ©o
  • alm_irrigation_global — agrĂ©gation alarmes station/dosage/rĂ©servoir
  • alm_systeme_global — agrĂ©gation alarmes coupleur / brĂ»leur / surchauffe

Ces 3 sorties pilotent typiquement des relais externes (sirùne, voyant, GSM autonome
).

Entrées externes NF

3 entrĂ©es DI normalement fermĂ©es (NF) — alarme si contact ouvert :

  • entree_alarme_climat
  • entree_alarme_irrigation
  • entree_alarme_systeme

Permettent de remonter au SCADA des alarmes externes (groupe froid, défaut moteur, etc.).

Création automatique

Le conteneur gestionnaire_alarmes est créé automatiquement sous SystÚme au reload runtime via _sync_coupleurs_systeme. Les 3 sorties DO + 3 entrées DI sont obligatoires (couleur bleue dans le wizard, non supprimables). L'installateur peut ajouter d'autres entree_alarme_* NF supplémentaires.

21. Réservoirs & drainage

2 types de réservoirs :

  • reservoir_eau_claire — alimentation pompe irrigation
  • reservoir_eau_drainage — rĂ©cupĂ©ration drainage

Niveaux

3 contacts DI possibles par réservoir : contact_niveau_bas, contact_niveau_milieu, contact_niveau_haut. Pour chaque niveau, configurez les actions :

  • alarme — alm_niveau_*
  • arret_pompe — bloque la pompe d'irrigation
  • ferme_v3v — force la V3V mĂ©lange Ă  fermĂ©e

Drainage (calcul %)

Le FB controler_drainage intĂšgre debit_station (arrosage) + debit_drainage sur le cycle pompe ON→OFF, expose pct_drainage. Indicateur clĂ© culture hors-sol (cible 20-30 %).

22. Courbes de programmation

Les courbes permettent de programmer une consigne variable dans le temps (ex: température jour/nuit avec rampes).

  • StockĂ©es dans data/curves.json cĂŽtĂ© serveur
  • LiĂ©es Ă  la variable (varKey), pas au tableau qui les affiche
  • 8 points horaires par courbe
  • Modes : Absolu / Lever ± / Coucher ±
  • Le runtime relit curves.json chaque seconde et applique la valeur interpolĂ©e Ă  la consigne
  • Export/import dans la sauvegarde JSON globale

Interpolation

interpoler_courbe(curve, temps_min) calcule la valeur courante par interpolation linéaire entre les points actifs. La courbe se boucle sur 24 h.

23. VPN Tailscale

Tailscale fournit un accÚs distant sécurisé HTTPS sans configuration routeur. URL stable : https://scada-ipc.<tailnet>.ts.net.

Installation initiale

cd /opt/scada/v18
sudo bash install_tailscale.sh

Le script installe Tailscale, configure les permissions sudo et active tailscale serve pour le port 8000.

Onglet VPN

Ctrl+Alt+22 → onglet 🔒 VPN :

  • Statut — installĂ© / connectĂ© au tailnet / serve actif
  • Hostname, IP Tailscale, URL HTTPS
  • Boutons : Install / Up / Down / Cert / Serve On / Serve Off
  • Peers — liste des appareils du tailnet
  • Log — sortie des commandes

Authentification initiale

Cliquez sur Up → l'URL d'authentification Tailscale est extraite et affichĂ©e. Ouvrez-la dans un navigateur, validez l'appareil dans votre tailnet.

Certificat HTTPS

Cliquez sur Cert pour générer le certificat Let's Encrypt automatique (nécessite HTTPS Certificates activé dans l'admin Tailscale).

24. Web Push (VAPID)

Les notifications push utilisent le protocole VAPID. CÎté serveur :

  • Module v18/serveur/push.py avec pywebpush 2.0
  • ClĂ©s VAPID gĂ©nĂ©rĂ©es au premier boot, stockĂ©es en data/vapid_keys.json
  • Table push_subscriptions en DB serveur
  • Broadcast automatique sur transition alm_*_global False → True
  • Cleanup auto des subscriptions mortes (50 Ă©checs consĂ©cutifs → suppression)

Endpoints

EndpointMéthodeRÎle
/api/push/vapid_public_keyGETClé publique pour le client
/api/push/subscribePOSTEnregistrer un abonnement client
/api/push/unsubscribePOSTDésabonnement
/api/push/testPOSTEnvoyer un push de test

Détection alarmes

Les alarmes sont détectées dynamiquement par pattern (préfixe alm_, securite_, entree_alarme NF). Ajouter une nouvelle alarme = ajouter le label dans fr.json/alarmes, zéro code à modifier.

25. Configuration IA

Ctrl+Alt+22 → onglet ⚙ GĂ©nĂ©ral → Intelligence Artificielle.

ProviderModĂšleNotes
🟣 Anthropic (Claude)claude-haiku-4-5-20251001Cloud — recommandĂ© pour conseil agro
🟱 OpenAIgpt-4o-miniCloud — alternative
đŸ”” Gemini (Google)gemini-2.0-flashCloud — free tier gĂ©nĂ©reux
🟡 LM Studiollama-3.2-11b-vision-instructLocal — gratuit, pas de rĂ©seau

Saisissez votre clé API (sauf LM Studio qui demande l'URL http://localhost:1234). Cliquez sur Sauver.

La clĂ© est stockĂ©e dans serre_production.db table app_settings. Les widgets IA conseil + analyse maladies utilisent cette mĂȘme clĂ© via le module ia_helpers.py.

Si le crĂ©dit du provider est Ă©puisĂ©, le widget affiche le message d'erreur complet retournĂ© par l'API (depuis la session 26/04, on capture le body HTTP — plus de "HTTP 400" opaque).

26. Export / Import config

Export

Onglet Config matĂ©riel → bouton Exporter config. GĂ©nĂšre un JSON contenant :

  • Armoires, coupleurs, modules KL, canaux
  • Équipements logiques (arborescence + alias + nom_auto)
  • Variables (avec scaling et filtres)
  • Consignes utilisateur
  • Liens entre Ă©quipements (chaleur, CO₂)
  • FonctionnalitĂ©s activĂ©es
  • Courbes de programmation

Une copie horodatée est aussi sauvegardée automatiquement dans data/backups/config_YYYY-MM-DD_HHMMSS.json à chaque export.

Import

Cliquez sur Importer config, sélectionnez un fichier JSON. Le serveur efface l'installation courante et recrée tout depuis le JSON.

L'import remplace TOUTE la configuration. Sauvegardez la config courante avant d'importer une nouvelle config.

27. Audit V18

Le script v18/tests/audit_v18.py automatise 11 audits depuis le poste Windows de développement :

cd f:\scada+plc
python v18/tests/audit_v18.py --all --runs 3 --output v18/rapports/AUDIT_$(date +%Y_%m_%d).md

Étapes :

  1. Backup config courante
  2. Tests unitaires (pytest sur Function Blocks)
  3. Audit sécurité (rate limiting, headers HTTP, XSS)
  4. Audit architecture (taille fichiers, couplage runtime/serveur)
  5. Fuzzing IA — N runs (Sonnet gĂ©nĂšre des configs alĂ©atoires rĂ©alistes)
  6. Audit adversarial (5 attaques robustesse)
  7. Audit performance (taille snapshot, débit API, DB)
  8. Audit frontend (doublons variables, validation)
  9. Audit alarmes (déclenchement, latch, acquittement)
  10. Audit i18n (symétrie FR/EN, hardcodes, fetch _urlLang)
  11. Restauration config (avec relance sim_modbus pour mapping coherent)

L'audit doit toujours ĂȘtre lancĂ© depuis Windows (jamais SSH IPC) — sim_modbus tourne sur le PC dev.

CohĂ©rence catalogue ↔ runtime

L'analyse statique catalogue ↔ runtime (catĂ©gories A-F) est faite par Claude Code en fin d'audit, puis appendĂ©e au fichier rapport. Elle vĂ©rifie qu'aucune variable lue/Ă©crite par un FB n'est absente du catalogue, et que tous les FB sont orchestrĂ©s dans main.py.

28. Simulation Modbus

Le serveur Modbus de simulation simulation/sim_modbus.py permet de tester sans matériel terrain.

Lancement

cd f:\scada+plc
start_sim.bat

Ouvre une console séparée. Le sim sert à 192.168.1.3:502 et expose un serveur HTTP de scénarios sur :7001.

Mode nominal

Météo réelle Open-Meteo + oscillations T° + rétroaction simple (ouvrir un ouvrant fait baisser la température).

Scénarios métier

POST sur http://localhost:7001/scenario/<nom> :

  • alarme_externe_climat — force le contact NF entree_alarme_climat Ă  ouvert
  • alarme_externe_irrigation
  • alarme_externe_systeme
  • niveau_bas_drainage
  • defaut_sonde
  • reset — retour mode nominal

Override primitif

POST http://localhost:7001/force {"fc":4,"addr":0,"val":12345} — forcer une valeur Modbus brute.

29. Mise Ă  jour

Pour déployer une nouvelle version sur l'IPC :

cd f:\scada+plc
bash deploy_v18.sh

Le script :

  1. git push depuis Windows vers GitHub
  2. SSH IPC → git pull
  3. pip install -r requirements.txt (si modifié)
  4. systemctl restart scada-runtime scada-serveur
  5. Vérification statut /api/status

Service worker (PWA)

À chaque mise à jour qui touche le frontend, bumpez CACHE_NAME dans sw.js (ex: v95 → v96). Le SW activera automatiquement la nouvelle version et les clients PWA se rechargeront via controllerchange.

30. Sauvegarde DB

Les 2 bases sont en mode WAL avec auto_vacuum INCREMENTAL. Sauvegarde recommandée :

  • Quotidien : data/scada_v18.db (runtime + historique)
  • Quotidien : data/serre.db (config serveur, alarmes, courbes)
  • Hebdomadaire : data/serre_production.db (cultures, opĂ©rateurs, sessions)
  • Backups config JSON dans data/backups/

Pour archiver manuellement :

sqlite3 data/scada_v18.db ".backup data/backups/scada_v18_$(date +%Y%m%d).db"

31. Function Blocks runtime

27 FB Python dans v18/runtime/fonctions/ :

FBDomaineRĂŽle
controler_compartimentClimatOrchestrateur compartiment
controler_chauffageClimatPID chauffage
controler_aerationClimatPID aération
controler_humiditeClimatBrumisation / déshumidification
controler_co2ClimatVanne CO₂ enrichissement
controler_ecranClimatPosition écran (énergétique + ombrage)
controler_eclairageClimatDLI cible
controler_ouvrantClimatOuvrants cÎté vent / abrité
controler_circuitClimatDemande chauffage circuit HT/BT
controler_chaudiereÉnergieBornes temp_mini/maxi + brĂ»leur
controler_bruleur_modulantÉnergiePID brĂ»leur modulant
controler_v3vÉnergieV3V circuit
controler_v3v_chaudiereÉnergieV3V anticondensation
controler_moteurTousMoteurs avec course_total_s + recalage butées
controler_pompe_irrigationIrrigationPompe arrosage
controler_dosage_ecIrrigationDoseurs EC PWM
controler_dosage_phIrrigationDoseur pH (acide ou base)
controler_alarmes_irrigationIrrigationAlarmes EC/pH/débit
controler_groupe_irrigationIrrigationPériodes + déclencheurs groupe
controler_vanneIrrigationVanne arrosage individuelle
controler_irrigation_stationIrrigationOrchestrateur station
controler_irrigationIrrigationBoucle (legacy, Ă  terminer)
controler_drainageIrrigation% drainage par cycle pompe
controler_reservoirIrrigationNiveaux + actions
controler_meteo_securiteMétéoSécurités vent/pluie/gel
controler_alarmes_globalesSystÚmeAgrégation 3 sorties DO
calculer_soleilMétéosunrise_min / sunset_min

Ordre d'orchestration dans runtime/main.py : mĂ©tĂ©o → compartiments (chauffage, aĂ©ration, CO₂
) → circuits → chaudiĂšres → irrigation → rĂ©servoirs → alarmes globales. Cycle 1 s par dĂ©faut.

32. API REST principale

Lecture

EndpointDescription
GET /api/statusStatut runtime + serveur
GET /api/config/installation?lang=xxArbre des équipements
GET /api/picker/catalogue?lang=xxCatalogue picker variables
GET /api/config/fonctionnalites/catalogue_filtreFonctionnalités filtrées par prérequis
GET /api/alarm/historyHistorique alarmes (filtrable)
GET /api/alarm/detectedÉtat courant des alarmes (reconstruit depuis history)
GET /api/curvesListe courbes de programmation
GET /api/desksListe bureaux sauvegardés

Écriture

EndpointDescription
POST /api/writeÉcrire une consigne (UPSERT en DB + bridge runtime)
POST /api/config/installationCréer une installation
PUT /api/config/installationModifier une installation existante
POST /api/config/validerValider la config (avant Appliquer)
POST /api/curvesSauver une courbe
POST /api/alarm/actionDétecter / Confirmer une alarme

WebSocket

ws://<host>:8000/ws — diffusion snapshot complet Ă  chaque cycle runtime + broadcast alarmes Ă©vĂ©nementiel.

33. Dépannage

Runtime déconnecté

  1. Vérifier systemctl status scada-runtime
  2. Logs : journalctl -u scada-runtime -f
  3. Tester ping coupleur : ping 192.168.1.3
  4. Tester Modbus : nc -vz 192.168.1.3 502

Tableaux systĂšme vides

  • Le picker peut tarder Ă  charger aprĂšs reload — attendre 1-2 s
  • VĂ©rifier que les variables physiques sont cĂąblĂ©es (Attribution canaux)
  • VĂ©rifier les fonctionnalitĂ©s activĂ©es sur l'Ă©quipement

Push notifications ne marchent pas

  • NĂ©cessite HTTPS (Tailscale ou autre) — pas en HTTP local
  • VĂ©rifier que les clĂ©s VAPID existent dans data/vapid_keys.json
  • VĂ©rifier que le service worker est enregistrĂ© (DevTools → Application → Service Workers)
  • Inspecter /api/push/test dans Postman pour test isolĂ©

IA conseil retourne erreur 400

  • CrĂ©dit API Ă©puisĂ© (le message exact s'affiche dans le widget depuis la fix HTTP body)
  • ClĂ© invalide / rĂ©voquĂ©e — recharger via Ctrl+Alt+22 → GĂ©nĂ©ral
  • Provider tombĂ© — basculer sur LM Studio en local le temps de la rĂ©solution

Frontend cache stale aprĂšs deploy

  • Hard refresh : Ctrl+Shift+R
  • Si PWA installĂ©e : DevTools → Application → Service Workers → Unregister puis hard refresh
  • VĂ©rifier que CACHE_NAME a Ă©tĂ© bumpĂ© dans sw.js

Doublons d'équipements aprÚs modifs successives

  • VĂ©rifier _DOMAINE_MAP dans routes_config_materiel.py — chaque type doit y ĂȘtre listĂ© sinon parent_id=None et la rĂ©conciliation ne match pas
  • Cas connu corrigĂ© : gestionnaire_alarmes (rattachĂ© Ă  'systeme' en V18.5)