David Annebicque | @DavidAnnebicque
Maître de Conférences en Automatique et Informatique Industriel.
Activité de recherche au CReSTIC
Chef du département MMI (Métiers du Multimédia et de l'Internet) de l'IUT de Troyes
Développeur passionné depuis plus de 20ans ...
Technologies .Net, Développement Web
Adepte du C#, de Symfony (PHP), VueJS (HTML/JS)
Membre de l'Afup | Traducteur de la document officielle PHP
@DavidAnnebicque | davidannebicque.fr
4 séances de 3 heures
Un projet noté
Piloter et superviser une maison domotisée à l'aide de C#
HomeIO dispose d'une DLL permetant de lire et écrire les valeurs de l'ensemble des capteurs et actionneurs de la maison.
HomeIO utilise le concept de MemoryMap pour sauvegarder les données de la maison. Cette MemoryMap est mise à jour en permanence par HomeIO qui indique les valeurs des capteurs, et lit les valeurs des actionneurs.
The MemoryMap class is a Singleton, meaning that only one instance can exist at any given time. This instance represents a Cached Copy of the memory mapped file;
The MemoryMap.Instance.Update() method is responsible for synchronizing your cached copy with the memory mapped file. This method must be called every time you want to access the latest I/O points or receive event notifications.
Ce dossier contient la DLL (engineio.dll), des exemples (à étudier), et un explorateur (écrire en C#) pour voir l'état des capteurs/actionneurs.
using System;
using System.Threading;
using EngineIO; //import the HomeIO dll
namespace EngineIO.Samples
{
class Program
{
//In this sample we are switching the living room light on and off 10 times.
static void Main(string[] args)
{
//We are using a MemoryBit which we get from the MemoryMap.
//You can find all the memory addresses at the Memory Addresses page.
MemoryBit livingRoomLight = MemoryMap.Instance.GetBit(0, MemoryType.Output);
for (int i = 0; i < 10; i++)
{
livingRoomLight.Value = !livingRoomLight.Value;
//When using a memory value before calling the Update method we are using a cached value.
Console.WriteLine("Light is on? " + livingRoomLight.Value);
//Calling the Update method will write the livingRoomLight.Value to the memory map.
MemoryMap.Instance.Update();
Thread.Sleep(1000);
}
//When we no longer need the MemoryMap we should call the Dispose method to release all the allocated resources.
MemoryMap.Instance.Dispose();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
L'écriture se fait donc très simplement :
La lecture d'une zone de la MemoryMap est différente selon le type de données attendu
On va implémenter le grafcet suivant, permettant d'allumer une lampe depuis un intérrupteur de type bouton poussoir.
$$ ft1 = X1 . \uparrow bp $$
$$ ft2 = X2 . \uparrow bp $$
$$ X1 = ft2 + X1 . \overline{ft1} $$
$$ X2 = ft1 + X2 . \overline{ft2} $$
On va définir un timer (à la candence d'un API), qui tournera en continu et simulera un cycle d'API
Récupération d'une entrée (capteur, bouton, ...)
bool bp = MemoryMap.Instance.GetBit(adresseDuComposant, MemoryType.Input).Value;
Récupération d'une sortie (actionneur, lampe, porte, ...)
MemoryBit lampe = MemoryMap.Instance.GetBit(adresseDuComposant, MemoryType.Output);
//lampe contient l'adresse. Pour accéder à la valeur, il faut utiliser la propriété Value;
Les extraits de code ci-après suppose que les déclarations sont effectuées. Le code ne concerne que la méthode qui est éxécutée cycliquement par le timer.
Nommons cette méthode :
private void runCycleApi()
this.bpPrec = this.bp;
this.bp = MemoryMap.Instance.GetBit(adresseDuComposant, MemoryType.Input).Value;
Un front montant correspond à un capteur faux sur l'état précédent et vrai maintenant.
this.front = ! this.bpPrec && this.bp;
this.ft1 = this.X1 && this.front;
this.ft2 = this.X2 && this.front;
this.X1 = this.ft2 || this.X1 && ! this.ft1;
this.X2 = this.ft1 || this.X2 && ! this.ft2;
En fonction des actions associées aux étapes.
this.lampe.Value = X2; //on active la lampe que sur l'étape 2
Cette dernière étape est spécifique à HomeIO et n'est pas une étape d'un cycle API traditionnel.
MemoryMap.Instance.Update();
Sous réserve que le timer soit nommé timer1.
private void timer1_Tick(object sender, EventArgs e)
{
runCylceApi();
}
On peut intégrer un bouton sur l'interface afin de déclencher le timer.
Ce bouton aura aussi pour fonction d'initialiser le grafcet, en mettant à faux les fonctions de transfert, à faux les étapes, et à vrai la ou les étapes initiales.
L'objectif va être de développer notre propre DLL permettant de faire le lien entre la DLL d'HomeIO et notre projet.
L'objectif étant de se simplifier la manipulation de la MemoryMap
Pour tester cette DLL, on pourra créer un projet de type Form basique, ou console.
Il existe plusieurs approches pour cette DLL. Choisissez ou imaginez celle que vous preferez.
Ouverture des stores d'une pièce.
Proposer une commande qui lors de l'appui sur l'interupteur du volet permet de lever le volet jusqu'en haut, sauf si l'utilisateur appuie de nouveau sur le bouton.
Pilotage de la porte de garage.
Cahier des charges : un appui sur le bouton 1 de la télécommande ouvre la porte du garage, après une temporisation de 5 secondes en position ouverte, la porte se referme. Lors de la fermeture, si on appuie une nouvelle fois sur le bouton 1 ou, si le détecteur infrarouge présent au niveau de la porte du garage détecte un passage, la porte s’ouvre à nouveau. Ce cycle est répété tant que la porte du garage n’est pas fermée.
On pourra fortement s'inspirer du grafcet donnée sur ce lien
Pilotage de la porte de garage et du portail
Cahier des charges : Un appui sur le bouton 1 de la télécommande ouvre la porte du garage et le portail simultanément, après une temporisation de 5 secondes en position ouverte pour la porte du garage et 1 seconde pour le portail, chaque porte se referme. Une fois la porte et le portail refermés le cycle reprend au départ et attend un appui sur le bouton 1.
On pourra fortement s'inspirer du grafcet donnée sur ce lien
Simuler en fonction de l'heure de la présence dans la maison (ouverture des stores le matin, fermeture le soir, gestion de l'éclairage, ...)
La supervision est une technique industrielle de suivi et de pilotage informatique de procédés de fabrication automatisés. La supervision concerne l'acquisition de données (mesures, alarmes, retour d'état de fonctionnement) et des paramètres de commande des processus généralement confiés à des automates programmables.
Evaluation dans la dernière heure de la dernière séance. Les points pris en compte sont les suivants
Apportera des points supplémentaires