Un capteur de lumière pour chatière connectée

Un capteur de lumière pour chatière connectée

Depuis quelques mois, un petit félin a élu domicile à côté de Yoctopuce et vient parfois nous rendre visite. Pour qu'il puisse entrer et sortir librement durant la journée, nous lui avons installé une chatière électronique à puce qui peut être contrôlée à distance. Au moment de l'installer, on se disait qu'il y aurait certainement un ou deux bricolages à faire avec des modules Yoctopuce, et ça n'a pas manqué...


La chatière connectée de Surepet, installée sur une fenêtre Le hub servant à raccorder la chatière à Internet
La chatière connectée Surepet Microchip Cat Door est pilotable via Internet grâce au petit hub en forme de chat.


Même si les chats sont à la base des animaux nocturnes, on recommande souvent de ne pas les laisser sortir la nuit: non seulement c'est là qu'ils ont le plus tendance à ramener des jouets encore vivants dans la maison, mais c'est aussi durant la nuit qu'ils sont le plus souvent victimes d'accidents. C'est pour cela que les fabricants de chatières automatiques proposent un mode couvre-feu - très d'actualité - permettant de bloquer la sortie des animaux sur une plage horaire définie.

La configuration du couvre-feu à heure fixe
La configuration du couvre-feu à heure fixe


Sauf que... entre le mois de septembre, où la chatière a été installée, et le mois de janvier, les horaires de la nuit ont passablement changé, et la chatière, elle, reste ainsi ouverte plusieurs heures après la tombée de la nuit et s'ouvre bien avant le lever du jour - et ce d'autant plus que le changement d'heure n'a pas été correctement pris en compte. Dommage! Nous vous proposons donc aujourd'hui une amélioration de cette chatière connectée, qui consiste simplement à utiliser un capteur de lumière ambiante pour adapter automatiquement les horaires d'ouverture tout au long de l'année.

Principe

Le principe est simple: quelque part dans la maison, un capteur Yocto-Light-V3 connecté au réseau mesure la luminosité extérieure. Le plus simple est de le monter directement sur un YoctoHub-Ethernet ou un YoctoHub-Wireless-n à proximité d'un point d'accès de réseau et d'une fenêtre. Ailleurs, un ordinateur de contrôle va périodiquement vérifier la luminosité ambiante et (dé)verrouiller la chatière en fonction de l'heure et de la lumière, en contactant le serveur de Surepet Care.

Contrôle de la chatière avec capteur de lumière
Contrôle de la chatière avec capteur de lumière



Conception

Une attention particulière doit être consacrée à la robustesse de la solution, et en particulier à la tolérance aux pertes de réseau qui sont inévitables. Nous allons donc profiter de ce projet pas très compliqué pour montrer

  • comment découpler de la logique de l'application les différentes interfaces vers l'extérieur, et
  • comment implémenter la logique de l'application avec une machine à états.

Le découplage permet de simplifier l'application en la découpant en composants qui peuvent être conçus, testés et documentés indépendamment les uns des autres. L'implémentation par machine à état permet de s'assurer que les différents états possibles du système sont clairement définis, et que tous les cas de transitions d'un état à l'autre sont gérés. Voici la conception que nous proposons:

Articulation du système de contrôle
Articulation du système de contrôle


Nous avons choisi d'effectuer l'implémentation en Node.js, mais ce code peut très facilement être traduit dans n'importe quel langage.

Interface vers le capteur de lumière

Pour être robuste, le code qui prend en charge la communication avec le capteur de lumière est prévu pour supporter à tout moment les connexions et déconnexions. Cela permet de gérer les pannes de réseau Wifi, les coupures d'électricité, etc. Par contre, comme on désire ne pas propager cette complexité vers l'application principale, tout est fait en interne dans cette interface, qui met directement à disposition de l'application la valeur de luminosité mesurée en [lux] la plus récente, ou -1 si aucune mesure récente n'est actuellement disponible.

Le capteur de lumière monté sur un YoctoHub Wi-Fi
Le capteur de lumière monté sur un YoctoHub Wi-Fi


La connexion passive avec le capteur de lumière branché au réseau Wi-Fi se fait à l'aide de la méthode YAPI.PreregisterHub(), qui n'exige pas de connectivité immédiate avec le capteur:

// Attempt to connect to the light sensor hub, without triggering
// an error in case the hub is momentarily not reachable
await YAPI.PreregisterHub(this.hubAddr, new YErrorMsg());


On active ensuite l'appel d'un callback dès qu'un capteur sera disponible, et dès que la connexion est perdue:

// Get a callback whenever the light sensor is connected or disconnected
await YAPI.RegisterDeviceArrivalCallback((m) => {
        this._deviceArrivalCallback(m);
});
await YAPI.RegisterDeviceRemovalCallback((m) => {
        this._deviceRemovalCallback(m);
});


Le callback de connexion de module détecte la présence d'un capteur de lumière Yoctopuce et le configure pour effectuer des mesures moyennées sur 30 secondes (2 mesures par minute):

