Binding : Introduction
- Bien démarrer
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
- Identifier les acteurs (objets réels à superviser) et leurs attributs utiles.
- Définir les familles correspondant aux types réels observés ; lister propriétés et handles attendus.
- Instancier chaque équipement concret (identité, localisation, appartenance à des scopes).
- Mapper les données (protocoles, API, fichiers) vers les handles de l’instance.
- 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, Floor → Scopes : « 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 :
- 📦 BuildingSensorSimulator — v1.0 • 1.8 MB • ZIP
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"));
}
Il n'est pas nécessaire de maitriser ce code pour ce tutoriel. Mais si on souhaite créer un jumeau numérique de cet exemple de syndicat de copropriété il est nécessaire de savoir quels sont les objets qui vont devoir être supervisés. Ainsi le point ci-après énumère l'ensemble des acteurs Immersive à créer qu'ils soient :
- Famille d'équipement
- Instance d'équipement'
- Handle
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
Pour rappel les familles peuvent déclarer des handles (socle commun) : ces handles sont hérités par toutes leurs instances, ce qui uniformise le scripting et l’UI (mêmes noms, mêmes types).
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 S1…S5
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) |
Pour chaque objet 3D, stockez une equipmentRef stable (ou un mapping) vers l’instance Immersive. Côté scripts,
écoutez les handles de famille (hérités) pour appliquer styles/animations/alertes de façon générique à toutes les instances
d’une même famille.
Téléchargement des sources
- 📦 BuildingSensorSimulator — v1.0 • 1.8 MB • ZIP