Yadoms propose aujourd’hui 2 moyens d’écrire des règles d’automatisation : de façon graphique, ou sous forme de code (en langage Python). Ce second format est plus adapté aux règles complexes. Python est un langage simple à appréhender, et de nombreuses librairies permettant d’étendre les fonctionnalités du langage sont disponibles sur Internet.
Une alarme basique
Ici, nous avons voulu créer une règle gérant une alarme simple, dont les états sont :
- Désactivée : vous êtes chez vous, l’alarme est désactivée (c’est l’état initial)
- Armée : vous êtes sorti, l’alarme est activée
- Effraction : Une effraction a été détectée
Les transitions entre ces événements doivent être définies :
- Désactivée ==> Appui sur le bouton d’armement ==> Armée
- Armée ==> Présentation d’un tag RFID reconnu ==> Désactivée
- Armée ==> Ouverture d’une fenêtre/porte ==> Effraction
- Effraction ==> Présentation d’un tag RFID reconnu ==> Désactivée
Réalisation
Le plus élégant pour réaliser ce genre de règle, est d’utiliser une librairie de machine d’état. Nous allons utiliser ici la librairie transitions. Elle va nous permettre de définir les états, ainsi que les triggers (événements de transition), et les liens entre ces triggers et états.
Installation de la librairie
Suivant l’OS utilisé pour Yadoms, une règle (un script Python) n’est pas autorisée à installer une librairie, ce serait une faille de sécurité. Nous devons donc installer cette librairie en accédant à l’invite de commande de la cible. Notre exemple considère que Yadoms est installé sur une Raspberry Pi.
Au préalable, il nous faut connaître :
- l’adresse IP de la Raspberry Pi
- Savoir accéder en SSH à la Raspberry Pi et connaître les identifiants d’accès (voir ici si l’installation a été réalisée via notre image de carte SD)
Une fois connecté et identifié en SSH sur la Rapberry Pi, une ligne suffit à installer la librairie voulue :
sudo pip install transitions
Petite explication sur cette ligne de commande :
sudo
: exécution de la commande en tant que super-utilisateur (droits nécessaire à l’installation)pip
: outil de gestion de paquets de Pythoninstall
: indique à pip d’installer un paquettransitions
: est le nom du paquet à installer
Utilisation de la librairie dans notre règle
Il suffit ensuite d’importer la librairie dans le code de notre règle pour pouvoir l’utiliser.
Le code de la règle est le suivant :
import scriptUtilities
import datetime
# Import de la librairie 'transitions'
from transitions import Machine
from transitions import State
# Modèle de machine d'état (non utilisé dans notre exemple)
class StateMachineModel(object):
pass
def yMain(yApi):
# Définition des équipements utilisés pour notre alarme
# - Capteurs d'ouverture des fenêtres et portes
capteursOuverture = [
yApi.getKeywordId('Fenetre salle a manger', 'state'),
yApi.getKeywordId('Fenetre cuisine', 'state'),
yApi.getKeywordId('Porte entree', 'state')
]
# - Bouton d'armement
boutonArmement = yApi.getKeywordId('Telecommande alarme', 'event')
# - Tag RFID utilisé pour désarmement
tagRfidDesarmement = yApi.getKeywordId('Tag RFID #123', 'event')
# Définition de la machine d'état
stateMachine = StateMachineModel()
# - Liste des états
states = [ 'desactive', 'arme', 'effraction' ]
# - Définition des transitions entre les états
transitions = [
{ 'trigger': 'appuiBoutonArmement', 'source': 'desactive', 'dest': 'arme' },
{ 'trigger': 'tagRfidReconnu', 'source': 'arme', 'dest': 'desactive' },
{ 'trigger': 'ouvertureFenetre', 'source': 'arme', 'dest': 'effraction' },
{ 'trigger': 'tagRfidReconnu', 'source': 'effraction', 'dest': 'desactive' }
]
# - Création de la machine d'état, en spécifiant l'état initial
sm = Machine(model=stateMachine, states=states, transitions=transitions, initial='desactive', ignore_invalid_triggers=True)
# Boucle principale, gestion des événements
while True:
print "L'alarme est dans l'état", stateMachine.state
event = yApi.waitForNextAcquisitions([boutonArmement] + [tagRfidDesarmement] + capteursOuverture)
if event[0] is boutonArmement and event[1] == '1':
stateMachine.appuiBoutonArmement()
elif event[0] is tagRfidDesarmement and event[1] == '1':
stateMachine.tagRfidReconnu()
elif event[0] in capteursOuverture:
stateMachine.ouvertureFenetre()
Si cela est nécessaire, il faut installer pip dans certains cas. Suivez le tutos suivant dans ce cas :
https://www.raspberrypi.org/documentation/linux/software/python.md
PIP s’installe simplement par un appel à :
sudo apt-get install python-pip