Skip to content

Superviseur — Supervision d'alarmes incendie Desautel

Logiciel professionnel de supervision en temps réel de centrales de détection incendie via les protocoles Modbus TCP et RTU, compatible avec les centrales INIS-E16 et AVISS.

Notice d'utilisation complète : voir NOTICE_UTILISATION.md


Fonctionnalités clés

  • Supervision temps réel multi-centrales — état consolidé de l'ensemble du parc, mises à jour poussées par SignalR.
  • Compatibilité INIS-E16 et AVISS — Modbus TCP et RTU, y compris bus série multi-drop (plusieurs centrales partageant la même liaison).
  • Acquittement granulaire par type d'incident — feu, dérangement, hors-service, évacuation… traités indépendamment sur chaque zone et chaque point, avec cascade hiérarchique zone → points.
  • Plans interactifs — positionnement des zones et points sur le plan du site, statut en temps réel et tooltips détaillés.
  • Statistiques et rapports — agrégation par type d'événement, tendances, exports CSV et PDF.
  • Alerte sonore — signalisation audio différenciée par type d'incident, avec reprise après acquittement.
  • Accès distant — supervision accessible à distance en complément du poste opérateur local.
  • Journal d'audit horodaté — chaque détection, acquittement et commande tracé en base PostgreSQL.
  • Sécurité — authentification JWT, contrôle d'accès par rôles (RBAC), secret applicatif unique, mode kiosk protégé.

Fonctionnement global

Le Superviseur interroge en permanence les centrales incendie via le bus Modbus. Chaque centrale expose des tables de bits : un bit passe de 0 à 1 lorsqu'un événement se produit (alarme feu, dérangement, hors-service, etc.). Le logiciel détecte ces changements, les affiche en temps réel et permet aux opérateurs d'acquitter chaque incident individuellement.

