# BACnet

> Relier des équipements de gestion technique du bâtiment en BACnet/IP : numéro d'instance de l'équipement, adressage par type et instance d'objet, découverte Who-Is et presentValue.

Le pilote **BACnet** parle au matériel de gestion technique du bâtiment en BACnet/IP.
Chaque tag lit la **valeur présente** d'un objet BACnet : la lecture en direct d'une
entrée analogique, l'état d'une sortie binaire, la position d'une valeur multi-état.
Ajoutez un équipement sous le pilote BACnet dans le [Connector](connector) ; le
volet ne montre que les champs que ce protocole emploie.

## Connexion {#connection}

| Champ | Sens | Défaut |
| --- | --- | --- |
| **Hôte** | L'adresse IP ou le nom d'hôte de l'équipement BACnet (ou du routeur qui répond pour lui). Un nom est résolu en son adresse IPv4 quand l'équipement se connecte ; un nom que cet ordinateur ne sait pas résoudre laisse l'équipement sans connexion, et le motif le dit. | vide |
| **Port** | Le port UDP de l'équipement, de 1 à 65535. Un champ vide affiche 47808, le standard BACnet/IP, en gris et l'équipement est joint sur ce port ; un équipement enregistré avec 0 se lit de la même façon. | 47808 |
| **Identifiant d'équipement** | Le numéro d'instance de l'équipement, celui de son objet Device, unique sur le réseau BACnet. | 0 |

L'en-tête de l'équipement montre l'endpoint assemblé, par exemple
`bacnet://192.168.0.30:47808/1234`. La connexion envoie une requête sur la taille
de la liste d'objets de l'équipement pour confirmer que le matériel répond ; la liste d'objets
elle-même n'est pas parcourue. Cette réponse est la connexion : un équipement qui ne répond pas
reste hors ligne au lieu de s'afficher comme connecté, et la raison (le port UDP
déjà pris, une adresse qui n'en est pas une) est écrite dans la page Événements
et dans le fichier journal du jour. Il n'y a pas de champ de période de scrutation pour ce pilote :
ses tags sont lus une fois par seconde.

## Adressage {#addressing}

Un tag BACnet est adressé par deux champs typés de la carte Source de la valeur du tag, sans
adresse en texte libre :

| Champ | Sens | Valeurs acceptées | Défaut |
| --- | --- | --- | --- |
| **Type d'objet** | Quelle sorte d'objet BACnet lire. | les neuf types ci-dessous | `AnalogInput` |
| **Numéro d'instance** | Le numéro d'instance de l'objet dans son type. | 0 et plus | 0 |

Les types d'objet proposés et leurs codes de type BACnet standard :

| Type d'objet | Code | La valeur présente porte |
| --- | --- | --- |
| `AnalogInput` | 0 | un nombre mesuré |
| `AnalogOutput` | 1 | un nombre commandé |
| `AnalogValue` | 2 | un nombre conservé |
| `BinaryInput` | 3 | inactif/actif |
| `BinaryOutput` | 4 | inactif/actif |
| `BinaryValue` | 5 | inactif/actif |
| `MultiStateInput` | 13 | un numéro d'état à partir de 1 |
| `MultiStateOutput` | 14 | un numéro d'état à partir de 1 |
| `MultiStateValue` | 19 | un numéro d'état à partir de 1 |

`AnalogInput` 5 sur l'équipement 1234 signifie « la valeur présente de l'entrée analogique 5 de
cet équipement ». Chaque lecture demande la propriété `presentValue` de l'objet ; les autres
propriétés ne sont pas adressables. La ligne **Adresse source (bus)** en lecture seule de la
carte Source de la valeur montre la paire `type,instance` assemblée au fil de la saisie.

## Types de donnée {#data-types}

Le sélecteur **Type de donnée** propose quatre types. Choisissez celui qui correspond à l'objet :

| Type de donnée | Convient à | Notes |
| --- | --- | --- |
| Float | les objets analogiques | une valeur présente Real ; les doubles sont réduits à Float |
| Boolean | les objets binaires | une valeur présente booléenne, ou les 0 et 1 énumérés qu'un objet binaire répond |
| Int32 | les valeurs multi-état et les autres valeurs entières | les réponses signées, non signées et énumérées arrivent toutes ici |
| String | les valeurs de type chaîne de caractères | du texte tel que l'équipement l'envoie |

Le type choisi doit correspondre à ce que l'objet porte. Un équipement qui répond avec
autre chose fait échouer la lecture de ce tag : le tag passe en mauvaise qualité et la raison
nomme ce qui est arrivé (« L'équipement a répondu une valeur Single pour un point déclaré
Integer. »), au lieu qu'un nombre converti n'entre dans la courbe, l'historique et
les alarmes. Lire un objet analogique en booléen, ou un Real en Int32, est exactement
ce cas-là. Le reste de l'équipement continue de se lire ; rien n'est reconnecté à cause d'un
tag dont le type est faux.

