Binding : Introduction

Formation

Le binding est l’étape qui relie la vue 3D (objets graphiques de la carte) au DOM des équipements (entités métiers supervisées). Concrètement, on crée des liens stables entre un objet visuel et un équipement Immersive, pour que toute action ou donnée (état, variable, alarme) impacte la bonne représentation visuelle — et réciproquement (sélection, focus, fiches d’équipement).

Modèle Objet Immersive : représenter fidèlement le réel

Le modèle Objet Immersive vise à traduire, sans distorsion, la réalité opérationnelle d’un site dans le système. Immersive s’appuie sur un MCD (modèle conceptuel de données) rigoureux pour garantir une représentation exacte et exploitable des acteurs métiers (ascenseurs, sondes, véhicules, caméras…) et des acteurs techniques (protocoles, variables, états, événements) qui seront supervisés. Comprendre ces acteurs en amont est indispensable : c’est cette analyse qui permet de transformer les sources métier et de les traduire correctement dans le modèle objet d’Immersive.

Pourquoi cette modélisation est essentielle

  • Fidélité au terrain : un objet numérique correspond à un objet réel (ou à un agrégat défini), sans ambiguïté.
  • Interopérabilité : des données hétérogènes (GMAO, BMS, IoT, fichiers) sont unifiées dans une structure unique.
  • Traçabilité & supervision : chaque donnée, événement ou alerte est rattaché à l’objet « juste ».
  • Évolutivité : un MCD clair facilite les extensions (nouvelles familles, nouvelles propriétés, nouveaux sites).

Vue d’ensemble du modèle

Immersive organise les entités autour de quatre notions clés : Famille d’équipement, Instance d’équipement, Propriétés/Handles et Scope.

Famille d’équipement

Une famille décrit un type homogène d’objets (ex. :Ascenseur, Sonde de température, Véhicule). Elle définit la structure attendue (propriétés standards, variables, sémantique) et sert de gabarit pour ses instances.

Instance d’équipement

Une instance est un équipement concret appartenant à une unique famille. Exemple : Ascenseur “ATR5910” du bâtiment B de l’usine Bidule. Les instances portent l’identité, la localisation, et les liens de supervision.

Propriétés / Handles

Une instance expose des propriétés (valeurs configurées) et des handles (points de données dynamiques publiés par le Hub). Les handles représentent les données d’état, de mesure ou d’alarme de l’équipement (ex. : Défaut porte palière, Étage courant, Porte ouverte/fermée).

Une famille peut elle aussi déclarer des Handles. Ces handles de famille sont hérités par toutes les instances de cette famille, ce qui garantit un socle commun (noms, types, sémantique) et simplifie grandement le scripting et l’intégration.

Scope (périmètre logique)

Un scope regroupe des instances selon une logique métier (équipe d’intervention, type d’activité) ou géographique (site, bâtiment, étage, zone). Un même équipement peut appartenir à plusieurs scopes pour refléter différents points de vue opérationnels (ex. : « Maintenance Ascenseurs », « Bâtiment B »).

Héritage des handles (famille → instance)

  • Contrat de données commun : définir les handles au niveau de la famille crée une API stable pour toutes les instances.
  • Réduction des écarts : moins de variations de noms/types, moins d’effort de mapping et de tests.
  • Extensibilité : chaque instance peut ajouter des handles spécifiques si nécessaire (sans casser le contrat de base).
  • Scripting simplifié : les scripts peuvent cibler les handles de famille en supposant leur présence sur toutes les instances.

Relations et règles structurelles

  • Famille → Instances : 1 famille regroupe N instances (cardinalité 1..*).
  • Famille → Handles : les handles de famille sont hérités par toutes les instances.
  • Instance → Handles : une instance peut ajouter ses propres handles (spécifiques) en plus de l’héritage.
  • Scopes ↔ Instances : relation N↔N permettant des regroupements souples et multiples.