mermaid
flowchart LR
    subgraph Site protégé
        C1[Centrale INIS-E16]
        C2[Centrale AVISS]
        C3[Centrale AVISS]
    end

    subgraph Superviseur
        BE[Service Windows\nBackend .NET 9]
        DB[(PostgreSQL embarqué\nJournal d'audit)]
        UI[Interface Web\nVue 3]
    end

    C1 -- Modbus TCP/RTU --> BE
    C2 -- Modbus TCP/RTU --> BE
    C3 -- Modbus TCP/RTU --> BE
    BE -- Lecture/Écriture --> DB
    BE -- SignalR temps réel --> UI
    UI -- API REST --> BE

Cycle de surveillance

Le backend interroge chaque centrale à intervalle régulier (1 à 5 secondes). À chaque cycle, il lit l'intégralité des tables Modbus et compare l'état actuel avec l'état précédent.

mermaid
flowchart TD
    A[Cycle de polling] --> B[Lecture des tables Modbus\nsur la centrale]
    B --> C{Comparer avec\nl'état précédent}
    C -- Nouveau bit à 1 --> D[Incident détecté\nLog en base + alerte UI]
    C -- Bit revient à 0 --> E{L'opérateur avait\nacquitté ?}
    C -- Pas de changement --> A
    E -- Oui --> F[Incident résolu\nDisparaît de l'écran]
    E -- Non --> G[Incident latché\nBouton Effacer affiché]
    D --> A
    F --> A
    G --> A

Tables Modbus — Ce qu'on surveille

Chaque centrale expose plusieurs tables de bits. Chaque table représente un type d'incident et chaque bit dans cette table correspond à un élément (zone, point, ou paramètre système).

mermaid
block-beta
    columns 3
    block:system["Paramètres système (23 bits)"]:3
        s1["Bit 1 : Alarme feu générale"]
        s2["Bit 2 : Dérangement général"]
        s3["Bit 3-8 : Défauts\n(réseau, secteur, batteries...)"]
    end
    block:points["Tables Points (508 bits chacune)"]:3
        p1["Feu Point\n@2001"]
        p2["Dérangement Point\n@3001"]
        p3["Hors-Service Point\n@1001"]
    end
    block:zones["Tables Zones (jusqu'à 999 bits chacune)"]:3
        z1["Feu Zone\n@5001"]
        z2["Dérangement Zone\n@6001"]
        z3["Hors-Service Zone\n@4001"]
    end
    block:extra["Tables spécifiques INIS-E16 (16 bits)"]:3
        e1["Évacuation\n@8001"]
        e2["Émission\n@8021"]
        e3["DM Extinction\n@8041"]
    end

    style system fill:#fee2e2,stroke:#ef4444
    style points fill:#fef3c7,stroke:#f59e0b
    style zones fill:#dbeafe,stroke:#3b82f6
    style extra fill:#f3e8ff,stroke:#a855f7

Un même élément peut avoir plusieurs incidents simultanés. Par exemple, la Zone 3 peut avoir son bit à 1 dans la table Feu et dans la table Dérangement en même temps. Chaque type d'incident est traité indépendamment.


Cycle de vie d'un incident

Un incident naît quand un bit passe à 1 et suit un parcours précis jusqu'à sa disparition complète de l'écran.

mermaid
stateDiagram-v2
    [*] --> Actif : Bit passe à 1\n(incident détecté)

    Actif --> Acquitté : L'opérateur clique\n"Acquitter"
    Actif --> EnAttente : Le bit revient à 0\nsans acquittement

    Acquitté --> Résolu : Le bit revient à 0\n(hardware réarmé)
    Acquitté --> Acquitté : Le bit reste à 1\n(en attente réarmement)

    EnAttente --> Actif : Le bit repasse à 1\n(réapparition)
    EnAttente --> Nettoyé : L'opérateur clique\n"Effacer"

    Résolu --> [*] : Disparaît automatiquement\nde l'écran

    Nettoyé --> [*] : Disparaît de l'écran

    state Actif {
        [*] : Bouton "Acquitter" affiché
    }
    state Acquitté {
        [*] : Bouton "Réarmer la centrale" affiché\nBadge atténué
    }
    state EnAttente {
        [*] : Bouton "Effacer" affiché\n(En attente de nettoyage)
    }

Ce que voit l'opérateur à chaque étape

ÉtatCe qui s'afficheAction disponibleCe qui se passe en coulisse
ActifBadge rouge vif (ex: "Alarme Feu")Bouton AcquitterBit = 1, AckStatus = None
AcquittéBadge atténué + icône checkBouton RéarmerBit = 1, AckStatus = SoftwareAcked
En attenteBadge vert + icône checkBouton EffacerBit = 0, AckStatus = HardwareCleared
RésoluDisparaîtBit = 0 après acquittement

Acquittement par type d'incident

L'acquittement est granulaire : chaque type d'incident sur chaque élément est traité indépendamment. Acquitter le feu sur la Zone 3 ne touche pas au dérangement sur cette même zone.

mermaid
flowchart TD
    subgraph Zone 3
        F["Alarme Feu\n(non acquitté)"]
        D["Dérangement\n(non acquitté)"]
    end

    OP[Opérateur] -- "Acquitter Feu\nsur Zone 3" --> F
    F -- "Seul le feu\nest acquitté" --> FA["Alarme Feu\n(acquitté)"]
    D -- "Le dérangement\nreste actif" --> D2["Dérangement\n(toujours non acquitté)"]

    style F fill:#fee2e2,stroke:#ef4444
    style D fill:#fef3c7,stroke:#f59e0b
    style FA fill:#f1f5f9,stroke:#94a3b8
    style D2 fill:#fef3c7,stroke:#f59e0b

Cascade hiérarchique

Quand un opérateur acquitte une zone, tous les points (détecteurs) rattachés à cette zone sont automatiquement acquittés pour le même type d'incident.

mermaid
flowchart TD
    Z["Zone 1 — Acquitter Feu"] --> P1["Point 10 — Feu auto-acquitté"]
    Z --> P2["Point 11 — Feu auto-acquitté"]
    Z --> P3["Point 12 — Dérangement\n(non touché, type différent)"]

    style Z fill:#dbeafe,stroke:#3b82f6
    style P1 fill:#f1f5f9,stroke:#94a3b8
    style P2 fill:#f1f5f9,stroke:#94a3b8
    style P3 fill:#fef3c7,stroke:#f59e0b

Hiérarchie des incidents

L'interface organise les incidents en 3 niveaux, du plus global au plus précis.

mermaid
flowchart TD
    subgraph Centrale["Centrale (Paramètres système)"]
        SYS1["Alarme feu générale"]
        SYS2["Défaut secteur"]
        SYS3["Défaut batteries"]
    end

    subgraph Zones["Zones (regroupements logiques)"]
        Z1["Zone 1 — Hall\nFeu + Dérangement"]
        Z2["Zone 3 — Serveurs\nÉvacuation"]
    end

    subgraph Points["Points (détecteurs physiques)"]
        P1["Point 10 — Détecteur fumée\nFeu"]
        P2["Point 11 — Détecteur chaleur\nFeu"]
        P3["Point 25 — DM étage 2\nDérangement"]
    end

    Centrale --> Zones
    Z1 --> P1
    Z1 --> P2
    Z2 --> P3

    style Centrale fill:#fee2e2,stroke:#ef4444
    style Zones fill:#dbeafe,stroke:#3b82f6
    style Points fill:#fef3c7,stroke:#f59e0b

Traçabilité et journal d'audit

Chaque action est enregistrée dans la base de données avec horodatage, utilisateur et type d'événement.

MomentCe qui est enregistréExemple
DétectionType + localisationPanel-1 — Zone 3 — Fire Alarm Detected
AcquittementUtilisateur + typePanel-1 — Zone 3 Fire Alarm Acknowledged by john.doe
Réarmement hardwareTransition d'étatPanel-1 — Zone 3 — Fire Alarm Restored (Awaiting Ack)
RéapparitionMême incident revientPanel-1 — Zone 3 — Fire Alarm Reappeared
NettoyageFin de cyclePanel-1 — Zone 3 Fire Alarm Reset by john.doe

Architecture technique

ComposantTechnologieRôle
backendC# .NET 9, ASP.NET Core, EF Core, PostgreSQL (Npgsql), SignalRService Windows : polling Modbus, API REST, temps réel, journal d'audit
frontendVue 3, TypeScript, Tailwind CSS, DaisyUI, PiniaInterface web : tableau de bord, carte SVG, historique
clientWPF .NET 9, WebView2Fenêtre native Windows (mode kiosk sécurisé)
managerWinForms .NET 9Gestionnaire de service (barre des tâches)
simulatorWPF .NET 9Simulateur de centrale Modbus pour les tests
sharedC# .NET 9Modèles et configuration partagés
tests/xUnit (backend), Vitest (frontend)Tests unitaires et d'intégration
mermaid
flowchart LR
    subgraph Poste opérateur
        CLIENT[Client WPF\nMode kiosk] --> UI[Frontend Vue 3\nTableau de bord]
    end

    subgraph Service Windows
        UI -- API REST --> API[ASP.NET Core]
        UI -- SignalR --> HUB[Hub temps réel]
        API --> SVC[Services métier\nZone / Point / System]
        HUB --> SVC
        SVC --> MODBUS[Adaptateurs Modbus\nINIS-E16 / AVISS]
        SVC --> LOG[Journal d'audit\nPostgreSQL]
    end

    subgraph Terrain
        MODBUS -- TCP/RTU --> C1[Centrale 1]
        MODBUS -- TCP/RTU --> C2[Centrale 2]
        MODBUS -- TCP/RTU --> C3[Centrale N]
    end

Développement

Prérequis

  • SDK .NET 9
  • Node.js 22+
  • Visual Studio 2022 ou JetBrains Rider
  • Fichier appsettings.Crypto.json réel (copier depuis appsettings.Crypto.exemple.json avec les clés revendeurs)

Secret applicatif uniqueSecurity:SuperAdminPassword (dans appsettings.Crypto.json, en clair) sert à la fois au compte SuperAdmin desautel (haché BCrypt au premier démarrage) et au mot de passe du rôle PostgreSQL (injecté dans la chaîne de connexion au démarrage). S'il est laissé vide, une valeur par défaut (SecurityDefaults) est appliquée. À l'installation, l'installateur le propage automatiquement à PostgreSQL.

Lancement en mode développement

bash
# Backend (service + API sur :5000)
dotnet run --project backend

# Frontend (dans un autre terminal, HMR sur :5173)
cd frontend && npm install && npm run dev

Le client WPF pointe sur http://localhost:5000 (production) ou http://localhost:5173 (développement Vite).

Tests

bash
# Backend (xUnit)
dotnet test

# Frontend (Vitest)
cd frontend && npm run test:run

Documentation

powershell
# Génération complète + serveur local sur http://localhost:3008/
.\generate-docs.ps1 -Serve

# Sans l'API C# (plus rapide)
.\generate-docs.ps1 -SkipBackend -Serve

# Développement avec hot-reload (guides + API TypeScript)
npm run docs:dev
SectionURLOutil
Portail et guideshttp://localhost:3008/VitePress
API TypeScripthttp://localhost:3008/api/TypeDoc
Référence C#http://localhost:3008/backend/DocFX

Build et déploiement

powershell
cd deployment
.\build-all.ps1

Le script compile tout en Release, télécharge le runtime WebView2 si nécessaire, et génère Installer/Superviseur-Setup.exe via Inno Setup 6. Voir deployment/README.md pour les détails.


Sécurité et rôles

Le système implémente un contrôle d'accès strict (RBAC) avec authentification JWT.

RôleDroits
UtilisateurConsultation, acquittement des incidents
AdminConfiguration des centrales, gestion des zones et points
SuperAdminGestion des utilisateurs, réseaux INIS, suppression de données, fermeture kiosk

Protections supplémentaires :

  • Chiffrement des fichiers de configuration INIS (algorithme SimpleCrypt Desautel)
  • Clés revendeurs et mots de passe sensibles dans appsettings.Crypto.json (non versionné)
  • Mode kiosk : fermeture protégée par authentification SuperAdmin

Documentation Modbus

Modes d'adressage

Type de centraleModeLogiqueExemple
INIS-E16DirectAdresse Logique = Adresse Protocole953 envoie 953
AVISSStandardAdresse Logique - 1 = Adresse Protocole2001 envoie 2000

Table d'adressage (INIS-E16)

FonctionAdresseDescription
Paramètres système1–2323 bits de synthèse (feu, défauts, etc.)
Hors-Service Point953508 bits (1 par point)
Feu Point2002508 bits (1 par point)
Dérangement Point3002508 bits (1 par point)
Hors-Service Zone4002999 bits (1 par zone)
Feu Zone5002999 bits (1 par zone)
Dérangement Zone6002999 bits (1 par zone)
Test Zone7002999 bits (1 par zone)
Évacuation800116 bits (INIS-E16 uniquement)
Émission802116 bits (INIS-E16 uniquement)
DM Extinction804116 bits (INIS-E16 uniquement)
Commandes5003 registres d'écriture

Commandes Modbus (écriture)

N° FonctionAction
1Mise hors-service point
2Mise en service point
3Mise hors-service zone
4Mise en service zone
5Mise en essai zone
10Arrêt signaux sonores
11Réarmement

Workflow et releases

  • main : branche de développement, CI (tests + build) à chaque push.
  • prod : branche de production, mise à jour par Pull Request uniquement, déclenche le CD (release GitHub).

Procédure de release

  1. Sur main : valider les tests, mettre à jour la version dans app.config.json et le CHANGELOG.md.
  2. Ouvrir une Pull Request mainprod, vérifier la CI.
  3. Au merge : le CD crée automatiquement une release GitHub en brouillon (tag vX.Y.Z + notes extraites du changelog). Il ne compile pas l'application.
  4. Compiler l'installateur localement : cd deployment && .\build-all.ps1.
  5. Attacher deployment/Installer/Superviseur-Setup.exe au brouillon de release, puis publier.

Le build de l'installateur (lourd) est volontairement réalisé en local, pas sur GitHub Actions.

Format CHANGELOG requis :

markdown
## [X.Y.Z] - DD-MM-YYYY

### Added
- Nouvelles fonctionnalités
### Fixed
- Corrections

Documentation Technique