Un tag dont l'équipement n'a pas l'objet voit sa lecture échouer avec la réponse
de l'équipement lui-même : la raison dit que l'équipement n'a aucun objet à cette
adresse et nomme l'erreur qu'il a envoyée (`ERROR_CODE_UNKNOWN_OBJECT`), si bien
qu'une adresse fausse se distingue d'un équipement qui a cessé de répondre.
L'équipement reste connecté.

## Écritures {#writes}

Les tags dont l'**Accès** est Lecture et écriture ou Écriture seule peuvent être écrits. Une écriture
pose le `presentValue` de l'objet dans le type que la norme BACnet donne à cette sorte d'objet,
quel que soit le type de donnée du tag :

| Objet | Écrit en | Accepte |
| --- | --- | --- |
| Entrée, sortie ou valeur binaire | Enumerated | inactif (0) ou actif (1), depuis un tag Boolean ou un Int32 valant 0 ou 1 |
| Entrée, sortie ou valeur multi-état | Unsigned | un numéro d'état à partir de 1 |
| Entrée, sortie ou valeur analogique | Real | un nombre depuis un tag Float ou Int32 |
| Tout autre type d'objet | le type de donnée du tag | Float un Real, Boolean un booléen, Int32 un entier signé, String une chaîne de caractères |

Aucune priorité de commande n'est envoyée avec l'écriture. Une valeur que l'objet ne peut pas
porter, comme 0 pour un objet multi-état ou 2 pour un objet binaire, est refusée avant tout
envoi, et le refus en donne la raison. Quand l'équipement répond à l'écriture par une erreur,
le tag rapporte la classe et le code d'erreur envoyés par l'équipement au lieu de feindre le
succès, et l'équipement reste connecté. Un nouveau tag démarre en Lecture seule.

## Découverte {#discovery}

Le bouton Découvrir du Connector diffuse un **Who-Is** BACnet et écoute les
réponses **I-Am** pendant 10 secondes. Chaque équipement qui répond devient un candidat
portant son adresse, son port et son numéro d'instance, prêt à ajouter avec les champs de
connexion remplis, et il apparaît dans la liste dès qu'il répond plutôt qu'à
la fin des dix secondes : un balayage que vous annulez à mi-chemin garde tout ce qui avait
déjà répondu. Le balayage ne parcourt pas les objets, si bien que les candidats arrivent avec zéro
tag ; ajoutez vous-même les paires type d'objet et instance.

Le Who-Is part sur le réseau que désigne la carte **Portée du balayage**. Sa case
prend une adresse IPv4 de ce réseau, celle d'un équipement ou celle de cet ordinateur
sur ce réseau (par exemple `192.168.1.20`), et le balayage ne diffuse alors que sur ce
réseau. Laissée vide, le Who-Is part sur tous les réseaux de cet ordinateur : un
ordinateur avec deux cartes réseau, un VPN ou Docker trouve ainsi les équipements de
chacun. Ce qui n'est pas une adresse IPv4 écrite en entier est refusé sous la case, et
Découvrir reste grisé tant que ce n'est pas corrigé.

Un équipement qui répond **à travers un routeur BACnet** s'ajoute de la même façon. Son
candidat porte l'adresse du routeur et, à côté, le réseau propre de l'équipement
et son adresse sur ce réseau ; les deux sont conservés quand vous l'ajoutez, et chaque lecture est envoyée
au routeur en nommant l'équipement à l'intérieur. Un équipement trouvé ainsi se lit donc
comme un autre, et son endpoint indique « équipement via routeur ». Un équipement ajouté à la main
n'a pas de route et est joint directement sur son hôte.

## Bon à savoir {#good-to-know}

- BACnet/IP seulement : un matériel MS/TP ou BACnet/SC n'est joignable qu'à travers un
  routeur qui le présente en BACnet/IP, et c'est le balayage qui le trouve : la route
  sur laquelle un équipement répond est conservée depuis le balayage, ajoutez-le donc depuis la liste découverte
  plutôt qu'en tapant ses champs à la main.
- Sur un ordinateur doté de plusieurs interfaces réseau (deux cartes réseau, un
  VPN, Docker), chaque équipement est joint par l'interface vers laquelle cet
  ordinateur route son adresse, celle que tout autre programme ici utiliserait ; il
  n'y a rien à choisir.
- Seul le socket qui écoute les messages des équipements occupe le port UDP BACnet
  standard 47808 sur cette station, si bien qu'une autre application BACnet qui tient
  ce port de façon exclusive sur le même ordinateur peut entrer en conflit avec lui.
  Les requêtes vers un équipement partent d'un port que le système choisit pour chaque
  client.
- La scrutation est fixée à une seconde pour chaque tag de ce pilote ; les champs habituels de
  période de scrutation ne sont pas affichés.
