mercredi 19 novembre 2014

Un exemple de script Lua | Time : Verifier la présence de matériel IP

Introduction

Il y a quelqu'un dans le réseau ?

Vérifier la présence sur le réseau IP de son domicile présente plusieurs intérêts :
  • Vérifier qu'une caméra IP est en marche.
  • Vérifier qu'un NAS/Raspberry est disponible.
  • Savoir si une personne présente en testant la présence de son téléphone !

The machine that goes 'Ping!'

Ping est une commande informatique présente sur tous le systèmes utilisant le réseau IP. Cette commande permet de tester l'accessibilité d'une machine à travers le réseau. Le nom 'ping'  est tiré du son émis par un sonar, car le fonctionnement est le même : on émet un signal qui va rebondir sur une cible, et donc nous revenir en cas de présence (pour les tatillons ce n'est pas le même principe, car la cible doit répondre activement ... ). 

Une analogie toute bête :
  1. Pour savoir si mon ami Robert est présent dans le coin (mon réseau) je crie : "Ping robert ?"
  2. Si robert est là, il répond : "Moi, Robert je suis là" !
  3. S'il n'est pas là (ou pas en état de répondre ) : aucune réponse.

Mise en place 

Principe  :

Je vais fournir une ou plusieurs adresses IP a tester, et si cette adresse répond présent je vais allumer ou éteindre un interrupteur virtuel.

Préparation :

  • Vérifier que les machines à tester ont une adresse IP Fixe.

  • Créer autant de virtual switch qu'il y a de matériel à tester.

  • Récupérer la liste des couples : adresse IP -> switch à activer si présent.
    • 192.168.0.100  -> Camera 1.
    • 192.168.0.101 -> Camera 2.
    • 192.168.0.200  -> Téléphone de Robert.
    • .....

Le script :

à Placer dans le repertoire LUA, sous le nom : script_time_ping.lua par exemple

--Initialise la commande de retour finale
commandArray={}


--Mode deboggage (affichage des messages)
debug=true
--Prefixe pour les sorties de log
prefixe="(PING) "


--Tableau des périphériques à "pinguer"
-- Key = adresse ip à pinguer
-- Value = périphérique virtuel à switcher
local ping={}
ping['192.168.0.200']='Presence Tom'
ping['192.168.0.201']='Presence Steph'
ping['192.168.0.20']='Presence Camera Interieure'
ping['192.168.0.21']='Presence Camera Exterieure'
ping['192.168.0.100']='Presence Raspberry'

--pour chaque entree du tableau
for ip, switch in pairs(ping) do

 --Le Ping ! : -c1 = Un seul ping  ,   -w1 délai d'une seconde d'attente de réponse
 ping_success=os.execute('ping -c1 -w1 '..ip)


 --Si le ping à répondu 
 if ping_success then
   if(debug==true)then
    print(prefixe.."ping success "..switch)
   end
   --si le switch etait sur off on l'allume
   if(otherdevices[switch]=='Off') then
      commandArray[switch]='On'
   end
 else

 --Si pas de réponse
   if(debug==true)then
    print(prefixe.."ping fail "..switch)
   end
   --si le switch etait sur oN on l'eteind
   if(otherdevices[switch]=='On') then
      commandArray[switch]='Off' 
   end
 end


end




return commandArray

lundi 28 juillet 2014

Un exemple de script Lua | Time : Cohérence et confirmation RFXCOM

LE 433mhz: pourquoi ? 


 Le RFXTRX 433mhz de RFXCOM est un outil permettant de communiquer avec des modules en 433 Mhz.

Avantage : leur prix (compter 15€ pour un module ON/OFF).

Inconvénient : Ces modules n'ont pas de retour d'état, c'est à dire qu'il est impossible de savoir si la commande que l'on vient d'envoyer à bien fonctionné (ou pas ) ...

 Il convient de ne pas lier des objets critiques à ce genre de modules, histoire de ne pas mettre le feu à la maison !

 Pour ma part, j'ai relié via ces modules quelques objets :
  • Radiateurs électriques pour gestion du chauffage. 
  • Contrôle de la VMC. 
  • Sondes de Température et Hygrométrie des chambres.

Un premier but : Vérifier la cohérence.

En domotisant ma VMC, il m'est arrivé de drôles de choses : ma vmc étant sensée s'éteindre en heures pleines continuait de tourner plein pot !
Comme nos chers modules 433 MHz n'accusent pas réception, il va falloir de temps en temps renvoyer la commande dans laquelle ils sont sensés être.
Pour cela nous allons utiliser les scripts LUA, surtout sous la forme "TIME" (c'est à dire déclenchée par le temps à certaines périodes).

Concrètement mon script fait ce qui suit :


  • Prend les éléments d'une liste à vérifier.
  • Regarde dans quel état l'élément est sensé être.
  • Renvoi le signal dans lequel l'élément est sensé être.
Deuxième But : Verifier l'âge des mesures de température.

Pour réduire la facture de domotisation, l'utilisation de sondes Oregon Scientific réduit considérablement la facture. Cependant il est difficile de savoir quand le module est à court de piles.
Mon script va donc vérifier l'age des dernières mesures de chaque sonde , et m'envoyer un mail dès que l'âge est supérieur à une valeur.

Voici le Fameux script :



--Permet toutes les 15 minutes de renvoyer la commande actuelle sensée etre appliquée aux modules en 433 ( sans retour d'etat )


commandArray = {}

--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
hours=tonumber(os.date('%H',time))

print('!*!*!*!*!*!*!*!*!Lancement du check à '..hours..'h'..minutes)


-------Toutes les 15 minutes
------------------------------------------------------------------------

if( (minutes==15) or (minutes==0) or (minutes==30) or (minutes==45) ) then



 --------Renforcement des envois de signal-------------------------------------
 ------------------------------------------------------------------------------
   print('check de tous les materiels rfxcom (sans retour d\'etat)');


   local check={}
   --Chauffage
   check['0']='Radiateur Mathilde'
   check['1']='Radiateur Parents'
   check['2']='Radiateur Salle De Bain'
   --VMC
   check['3']='VMC'
   --Lumieres
   check['4']='Lumiere TV'
   check['5']='Lumiere Salle De Jeu'
   --Piscine
   check['6']='Filtration Piscine Temp'

   --Parcours le Tableau
   for key, valeur in pairs(check) do
      print ('CHECK : '..valeur.. ' -> ' ..otherdevices[valeur])
      commandArray[valeur]=otherdevices[valeur]
   end


 --------FIN Renforcement des envois de signal-------------------------------------
 ------------------------------------------------------------------------------




end 

-------FIN Toutes les 15 minutes
------------------------------------------------------------------------

-------Une fois par heure, verifie l'age des mesures

if((minutes==0) or (minutes==1) ) then

    local temp={}
    --temperatures
    temp['0']='Mathilde'
    temp['1']='Parents'
    temp['2']='Salle De Bain'
    temp['3']='Salon'
    temp['4']='Meteo'
    --temp['4']='Entree'

    --delai au dela duquel on alerte en secondes
    local alerte=3600

    local mail='Alerte sur sonde temperature'
    local trigger=0

       --Parcours le Tableau de stemperatures
   for key, valeur in pairs(temp) do

                        s = otherdevices_lastupdate[valeur]
   -- returns a date time like 2013-07-11 17:23:12
                        t1 = os.time()
   year = string.sub(s, 1, 4)
   month = string.sub(s, 6, 7)
   day = string.sub(s, 9, 10)
   hour = string.sub(s, 12, 13)
   minutes = string.sub(s, 15, 16)
   seconds = string.sub(s, 18, 19)

   commandArray = {}

   t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
   difference = (os.difftime (t1, t2))

             
      print ('CHECK Temperature: '..valeur.. ' -> ' ..otherdevices[valeur].. ' age = '..difference..' secondes')
             
             if(difference > alerte)then
                mail=mail..'Age de '..valeur .. '-> '..difference..' secondes !!
'
                trigger=trigger+1  
             end
      
   end
 if(trigger>0)then
    commandArray['SendEmail']='Alerte Age Sonde Temperature #Attention aux sondes suivantes :

'..mail..' #gruelt@gmail.com'
        end


end









return commandArray


Explications partie Renvoi de signal

--recupere les minutes
time=os.time()
minutes=tonumber(os.date('%M',time))
hours=tonumber(os.date('%H',time))

Au début du script on récupère l'heure système actuelle ( dans time) , et on extrait les chiffres des minutes et des secondes.
local check={}
   --Chauffage
   check['0']='Radiateur Mathilde'
   check['1']='Radiateur Parents'
   check['2']='Radiateur Salle De Bain'
   --VMC
   check['3']='VMC'
   --Lumieres
   check['4']='Lumiere TV'
   check['5']='Lumiere Salle De Jeu'
   --Piscine
   check['6']='Filtration Piscine Temp'


Ici j'initialise ma variable "check" , sous forme de tableau avec les deux accolades.Chaque ligne représente le nom du périphérique que je veux renforcer.
for key, valeur in pairs(check) do
Cette ligne permet d’exécuter le code suivant ( jusqu'au "end" associé ) une fois par périphérique. key = index dans le tableau ( 1 , 2 , 3 ...). valeur = centenu de la ligne du tableau ( 'Radiateur Mathilde' ....). check = nom du tableau parcouru.
      commandArray[valeur]=otherdevices[valeur]
Tout simplement : Je récupère l'état du périphérique courant, et je force le renvoi de l'état dans lequel il est sensé être. Et c'est fini pour cette partie !

mercredi 23 avril 2014

Un exemple de script Lua | device: Alarme Simple

Un des arguments m'ayant fait pencher vers domoticz est la possibilité d'utiliser un langage de script : Lua ( http://www.lua.org/ ). En effet Blocky est gentil pour les petites automatisations, mais trouve très vite ses limites dès que l'on veut chercher un peu plus loin que "si bouton 1 = allumer lumière".

Où sont les scripts ?

Les scripts se situent dans votre répertoire d'installation de domoticz, dans scripts/lua . Pour ma part cela donne /home/pi/domoticz/scripts/lua ).
Dans ce repertoire ce situent deux scripts exemples : script_time_demo.lua et script_device_demo.lua

A savoir que les scripts contenant comme dernier mot "demo" sont ignorés par le système. Il peut être judicieux d'aller consulter le contenu de ces scripts pour se donner une première idée.

Qui déclenche les scripts ?

Il existe deux méthodes de déclenchement :
  • Device : le changement d'état d'un périphérique. Lorsque je presse un bouton sur ma télécommande ou que mon capteur de mouvement détecte une présence, cela induit un changement d'état : le système va donc parcourir tous les script débutant par script_device_xxxx.lua et executant leur contenu. Nous verrons par la suite comment utiliser ces scritps.
  • Time : Le déclenchement est basé sur le temps. Pour ceux qui connaissent le monde Unix on peu assimiler cette partie aux taches planifiées dans Cron. Pour faire simple : le script peut se déclencher sans requérir de changement d'état. Le script de demo présente une manière simple de tester si une porte de garage est ouverte depuis plus de 10 minutes, et ainsi de notifier par mail de cet état. Il n'y a donc pas de changement d'état déclenchant ce script, juste le temps.

Un exemple : une alarme simple

  • Dans cet exemple je pars ce cette configuration initiale, notez bien que la casse est très importante !
Voici le fameux script que nous allons décrypter un peu plus bas :


commandArray = {}



if ((otherdevices['Alarme'] == 'On') and (devicechanged['Motion Salon'] == 'On' or devicechanged['Motion Couloir'] == 'On')) then
   --recupere qui a change
   mydevice="rien"
   if(devicechanged['Motion Salon']=='On')then
      mydevice = "Salon"
   end
   if(devicechanged['Motion Couloir']=='On')then
      mydevice = "Couloir"
   end

   --notifie l'android via NMA
   commandArray['SendNotification']='Alarme '..tostring(mydevice)..'#Mouvement detecte avec alarme activee ! !!'
   commandArray['SendEmail']='Alarme '..tostring(mydevice)..'#Attention alarme activee#yourmail@gmail.com'
   print('Detection sur alarme activee : '..tostring(mydevice))
end

return commandArray


Ligne par ligne :
commandArray = {} 
: Initialise le tableau de commandes qui va être retourné en fin de script. Tous les scripts débutent ainsi.
if ((otherdevices['Alarme'] == 'On') and (devicechanged['Motion Salon'] == 'On' or devicechanged['Motion Couloir'] == 'On')) then 
:  La boucle d'entrée vérifiant que les conditions sont réunies.
devicechanged contient les données sur l'élément ayant changé d'état ( et qui a donc ainsi déclenché le lancement du script). otherdevices contient les données des autres éléments , qui eut n'ont pas changé d'état. Cette ligne vérifie que si
  • Le switch "alarme" est bien en état activé.
  • Et que soit "Motion Salon" ou "Motion Couloir" ont changé d'état en passant à "On".
commandArray['SendNotification']='Alarme #Mouvement detecte avec alarme activee ! !!'
Ajoute Au tableau de commandes retournée en fin de script l'envoi d'une Notification Via NotifyMyAndroid.
commandArray['SendEmail']='Alarme#Attention alarme activee#tonmail@gmail.com'
   print('Detection sur alarme activee : '
Ajoute Au tableau de commandes retournée en fin de script l'envoi d'une Notification Via Mail. Formalisme : " TITRE DU MAIL#CONTENU DU MESSAGE#mail destinataire. Et voici notre premier script, qu'il ne reste plus qu'à renommer en script_device_alarme.lua ! Une alarme vous notifiera des mouvements , du moment que le virtual switch "alarme" est sur "on".



jeudi 13 mars 2014

Domoticz : Un virtual switch pour les heures creuses EDF

Un des premiers but de la domotique étant d'optimiser sa consommation d'énergie, il peut être intéressant de connaitre à l'instant T si nous sommes en période pleine ou creuse de tarification EDF.
Les intérêts sont multiples pendant les heures creuses: mise en marche d'un chauffe eau, démarrage programmé d'un seiche linge, filtration de la piscine .... Autant d'économies sur la facture à la fin du mois ! Ce n'est pas une solution écologique, mais uniquement économique ! (On consomme autant d'énergie, mais la facture est moins élevée). Dans mon cas les heures pleines sont facturées 0.1009 €  le KW/h, et les heures creuses 0.1467 €  le KW/h , soit une différence de environs 30 % !

Nous allons Suivre les étapes de création d'un interrupteur, qui changera d'état en fonction de l'heure dans la journée. Ce procédé n'est valide que si vous connaissez les plages horaires d'heures creuses EDF. Nous pourrons ensuite utiliser ce switch dans nos scripts LUA et Blocky.

Mise en place du Matériel Virtuel (Dummy)

Domoticz utilise un système de référentiel sur le matériel : la création d'un matériel permet d'importer des modules. Par exemple pour utiliser des périphériques RF433mHz, il faut déclarer un RFXCOM, qui permettra de faire apparaître les périphériques (A voir dans un futur article)....
Ici notre but est de créer un faux matériel, qui permettra de générer des périphériques virtuels.

Le type "Dummy" n'est lié à aucun matériel physique.
  1. Configuration.
  2. Périphériques.
  3. Sélectionner "Dummy" et lui donner un Nom.
  4. Ajouter.
  5. Et voilà !

Création du Switch Virtuel

Nous allons pouvoir ajouter à la main notre switch. Tout se passe dans la section "Interrupteurs".
  1. Interrupteurs.
  2. Ajout Manuel (en haut a gauche de la liste des périphériques).
  3. Sélectionner en Hardware le périphérique virtuel créé  plus haut.
  4. Sélectionner "Switch type" : On/Off.
  5. Laisser les autres champs par défaut.
  6. Add device.

Notre Switch apparaît dans la liste des interrupteurs !

Planification des basculement d'état

Dans mon cas je dispose de 3 plages Horaires en heures creuses :
  • 3h00   -  7h00
  • 12h30 -  14h30
  • 20h30 - 22h30
Ces plages sont intéressantes, car étalées sur la journée. Je peux donc par exemple me permettre de filtrer ma piscine plusieurs fois par jour !
Pour planifier le changement d'état de l'interrupteur, il faut utiliser le bouton "Planning" de l'interrupteur concerné (en violet dans l'image précédente).

Le concept est simple, donner des ordres en fonction de la date/l'heure, ou même le lever/coucher du soleil. J'utilise la même astuce pour un virtual switch indiquant s'il fait jour/nuit.

Pour que mon virtual switch passe automatiquement en heure creuse à 3H00 :
  • Type : On Time
  • Heure : 03 : 00
  • Commande : Off ( = Heure creuse)
  • Quand : Tous les jours.
  • Ajouter.
Pour que mon virtual switch passe automatiquement en heure pleine à 7H00 :
  • Type : On Time
  • Heure : 07 : 00
  • Commande : On ( = Heure pleine)
  • Quand : Tous les jours.
  • Ajouter.
Au final, l'implémentation de mes plages horaires donne ceci :


En consultant les logs, on voit bien que le basculement se fait automatiquement aux heure indiquées :



Le virtual swicth est fonctionnel, il ne reste plus qu'à l'utiliser dans nos scripts !

mercredi 12 mars 2014

domoticz + Raspberry + Razberry !

Décevante Zipabox

Après une courte période d'essai de 4 mois avec une "prometteuse" Zipabox, je l'ai finalement revendue. Pourquoi ?
Les Tweets en disent long sur la maturité.
  • La réactivité laissait vraiment à désirer (dommage la lampe du corridor qui s’allume une fois que l'on est parti ) . 
  • Le mode "Cloud Only" m'est vraiment insupportable tellement la dépendance aux serveurs de Zipato est grande.
  • La maturité de la box est proche de la Beta publique payante.
  • Chaque mise à jour de la box entraîne la perte de certains modules aléatoirement.
  • Les opérations de maintenance quasi quotidiennes empêchent d'utiliser ses modules domotique : Je me suis retrouvé devant mon portail qui restait en position fermée à cause d'une opération de maintenance à 19H00... Obligé d'attendre 15 minutes dans la voiture .... 
  • Les opérations sont faciles mais ultra limitées : le faut d'appeler une URL avec un paramètre faisait parti des services premium. Imaginez que vous achetiez une voiture, mais que pour ouvrir les fenêtres ou le coffre il faille payer un service premium au constructeur. Agaçant n'est-ce pas ?

Et après ? Vera 3 ? Fibaro Home center 2 ? Lite ? Domoticz ?

Les box domotiques concurrentes se bousculent en se positionnant sur des secteurs très particuliers. Chacune dispose de ses forces et de ses faiblesses : Dépendance au cloud, ergonomie, prix , "bidouillabilité", réactivité de l'interface. Je me suis donc penché sur le sujet en pondant ce comparatif rapide entre les différents élus niveau box: Vera 3, Fibaro Home center 2 et Fibaro Home center Lite.Et de loin une autre solution : Domoticz + Razberry.


Fibaro Home Center 2 : Le luxe à 600 €
 Fibaro Home Center 2 : 599 €

  • Points Forts
    • La réactivité.
    • Matériel au dessus de la concurrence
    • Compatibilité avec les modules Fibaro.
    • Interface bien finie.
    • La possibilité d'utiliser le langage de script Lua.
  • Points Faibles
    • Le Prix (599 € !) .
    • Impossibilité d'utiliser les périphériques RF433mHz.


Fibaro Home center Lite : 279€

Home center allégée du LUA. Dommage.
  • Points Forts :  
    • Compatibilité avec les modules Fibaro.
    • Interface bien finie.
    • Prix plus accessible que le Home center 2(279€).
  • Points Faibles :
    •  Impossibilité d'utiliser le langage de script Lua (Bridage Logiciel).
    • Impossibilité d'utiliser les périphériques RF433MHz.
    • Matériel bien en dessous de sa grande soeur.
Vera Control Ltd Vera 3 : 238€
Non, ce n'est pas un vieux switch 3COM.
  • Points Forts :  
    • Compatible Wifi, incluant un Switch Ethernet.
    • Ecosystème de plugins fourni.
    • Bonne compatibilité avec les modulesFibaro.
    • Compatible RF433MHz via RFXCOM.
    • Langage de script LUUP.
    • Réputée box du "bidouilleur".
  • Points Faibles : 
    • Quelques lenteurs d'interface.
    • Interface un peu vieillissante.
    • A priori va être remplacée courant 2014 par les modèles "Plus" et "Pro".
    • Langage LUUP semi propriétaire.
Domoticz+Raspberry+Razberry : 0€ + 32€ +  59 € = 91 € !
  • Points Forts :  
    • Basé sur des logiciels libres !
    • Très faible consommation de courant : Environs 4 Watts. (< 5 Euro par ans).
    • Grande puissance des scripts : LUA, Bash , PHP, batch pour Windows ...
    • Développement actif.
    • Idéal pour le bidouilleur.
    • Interface RF433MHz  via rfxcom.
    • Le prix !
    • Très bon système de graphes/Logs.
  • Points Faibles : 
    • Nécessite de bonnes notions système Linux.
    • Interface Razberry/Domoticz un peu obscure de prime abord.
    • Nécessite pas mal de paramétrage.
    • Besoin d'acheter un boitier, une carte SD ( 4Go classe 10) et une alimentation en plus. 

Mon scénario initial n'arrivant pas à se dessiner, il m'était impossible de choisir une box, sachant que toutes disposent à ce jour de contraintes bloquantes pour moi. Je décide donc en attendant de relancer mon Razberry en y installant Domoticz en surcouche. Cela va faire maintenant une semaine, et je songe sérieusement a ne pas commander de box dédiée tellement je suis emballé !

Je vais donc tenter de vous partager mon expérience sur ce prometteur système domotique.