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) doCette 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 !
Très bon script et très utile. Je vais l'implémenter car il est pas facile de faire une remontée d'alerte en cas de batterie faible sur un module.
RépondreSupprimerMerci
Je ne sais pas si le script est bon, mais il m'a aidé à réaliser le mien.....sauf qu'il ne fonctionne plus voici l'erreur retournée par le Log de domoticz"Error: Lua script did not return a commandArray" il était lancé par un contacteur de porte (chacon) j'ai dù le reconfigurer après un changement de pile (domoticz ne le reconnaissait plus) et depuis, même en supprimant son lancement, le Log me retourne l'erreur!!
RépondreSupprimerSi tu as une idée du problème !
Merci et continu sur les scripts, je ne trouve pas grand chose en français.
Est-ce qu'il y a bien au début "commandArray={}" et à la fin "return commandARRAY" , en respectant bien la casse ?
SupprimerSinon envoie mon ton script je le testerai de mon côté.
Thomas
Salut pascal, est-ce dans ton script il y a au tout début ( en respectant bien la casse) :
RépondreSupprimercommandArray = {}
qui te permet d'initialiser la variable renvoyée...
Et a la fin :
return commandArray
qui permet de retourner le fameux commandArray.
Sinon envois moi ton script je le testerai de mon côté.
Thomas
Merci de ta réponse, entre-temps, j'ai trouvé une partie de mon problème.
RépondreSupprimerEn reconfigurant mon contact de porte,.....je lui avais donné un nom différent que dans mon script.
Donc mon script refonctionne, mais j'ai toujours cette "Error: Lua script did not return a commandArray" dans le Log toutes les 30sc!!
Le script consiste à envoyer un sms (opérateur free) lorsque la porte est ouverte.
commandArray = {}
if (devicechanged['detecteur presence'] == ‘Open’) then
os.execute(‘curl -k “https://smsapi.free-mobile.fr/sendmsg?user=xxxxxxx&pass=xxxxxxx&msg=alerte ! “’)
end
return commandArray
Je l'ai mis dans la case "On action" mais j'ai rien mis en "Off action".
Aaaaaaaaaaaaaaaaaaaaah une vulgaire faute de frappe sur le "commandeArray = {}"
RépondreSupprimermais, le script fonctionnait quand même !
Bonjour,
RépondreSupprimersuper script, mais je ne comprends pas bien comment il fonctionne !
Je souhaiterais vérifier si une sonde température Oregon fonctionne.
Que fait exactement la ligne 42 de ton script ? A quoi correspond ce otherdevices ?
Merci de ton aide.
En fait le script est en 2 parties :
RépondreSupprimerLa première Vérifie que les appareils sont dans l'état ou ils devraient être : pour chaque appareil renseigné dans "check" , on regarde dans quel état il sont censés être ( on ou off ) et on renvoie le signal de cet état. L’intérêt ? Si pour X raison la lumière qui est censée être allumée ne l'est pas (interférence par exemple) , on renvoi l'information. Pour faire une analogie simple : Toutes les 15 minutes j'ai quelqu'un qui va aller se promener chez moi pour être sur que mes lumières/radiateurs sont bien dans l'état renseigné dans domoticz.
La deuxième partie, qui je pense est celle qui t’intéresse, vérifie à quand remonte la dernière mesure d'une sonde. Dans mon cas si l'age est trop élevé, il m'envoie un mail avec les sondes ayant une mesure trop "vieille".
La partie qui t’intéresse doit être celle de la ligne 57 jusqu'à la fin.
Au pire envoie moi le nom de tes périphériques, l'age maximal que tu veux pour une alerte , et je te ferais une adaptation du code.
Attention le nom des périphériques est sensible à la casse (majuscules/minuscules).
Bonjour et merci de ta réponse. Ci joint la version de mon script :
RépondreSupprimer--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) or (minutes>0) ) then
--------Renforcement des envois de signal-------------------------------------
------------------------------------------------------------------------------
print('__________ Check de tous les materiels rfxcom (sans retour d\'etat)')
local check={}
--Bureau
check['0']='Sonde bureau'
--Parcours le Tableau
for key, valeur in pairs(check) do
print ('CHECK : '..valeur.. ' -> ' ..devices[valeur])
commandArray[valeur]=devices[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']='Sonde bureau'
--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
Je cherche à contrôler l'état de la sonde de température "Sonde Bureau".
Merci de ton aide.
Si j'ai bien compris, c'est une sonde de température ?
SupprimerMon script permet de vérifier si l'age de la dernière mesure de la sonde est supérieur à une heure (paramétrable en secondes , à la ligne "local alerte=3600") et envoi un mail à la ligne commandArray['SendEmail'] . (D'ailleurs attendtion , dans ton script il envoie un mai là mon adresse en fin de ligne).
Bonjour,
Supprimerc'est bien ce que je souhaite faire. Je vais corriger l'email.
Voilà l'erreur que j'obtiens à l'exécution du script :
Wed Oct 1 11:56:55 2014 Error: /home/pi/domoticz/scripts/lua/script_device_agesondes.lua:25: attempt to index global 'devices' (a nil value)
Bonjour,
SupprimerAvez vous pu trouver quelque chose concernant mon erreur ?
D'autre part, j'utilise deux détecteur de fumée Chacon dont je souhaiterais surveiller la présence. Ce détecteurs ne communiquent que lorsqu'il y a une détection ou un test. Pensez vous qu'il soit possible de les surveiller avec un tel script ?
Merci d'avance.
Bonjour,
Supprimerj'ai un peu retravaillé le script, mais il ne fonctionne toujours pas !
Voilà le nouveau 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) or (minutes>0) ) then
--------Renforcement des envois de signal-------------------------------------
------------------------------------------------------------------------------
print('__________ Check de tous les materiels rfxcom (sans retour d\'etat)')
local check={}
--Bureau
check['0']='TH - Bureau'
check['1']='TH1 - Ext Veranda'
--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']='TH - Bureau'
temp['1']='TH1 - Ext Veranda'
--delai au dela duquel on alerte en secondes
local alerte=3600
local mail='Alerte sur sonde temperature'
local trigger=0
print("__________ suite bis")
--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
print ('__________ '..trigger)
if(trigger>0)then
commandArray['SendEmail']='Alerte Age Sonde Temperature #Attention aux sondes suivantes :'..mail..' #test@gmail.com'
end
end
return commandArray
Et voilà l'erreur que j'obtiens :
Script event triggered: /home/pi/domoticz/scripts/lua/script_device_agesondes.lua
Je ne comprends pas pourquoi ... Une idée ?
Ce commentaire a été supprimé par l'auteur.
RépondreSupprimerSalut François, désolé je suis bien pris en ce moment.
RépondreSupprimerVOici le script simplifié qui devrait faire le boulot chez toi.
J'ai supprimé la partie qui renvois le signal , car a priori ce n'est pas ton objectif.
Pour ce qui est des détecteurs de fumée, je n'ai pas vraiment de solution, car il s n'émettent pas de signal à aucun moment... c'ets d'ailleurs dommage.
Pour le script ci dessous, si tu as une erreur du genre :
Error: /home/pi/domoticz/scripts/lua/script_time_munier.lua:21: bad argument #1 to 'sub' (string expected, got nil)
C'est que le nom de tes périphériques n'est pas le bon (attention aux majuscules)
Pour tester toutes les minutes au lieu de toutes les heures, je t'invite à commenter les lignes 2 et 48.
-------Une fois par heure, verifie l'age des mesures
if((minutes==0) or (minutes==1) ) then
local temp={}
--temperatures
temp['0']='TH - Bureau'
temp['1']='TH1 - Ext Veranda'
--delai au dela duquel on alerte en secondes
local alerte=3600
local mail='Alerte sur sonde temperature'
local trigger=0
print("Verification des temperatures")
--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
print ('__________ '..trigger)
if(trigger>0)then
commandArray['SendEmail']='Alerte Age Sonde Temperature #Attention aux sondes suivantes :'..mail..' #test@gmail.com'
end
return commandArray
end
Bonjour et merci,
Supprimerje vais tester ça dés ce soir ...
Merci.
Bonjour,
RépondreSupprimerLe script est très bien fait. Je voulais l'aménager à ma sauce en rajoutant une condition : le script ne soit se déclencher qu'après 7h30 et à heures fixes.
J'ai donc mis :
if (((hours>=7) or (minutes>=30)) and ((minutes==0) or (minutes==1))) then
le code...
mais ça ne fonctionne pas ! Est-ce que je me trompe quelque part ? Qu'est ce que je fais mal ?
Merci
Pour que ton script fonctionne il faut prendre en compte aussi une heure de fin
Supprimerif ( ( hours >7 OR (hours==7 and minutes>=30) and ( hours <21) )
hours>=7 ---> s'il est au moins 8h00
OU
hours==7 ----> il est 7hxx ET minutes>=30 -> plus de 7H30
ET
hours<21 ---> Qu'il est moins de 21h00 ( pour faire une borne de fin)
Ce commentaire a été supprimé par l'auteur.
RépondreSupprimerSalut !
RépondreSupprimersuper script !
j ai un soucis, il ce lance toute les 1 minutes au lieu de 15 chez moi.
voici un peu de log :
2015-02-04 17:15:00 LUA: !*!*!*!*!*!*!*!*!Lancement du check � 17h15
2015-02-04 17:15:00 LUA: check de tous les materiels rfxcom (sans retour d'etat)
2015-02-04 17:15:00 LUA: CHECK : Platine Vinyle -> Off
2015-02-04 17:15:00 LUA: CHECK : TV Loisir -> Off
2015-02-04 17:15:00 LUA: CHECK : Anti Moustique Parents -> Off
2015-02-04 17:15:00 LUA: CHECK : Anti Mouche Salon -> Off
2015-02-04 17:15:00 LUA: CHECK : VMC Studio -> Off
2015-02-04 17:15:00 LUA: CHECK : Lumiere Coin TV -> Off
2015-02-04 17:15:00 Error: /home/pi/domoticz/scripts/lua/script_time_check.lua:55: attempt to concatenate field '?' (a nil value)
2015-02-04 17:15:00 Script event triggered: /home/pi/domoticz/scripts/lua/script_time_check.lua
2015-02-04 17:15:01 Schedule item started! Type: On Time, DevID: 291, Time: Wed Feb 4 17:15:01 2015
est ce que cela aide ?
Salut,
SupprimerLe script est en effet lancé toutes les minutes (tu dois voir "lancement du check à hh:mm" toutes les minutes dans les logs).
Mais le traitement n'est effectif que toutes les 15 minutes, à cause de la condition :
if( (minutes==15) .....
Tu ne dois voir que toutes les 15 minutes le message :
LUA: check de tous les materiels rfxcom (sans retour d'etat)
Sinon pour ton problème de script, on dirait que tu as une variable qui renvoie un caractère nul. Souvent la cause est que le peripherique n'existe pas dans domoticz (erreur de frappe , sensibilité à la casse , accents ...). Si tu veux envois moi ton script que je regarde si quelque chose cloche.
Merci pour ton script que jai hate de mettre en place. La derniere fois que j'ai voulu faire du Lua domoticz ignorait mes fichiers et depuis je me suis rabattu sur blocky. La logique voulant effectivement que s'il y a trop de if else et d'appareils, le rasp sature. Du coup je suis resté sur des commandes simples : à chaque changement d'état les commandes en vigueur sont renvoyées. En gros toutes les minutes.. c'est pas terrible mais ça fonctionne. Donc je ne sais pas si les Lua vont maintenant fonctionner mais ça permettrait de pas encombrer les ondes non stop grâce à des if else imbriquées, ce que blocky ne fait pas. Cela dit avec la logique que j'ai utilisé blocky marche très bien. Pour en revenir à la cohérence c'est super de comparer l'âge des update. Parce que bizarrement le symbole pile dans domoticz affiche vraiment n'importe quoi. 100% pour des piles déjà vider à 50% et Faible pour des piles neuves. Bref, y'a t il pas un bug ou un réglage à faire dans domoticz pour avoir enfin un état des piles correct ?
RépondreSupprimerCe commentaire a été supprimé par l'auteur.
RépondreSupprimer