Sécurité et périmètres

Les familles d’équipements et les scopes sont sécurisables : on peut contrôler qui voit, qui configure ou qui opère un périmètre/famille. Cette granularité d’accès est cruciale pour cloisonner les usages (ex. : opérateurs, maintenance, sécurité, direction) et respecter les responsabilités.

Transformer la connaissance métier en modèle Immersive

  1. Identifier les acteurs (objets réels à superviser) et leurs attributs utiles.
  2. Définir les familles correspondant aux types réels observés ; lister propriétés et handles attendus.
  3. Instancier chaque équipement concret (identité, localisation, appartenance à des scopes).
  4. Mapper les données (protocoles, API, fichiers) vers les handles de l’instance.
  5. Valider la traçabilité (un événement = un objet exact) et ajuster le MCD si nécessaire.

Exemple résumé

Famille : Ascenseur → Instance : “ATR5910” (Bâtiment B) → Handles : DoorFault, DoorState, FloorScopes : « Maintenance Ascenseurs », « Bâtiment B ».

Bonnes pratiques

  • Nommage stable (IDs, familles, handles) pour éviter les ruptures lors des évolutions.
  • Référentiels partagés (sites, bâtiments, zones) pour garantir une cohérence transverse.
  • Handles explicites (type, unité, sémantique) pour faciliter les règles de scripting et l’UI.
  • Scopes pertinents pour refléter les vrais usages (exploitation, sûreté, maintenance, direction).
  • Contrôles réguliers (couverture, orphelins, doublons) pour maintenir la qualité du modèle.

Binding — modèle d’exemple (BuildingSensorSimulator)

Pour illustrer le binding 3D ↔ DOM, nous nous appuyons sur le projet d’exemple BuildingSensorSimulator. Imaginons que nous travaillions pour un syndic de copropriété : il faut importer les équipements dans Immersive et donc répertorier les familles, les instances et les handles qui serviront de contrat de données pour le binding.

Rappel

Le projet BuildingSensorSimulator dont voici le code source :

simule un ensemble de capteurs et d'équipements qui permettent d'étayer les différents tutoriaux de nos pages dédiés aux développeurs de la solution Immersive.

Ce projet après analyse instancie et créé un certain nombre d'équipement qui peuvent être déterminé après analyse du code source pour ceux qui maitrisent le langage C# :

private void Seed()
{
    var now = DateTime.UtcNow;

    int lastId = 0;
    int NextId() => ++lastId;

    //function for simple device with one variable
    Device Single(string name, string type, string unit, string value, int? fixedId = null)
    {
        var id = fixedId ?? NextId();
        return new Device
        {
            Id = id,
            Name = name,
            Type = type,
            Value = value,              // valeurs normalisées en string
            Unit = unit,
            TimestampUtc = now
        };
    }

    //function for elevator
    Device Elevator(string name, int? fixedId = null)
    {
        var id = fixedId ?? NextId();
        return new Device
        {
            Id = id,
            Name = name,
            Type = "elevator",
            Variables =
            [
                new() { Name = "floor", Path = $"floor", Kind = "numeric", Unit = null, Value = "0",      TimestampUtc = now },
                new() { Name = "state", Path = $"state", Kind = "enum",    Unit = null, Value = "Idle",   TimestampUtc = now },
                new() { Name = "door",  Path = $"door",  Kind = "enum",    Unit = null, Value = "Closed", TimestampUtc = now },
            ]
        };
    }

    //function for garage door
    Device GarageDoor(string name, int? fixedId = null)
    {
        var id = fixedId ?? NextId();
        return new Device
        {
            Id = id,
            Name = name,
            Type = "garageDoor",
            Variables =
            [
                new() { Name = "door",     Path = $"door",     Kind = "enum", Value = "Closed", TimestampUtc = now },
                new() { Name = "obstacle", Path = $"obstacle", Kind = "bool", Value = "false",  TimestampUtc = now },
            ]
        };
    }

    // ---------------------------------------
    Devices.AddRange(
    [
        Single("Temp S1",               "sensor",     "°C",  "27.5"),
        Single("Parking Humidity",     "humidity",   "%",   "50"),
        Single("Corridor Light Level",  "light",      "lux", "300"),
        Single("Office Presence",       "presence",   "bool","0"),
        Single("Main Electric Counter", "energy",     "kWh", "1250"),
        Single("Smoke Detector",        "smoke",      "bool","0"),
        Single("Parking Temperature",  "temperature","°C",  "21"),
        ]);

    // Rooms supplémentaires (temp + humidity)
    foreach (var room in new[] {101, 102, 103, 104, 201, 202, 203, 204, 301, 302, 303, 304 })
    {
        Devices.Add(Single($"Room {room} Temperature", "temperature", "°C", "21"));
        Devices.Add(Single($"Room {room} Humidity", "humidity", "%", "50"));
    }

    // 5 détecteurs de fumée
    for (int i = 1; i <= 5; i++)
        Devices.Add(Single($"Smoke Detector S{i}", "smoke", "bool", "0"));


    //start id farther for complex devices
    lastId = 101;
    Devices.Add(Elevator("Lift A"));
    Devices.Add(Elevator("Lift B"));
    Devices.Add(GarageDoor("Garage G1"));

}

