Il y a quelques mois, nous avons écrit un article qui expliquait comment piloter l'ouverture de Velux à l'aide d'une interface KLF 200. Cette semaine, nous allons améliorer ce système en ajoutant un panneau de contrôle.
Pour rappel, dans notre précédent article nous avions utilisé deux Yocto-MaxiPowerRelay pour piloter l'interface Velux KLF 200 qui elle-même contrôlait l'ouverture et la fermeture des fenêtres de la pièce. L'objectif initial était d'ouvrir les fenêtres si le taux de CO2 dépassait un certain seuil.
Ce système fonctionne toujours, mais avec les premières chaleurs nous avons voulu ajouter un panneau de contrôle qui permette de piloter manuellement l'ouverture et la fermeture des fenêtres.
Ce panneau de contrôle a deux boutons qui permettent d'ouvrir et de fermer toutes les fenêtres, et un écran qui affiche la température de la pièce et le taux de CO2.
Le panneau de contrôle
Pour réaliser ce panneau de contrôle, nous avons utilisé un Yocto-MaxiDisplay, un Yocto-Meteo-V2 et un YoctoHub-Wireless-n. Le Yocto-MaxiDisplay est parfait pour ce type d'application, car en plus de l'écran il possède 6 entrées analogiques sur lequel on peut brancher des boutons. Le Yocto-Meteo-V2 nous permet d'obtenir la température ambiante. Notez que l'on aurait pu utiliser n'importe quel autre capteur de température Yoctopuce, comme le Yocto-Temperature qui est moins cher.
Afin de pouvoir placer le panneau de contrôle n'importe où, nous avons branché ces modules sur un YoctoHub-Wireless-n.
Les modules composant le panneau de contrôle
Une fois les modules montés, il faut configurer le YoctoHub-Wireless-n à l'aide du VirtualHub pour qu'il se connecte au réseau WiFi local.
Adapter le code
Grâce à à la structure logique des modules Yoctopuce, nous avons pu facilement modifier le code pour intégrer ce panneau de contrôle.
La première modification a été d'inclure les fichiers des fonctions qui sont utilisées par le panneau de contrôle, à savoir YDisplay, YTemperature et YAnbutton.
from yocto_api import *
from yocto_relay import *
from yocto_carbondioxide import *
from yocto_display import *
from yocto_temperature import *
from yocto_anbutton import *
La deuxième est d'appeler la méthode YAPI.RegisterHub pour chaque YoctoHub. Dans ce cas précis, l'adresse des YoctoHubs est prise du ficher de configuration.
if YAPI.RegisterHub(hub, errmsg) != YAPI.SUCCESS:
sys.exit("Unable connect to %s : %s" % (hub, errmsg.value))
Nous avons ensuite ajouté une méthode refreshDisplays qui affiche la température courante ainsi que le taux de CO2 mesuré. Afin d'éviter les problèmes de scintillement (flickering) durant de la mise à jour des informations, nous avons utilisé deux layers: un layer qui est toujours caché et un layer qui est toujours affiché. Le code "dessine" le texte sur le layer qui est caché et quand tout est prêt, la méthode swapLayerContent permute le contenu des deux layers.
for disp in self.displays:
if not disp.isOnline():
continue
try:
# retrieves the display size
w = disp.get_displayWidth()
h = disp.get_displayHeight()
# retrieves the first layer
l1 = disp.get_displayLayer(1)
l1.hide()
l1.clear()
l1.selectFont("Large.yfm")
if self.temperature.isOnline():
msg = "%.1d %s" % (self.temperature.get_currentValue(),
self.temperature.get_unit())
else:
msg = "Unk"
# displays a text in the middle of the screen
l1.drawText(w / 2, h / 4, YDisplayLayer.ALIGN.CENTER, msg)
if self.co2sensor.isOnline():
msg = "%.1d %s" % (self.co2sensor.get_currentValue(),
self.co2sensor.get_unit())
else:
msg = "Unk"
# displays a text in the middle of the screen
l1.drawText(w / 2, h / 4 * 3, YDisplayLayer.ALIGN.CENTER, msg)
l1.selectFont("Small.yfm")
l1.drawText(0, 0, YDisplayLayer.ALIGN.TOP_LEFT, "%d" % self._alive_counter)
self._alive_counter += 1
if self._alive_counter >= 10:
self._alive_counter = 0
disp.swapLayerContent(3, 1)
except YAPI_Exception:
print("unable to display information on " + disp.get_friendlyName())
Pour gérer les boutons, nous avons écrit un petit objet VeluxButton qui permet d'encapsuler proprement la gestion du callback des entrées analogiques du Yocto-MaxiDisplay. Pour chaque bouton de l'écran à gérer, il faut instancier un objet VeluxButton en lui passant le hardwareId de l'entrée, le pointeur sur le contrôleur de Vélux et la commande à effectuer (open ou close).
def __init__(self, controler, cmd, targets, hwid):
self._controler = controler
self._cmd = cmd.lower()
self._target = targets
self._anButton = YAnButton.FindAnButton(hwid)
self._anButton.registerValueCallback(self.anButtonCB)
def anButtonCB(self, anbutton, value):
if sef._controler.isVerbose():
print("AnCB:" + anbutton.get_hardwareId() + "=" + value)
if int(value) != 0:
# value != 0 meant that the button is pressed
if (self._cmd == 'open'):
self._controler.open(self._target, True)
elif self._cmd == 'close':
self._controler.close(self._target, True)
Pour finir, nous avons modifié la boucle principale afin d'ajouter l'appel à notre méthode refreshDisplays ainsi qu'à la méthode YAPI.Sleep qui va attendre 1 seconde et appeler les callbacks anButtonCB des objets VeluxButton. Pour plus d'informations sur les mécanismes de callback, vous pouvez consulter notre article sur le sujet.
# starts with all Velux closed
self.close([], True)
self.manually_open = False
if self.verbose:
print("Co2 limit is set to %d ppm" % self.co2_open_limit)
# display clean up
for disp in self.displays:
if (disp.isOnline()):
disp.resetAll()
while True:
self.refreshDisplays()
if self.co2sensor.isOnline():
value = self.co2sensor.get_currentValue()
if value > self.co2_open_limit:
self.open([], false)
elif value < self.co2_close_limit and not self.manually_open:
self.close([], false)
YAPI.UpdateDeviceList()
YAPI.Sleep(1000)
Nous avons détaillé uniquement les parties du code qui interagissaient avec la librairie Yoctopuce, mais le code complet est disponible sur GitHub: https://github.com/yoctopuce-examples/velux_controler.