async _deviceArrivalCallback(module)
{
    let product = await module.get_productName();
    let serial = await module.get_serialNumber();
    console.log('Yoctopuce device connected: '+product+' ('+serial+')');
    if(!product.match(/^Yocto-Light/)) return;

    // If a Yocto-Light(-V3) is found, get average luminosity twice per minute
    let sensor = YLightSensor.FindLightSensor(serial+'.lightSensor');
    await sensor.set_reportFrequency("2/m");
    await sensor.registerTimedReportCallback((s,m) => {
        this._lightSensorCallback(s,m);
    });
    // initialize current luminosity with current instant value
    this.currentLuminosity = await sensor.get_currentValue();
}


Lorsqu'une mesure est disponible, elle est sauvegardée dans une propriété du module pour être immédiatement disponible:

async _lightSensorCallback(sensor, measure)
{
    this.currentLuminosity = measure.get_averageValue();
    //console.log('Average luminosity: ' + this.currentLuminosity + ' lux');
}


Et lorsque qu'on perd la connexion avec le capteur de lumière, on le signale et on invalide la mesure de lumière. Si nécessaire, on pourrait améliorer la solution en associant une date de péremption à la mesure plutôt que de l'invalider immédiatement.

async _deviceRemovalCallback(module)
{
    let product = await module.get_productName();
    let serial = await module.get_serialNumber();
    console.log('Yoctopuce device disconnected: '+product+' ('+serial+')');
    if(!product.match(/^Yocto-Light/)) return;

    this.currentLuminosity = -1;
}


Le code complet de ce module de gestion du capteur de lumière est disponible dans le fichier light-sensor.js sur GitHub.

Interface vers la chatière connectée de Sure Petcare

Le code qui sert à interfacer la chatière connectée fonctionne selon le même principe: le programme contacte périodiquement le serveur de contrôle pour lire l'état de blocage actuel de la chatière, et met à disposition le dernier état connu de l'application principale. En effet, l'application ne peut pas supposer être la seule source de contrôle de la chatière: il se peut qu'une personne décide de verrouiller manuellement la chatière pour une raison ou une autre. Dans ce cas, l'application doit en tenir compte et ne pas la déverrouiller. Par contre, si le programme principal décide de changer l'état de blocage, la commande est mémorisée et sera envoyée lors de la prochaine connexion.

Les appels à l'API REST de Sure Petcare, à travers le serveur app.api.surehub.io, ont été implémentés sur la base d'une API similaire réalisée par Wylan Swets et publiée en licence MIT sur GitHub. Nous lui sommes très reconnaissant d'avoir fait tout le travail d'analyse des protocoles et d'avoir mis à disposition de tous le résultat. Nous avons néanmoins choisi de refaire notre propre implémentation en utilisant des appels async/await plutôt que le chaînage asynchrone par callback pour la lisibilité du code, et avec une interface de lecture découplée des appels réseau. Le code complet de notre interface de gestion de la chatière est disponible sur le fichier sure-petcare.js sur GitHub.

Application principale

L'application principale n'a donc à gérer que la logique des états, que nous avons modélisée en début de cet article. Il suffit de vérifier à intervalle régulier si une transition d'état est nécessaire, et de déclencher éventuellement une action correspondante. On utilisera quatre états principaux:

  • état NIGHT: Durant la nuit, la chatière est normalement en mode couvre-feu et rien ne se passe.
  • état MORNING: Le matin, on garde le mode couvre-feu jusqu'à-ce que la luminosité atteigne une valeur donnée. On passe alors en état DAYLIGHT.
  • état DAYLIGHT: La journée, rien ne se passe.
  • état EVENING: La soirée, on attend que la luminosité baisse sous une valeur donnée pour activer le mode couvre-feu et passer dans l'état NIGHT.

Chacun de ces états peut être terminé par une condition temporelle: l'heure limite de passage à l'état suivant. Cette heure correspond normalement à l'horaire de couvre-feu programmé dans l'interface utilisateur de surepetcare.io, qui garantit un comportement minimal adéquat même en cas de panne complète du système de régulation par la luminosité.

De plus, l'état MORNING et l'état EVENING peuvent être terminés par une condition de luminosité, déclenchant au passage l'activation ou la désactivation du couvre-feu sur la chatière, à une heure plus appropriée pour la saison. C'était bien le but original de cette application... Le code complet de l'application principale est disponible dans le fichier demo.js sur GitHub. C'est aussi dans ce fichier que vous pourrez configurer vos propres identifiants pour la connexion au serveur surepetcare, ainsi que les horaires de base que vous désirez appliquer.

Conclusion

Cette méthodologie de découplage et de machine à états pourrait paraître exagérée pour une application aussi simple. Mais lorsqu'on veut faire soi-même un système automatique avec une assurance raisonnable qu'il va bien fonctionner à long terme quels que soient les impondérables, c'est à notre avis la meilleure manière de procéder.

De plus, si vous décidez de reprendre ce projet à votre compte, vous aurez aussi plus de facilité à l'adapter à vos besoins que si tout était codé en une seule grosse fonction mélangeant traitement d'erreurs et transitions logiques.

Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.