Familles d’équipements (proposées)

Le syndicat de copropriété d'exemple expose les familles d'objet suivantes :

  • Elevator (ascenseur)
  • GarageDoor (porte de garage)
  • TemperatureSensor
  • HumiditySensor
  • LightSensor
  • PresenceSensor
  • EnergyCounter
  • SmokeDetector

Instances simulées (extrait)

Ascenseurs & porte de garage

  • Elevator : Lift A, Lift B
  • GarageDoor : Garage G1

Capteurs mono-valeur

  • TemperatureSensor : Temp S1, Parking Temperature, Room 101 Temperature, Room 102 Temperature, Room 103 Temperature, Room 104 Temperature, Room 201 Temperature, Room 202 Temperature, Room 203 Temperature, Room 204 Temperature, Room 301 Temperature, Room 302 Temperature,Room 303 Temperature, Room 304 Temperature
  • HumiditySensor : Parking Humidity, Room 101 Humidity, Room 102 Humidity,Room 103 Humidity, Room 104 Humidity, Room 201 Humidity, Room 202 Humidity,Room 203 Humidity, Room 204 Humidity, Room 301 Humidity, Room 302 Humidity,Room 303 Humidity, Room 304 Humidity
  • LightSensor : Corridor Light Level
  • PresenceSensor : Office Presence
  • EnergyCounter : Main Electric Counter
  • SmokeDetector : Smoke Detector, Smoke Detector S1S5

Handles de famille (hérités par les instances)

Elevator

Path Kind Unité Description
Handle Elevator/Floor numeric Étage courant (0, 1, 2 …)
Handle Elevator/State enum État : Idle, Moving, Alarm
Handle Elevator/Door enum Porte : Open / Closed

GarageDoor

Handle Kind Unité Description
GarageDoor/Door enum Position de la porte : Open / Closed
GarageDoor/Obstacle bool Obstacle détecté (sécurité)

TemperatureSensor

Handle Kind Unité Description
Temperature/Value numeric °C Température mesurée

HumiditySensor

Handle Kind Unité Description
Humidity/Value numeric % Humidité relative

LightSensor

Handle Kind Unité Description
Light/Level numeric lux Niveau lumineux

PresenceSensor

Handle Kind Unité Description
Presence/State bool Présence détectée (1) / non (0)

EnergyCounter

Handle Kind Unité Description
Energy/Total numeric kWh Index de consommation

SmokeDetector

Handle Kind Unité Description
Smoke/Alarm bool Alarme fumée (true/false)

Téléchargement des sources