Page 1 sur 1

[LUA] Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 06 sept. 2017, 21:47
par Dim33
Bonjour,

Comme indiqué dans ce post https://easydomoticz.com/forum/viewtopi ... 449#p38449, vous trouverez ci-dessous mon script pour le chauffage d'une chambre.

Code : Tout sélectionner

--------------------------------
------ Variables à éditer ------
--------------------------------
nom = 'Chambre de X'  --Affichage dans le log
local consigne_normal = tonumber(otherdevices_svalues['Thermostat_Normal_Chambre'])  -- Température de consigne mode travail
local consigne_vacances = tonumber(otherdevices_svalues['Thermostat_Vacances_Chambre'])  -- Température de consigne mode congés à la maison
local consigne_abs = tonumber(otherdevices_svalues['Thermostat_Absent'])  -- Température de consigne lors d'abscence prolongée
local consigne_eco = tonumber(otherdevices_svalues['Thermostat_Eco'])  -- Température de consigne mode absence courte durée

local sonde = 'Sonde_Chambre_X' -- Nom de la sonde de température
local mode = 'Mode_Chauffage' -- Nom de l'interrupteur virtuel de sélection de mode Normal-Vavances-Absent-Eco
local hysteresis = 0.5

local radiateurr = 'Radiateur_Réel_X' -- Nom de l'interrupteur réel de chauffage
local radiateur = 'Radiateur_X' -- Nom de l'interrupteur virtuel de chauffage
local compteur = 'oui'   -- oui ou non si gestion de la consommation
local puissance = 1000   -- puissance du chauffage en watt
local conso = 'Conso_Chambre_X'   -- nom du capteur virtuel de consommation électrique
local conso_id = 50  -- idx du capteur virtuel de consommation électrique
local reset = false  -- force la mise à zero de la consomation instantané (laisser à false pour un fonctionnement normal) true/false

local temps = 120 -- temps en seconde si sonde ne repond pas --
local modeAlarme = 'sondeBis'  -- action à effectuer si il y a une alarme sonde:
                    -- choisir 'on' pour que le chauffage reste allumé, ou 'off' pour qu'il soit éteint
                    -- ou choisir 'sondeBis' pour utiliser une autre sonde de température (par ex une située dans une autre pièce) 
local sondeBis = 'Sonde_Chambre_Y' -- nom de la sonde de remplacement pour le mode sondeBis
   
local EmailTo = 'mon.email@xxxxx.xxx' -- adresse mail où seront envoyées les notifications, si plusieurs séparer par ;
local objet = 'Domoticz - Alerte Sonde le '
local envoiMail = 'mail_sonde_X' -- nom de la variable utilisateur gérant l'envoi des alertes

local user = 'xxxxxx'            -- A remplacer par identifiant Free Mobile
local pass = 'xxxxxx'      -- A remplacer par la clé d'identification au service SMS Free

--------------------------------
-- Fin des variables à éditer --
--------------------------------
 
commandArray = {}
 
------------------------------------ 
--- Gestion de l'alarme de sonde ---
------------------------------------
 
time = os.date("*t")  

function timedifference(d)
   s = otherdevices_lastupdate[d]
   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)
   t1 = os.time()
   t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
   difference = os.difftime (t1, t2)
   return difference
end
 
cumul_power = 0   -- initialisation de la puissance instantanee des radiateurs en fonctionnement

local lastSeen = timedifference(sonde)

if (lastSeen > temps)  then
   alarmeSonde = 1
   else
   alarmeSonde = 0
   commandArray['Variable:'..envoiMail] = tostring (0)
end


-- on récupère la valeur de envoiMail
mailEnvoye = tonumber(uservariables[envoiMail])

if (mailEnvoye==0) and (alarmeSonde == 1) then envoyerAlerte = 1 end
if (mailEnvoye==1) and (alarmeSonde == 1) then envoyerAlerte = 0 end
if (mailEnvoye==0) and (alarmeSonde == 0) then envoyerAlerte = 0 end
if (mailEnvoye==1) and (alarmeSonde == 0) then envoyerAlerte = 0 end
   
----------------------------------
--- Gestion de la température ----
----------------------------------
local temperature = tonumber(string.sub(otherdevices_svalues[sonde],1,4)) -- Température relevée
    
-- Adaptation de la consigne suivant le mode choisi --
if (otherdevices[mode] == 'Normal') then consigne = consigne_normal end
if (otherdevices[mode] == 'Vacances') then consigne = consigne_vacances end
if (otherdevices[mode] == 'Absent') then consigne = consigne_abs end
if (otherdevices[mode] == 'Eco') then consigne = consigne_eco end
if ((otherdevices[Jour_ferie] == 'On') and (otherdevices[mode] == 'Normal')) then consigne = consigne_vacances end

if (temperature < (consigne-hysteresis)) then
   
      commandArray[radiateurr]='Off' -- Radiateur allumé : gestion fil pilote
	  commandArray[radiateur]='On' -- Radiateur virtuel pour afficher sur le tableau de bord que le radiateur est allumé
	  status = 1
      print('Chauffage ' .. nom .. ' -. ON .-')          
         
elseif (temperature > (consigne+hysteresis)) then
      
      commandArray[radiateurr]='On'
	  commandArray[radiateur]='Off'
	  status = 0
      print('Chauffage ' .. nom .. ' -. OFF .-')
	  print('il fait '..temperature..'°C pour une consigne de '..consigne..'°C dans la ' .. nom)

end
   
-- Radiateur est ON mais il y a une alarme sonde
   
if (otherdevices[radiateur]=='On') and (alarmeSonde == 1) then
            
      if modeAlarme == 'off' then
         print ('Extinction du chauffage :'..nom)
         commandArray[radiateurr]='On'
		 commandArray[radiateur]='Off'
		 status = 0
         -- on envoi un mail sauf si c'est déjà fait
         if envoyerAlerte == 1 then
            print ('Alerte sonde, envoi d\'un mail et SMS')
            objet = 'Alerte chauffage '..nom..' '
            message = 'Impossible d\'allumer le chauffage'..nom..' - Problème avec la sonde de la '..nom', inactive depuis plus de '..(temps/60)..' minutes.'
			DateMail = os.date('%d/%m/%Y à %H:%M:%S', os.time())
            commandArray['SendEmail']=objet..DateMail..'#'..message..'#'..EmailTo		
            commandArray['Variable:'..envoiMail] = tostring (1)
			os.execute("curl -s 'https://smsapi.free-mobile.fr/sendmsg?user="..user.."&pass="..pass.."&msg="..message.."'")
                  
         else 
            print ('Alerte sonde, mail déjà envoyé')
         end
		 
elseif modeAlarme == 'sondeBis' then 
         print ('Alerte sonde, mode sonde bis')
         if envoyerAlerte == 1 then
            print ('Alerte sonde, envoi d\'un mail et SMS')
            objet = 'Alerte chauffage '..nom..' '
            message = 'Problème avec la sonde de la '..nom..', inactive depuis plus de '..(temps/60)..' minutes. Passage en mode sonde bis. La sonde utilisée est : '..sondeBis
            DateMail = os.date('%d/%m/%Y à %H:%M:%S', os.time())
            commandArray['SendEmail']=objet..DateMail..'#'..message..'#'..EmailTo
            commandArray['Variable:'..envoiMail] = tostring (1)
			os.execute("curl -s 'https://smsapi.free-mobile.fr/sendmsg?user="..user.."&pass="..pass.."&msg="..message.."'")
                  
         else 
            print ('Alerte sonde, mail déjà envoyé')
         end
         local temperature = tonumber(string.sub(otherdevices_svalues[sondeBis],1,4))
         if (temperature < (consigne - hysteresis)) then
             print('Allumage du chauffage :'..nom)
             commandArray[radiateurr]='Off'
			 commandArray[radiateur]='On'
			 status = 1
                        
         elseif (temperature > (consigne + hysteresis)) then
            print('Extinction du chauffage:'..nom)
         commandArray[radiateurr]='On'
		 commandArray[radiateur]='Off'
		 status = 0
         end
            
      elseif modeAlarme == 'on' then
         print ('Alerte sonde, mode ON')
         print ('Allumage du chauffage :'..nom)
         commandArray[radiateurr]='Off'
		 commandArray[radiateur]='On'
		 status = 1
         -- on envoi un mail sauf si c'est déjà fait
         if envoyerAlerte == 1 then
            print ('Alerte sonde, envoi d\'un mail et SMS')
            objet = 'Alerte chauffage '..nom..' '
            message = 'Allumage permanent du chauffage'..nom..' - Problème avec la sonde de la '..nom..', inactive depuis plus de '..(temps/60)..' minutes.'
            DateMail = os.date('%d/%m/%Y à %H:%M:%S', os.time())
            commandArray['SendEmail']=objet..DateMail..'#'..message..'#'..EmailTo			
            commandArray['Variable:'..envoiMail] = tostring (1)
			os.execute("curl -s 'https://smsapi.free-mobile.fr/sendmsg?user="..user.."&pass="..pass.."&msg="..message.."'")
                  
         else 
            print ('Alerte sonde, mail déjà envoyé')
         end
      end
      
      
end
      
   
-- Radiateur est OFF et il y a une alerte sonde   
   
if (otherdevices[radiateur]=='Off') and (alarmeSonde == 1) then
            
      print ('Extinction du chauffage :'..nom)
      commandArray[radiateur]='Off'
	  commandArray[radiateurr]='On'
	  status = 0
      -- on envoi un mail sauf si c'est déjà fait
      if envoyerAlerte == 1 then
         print ('Alerte sonde, envoi d\'un mail et SMS')
         objet = 'Alerte chauffage '..nom
         message = 'Problème avec la sonde de la '..nom..', inactive depuis plus de '..(temps/60)..' minutes.'
         commandArray['SendEmail']= objet..'#'.. message .. '#' .. EmailTo		 
         commandArray['Variable:'..envoiMail] = tostring (1)
		 os.execute("curl -s 'https://smsapi.free-mobile.fr/sendmsg?user="..user.."&pass="..pass.."&msg="..message.."'")
                  
      else 
         print ('Alerte sonde, mail déjà envoyé')
      end
      
end
  
----------------------------------
--- Gestion de la consommation ---
----------------------------------

if (compteur == 'oui') then
     -- calcul de la conso (npower = puissance actuelle / energy = puissance cumulee)

      npower, energy = string.match(otherdevices_svalues[conso], "(%d+%.*%d*);(%d+%.*%d*)") -- extraction des valeurs stockees dans le device conso
	     
      if (status == 1) then  -- le radiateur est allume
         cumul_power = tonumber(cumul_power + puissance)
	     energy = tonumber(energy + (puissance / 60))   -- puissance journaliere cumulee		
      else                   -- Le radiateur est eteint
         energy = tonumber(energy)
      end   
      
      power = tonumber(cumul_power)                  -- puissance instantanee	       
         
   -- envoi de la conso dans le capteur virtuel d'énergie
   
     if (reset) then
       power = 0
       energy = 0
     end

   commandArray['UpdateDevice'] = conso_id .. '|0|' .. power .. ';' .. energy   
end
   
return commandArray
Pour faire simple, mon script permet :

* De gérer 4 modes (4 thermostats avec un planning différent) :
- Normal (boulot en semaine)
- Vacances (présent à la maison, planning identique au weekend mais tous les jours)
- Eco (absent mais pas trop longtemps 1 jour ou 2)
- Absent (absence prolongée)
Le choix du mode passe par un Switch Selector.

* Si une sonde ne répond pas (envoi d'un SMS et d'un mail), 3 possibilités : bascule sur la sonde de la chambre d'a coté, arrêt du chauffage ou maintien sur On. Pour l'instant, mon script tourne avec la bascule sur une autre sonde.

* De Mesurer la conso de la pièce.

J'ai également rajouté un script pour les jours fériés (switch Jour_ferie passe à ON) pour que ça bascule automatiquement en mode Vacances (si mode Normal activé).

Le but de ce post est double :
- partager mon script,
- optimiser ce script et le modifier de façon intelligente pour qu'il gère trois chambre plutôt que d'avoir trois scripts (un par chambre).

Dans l'attente de vos suggestions.

Merci d'avance.

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 10 sept. 2017, 16:30
par Snake29
Bonjour,

Et merci pour le partage de ton script.
Je fonctionnais depuis l'hiver dernier avec un script similaire, mais avec des fonctionnalités en moins.

J'ai testé ton script, hormis la partie mail / SMS que j'ai supprimé car elle ne m'intéresse pas pour le moment.


J'ai cependant quelques questions.

1- Concernant le capteur virtuel de conso.
- Quel type (utilisation ou inst. + compteur) + et quels paramètres (utilisation / retour et computed / from device) ?

Car de mon côté, l'énergie cumulée grimpe de façon astronomique (genre 15 kWH en 45 sec sur un radia 1000W).


2- Quelle séquence pour le script ?
- Time ou device ?

Mon ancien script fonctionnait en device et se lançait donc à chaque mise à jour de la sonde de tempé.

Je continue à tester tout ça en tous cas
Merci d'avance,

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 10 sept. 2017, 20:56
par Dim33
Bonjour,

Content que mon script puisse servir.

1/ Inst+compteur / Utilisation / From device

2/ Time

@+

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 11 sept. 2017, 08:35
par Snake29
Merci à toi ;)

Cela fonctionne, mon bug venait du fait que je n'étais pas en "time" mais en "device" pour le déclenchement du script.

Je suis dans la même config que toi, à savoir que j'ai 4 pièces à gérer de cette façon.
Il faut que j'optimise tout cela...

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 11 sept. 2017, 14:29
par vil1driver
Salut,
Dim33 a écrit :(...) le modifier de façon intelligente pour qu'il gère trois chambre plutôt que d'avoir trois scripts (un par chambre).
(...)
Mieux vaut plusieurs scripts qu'une usine à gaz..

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 11 sept. 2017, 16:02
par DreamL
Bonjour

Je pense que tu peux facilement gérer autant de pièce que tu le désires simplement en ajoutant une liste de pièce avec un paramétrage par pièce

Exemple plus bas d'un script que j'ai réalisé pour paramétrer des alertes par capteur avec différent paramètre de notification par capteur.

ex

Code : Tout sélectionner

local ListeAction={}  --Purement informatif, ne sert qu'a définir l'action correspondante
ListeAction[1] = '1ere notif si open apres '
ListeAction[2] = 'Repeter la notif si open tous les '
ListeAction[3] = 'Nombre maxi de répétition mail & sms'  --0 pas de limite
ListeAction[4] = 'Notif son si Open '
ListeAction[5] = 'Notif son si closed '



local ListeOuverture={} --Nom du capteur = {timer 1ere notification en minute,timer repeat  en minute ,Nb max envoi notif, Fichier son si interrupteur On, Off }
ListeOuverture['Contact porte frigo'] = {2,2,3,'portefrigo_on.mp3','portefrigo_off.mp3'}
ListeOuverture['Contact porte congélateur'] = {2,2,3,'portecongelo_on.mp3','portecongelo_off.mp3'}
ListeOuverture['Contact porte de garage'] =  {5,10,3,'portegarage_on.mp3','portegarage_off.mp3'}
--ListeOuverture['TEST'] = {2,2,4,'portefrigo_on.mp3','portefrigo_off.mp3'}

ensuite dans le corps


for device in pairs(ListeOuverture) do
	--Tu accèdes au paramètre de la liste de cette manière
	
	ListeOuverture[device][1] --recupere la durée pour 1ere notif
	ListeOuverture[device][2] --recupere la durée pour répetition
	etc...

end

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 11 sept. 2017, 21:11
par Dim33
vil1driver a écrit :Salut,
Dim33 a écrit :(...) le modifier de façon intelligente pour qu'il gère trois chambre plutôt que d'avoir trois scripts (un par chambre).
(...)
Mieux vaut plusieurs scripts qu'une usine à gaz..
Effectivement, mais dans mon cas, la consigne de T° est identique, les plannings sont identiques, la puissance des radiateurs est identique bref tout est pareil hormis :
- le nom de la sonde
- le nom du module de commande de chaque radiateur
- le compteur électrique virtuel (1 pour chaque chambre)

Je pense qu'un script pour les chambres (3) et un pour la pièce vivre serait plus logique et cohérent.

Pour DreamL : désolé mais j'ai rien compris à ton exemple. Faut que j'approfondisse....

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 11 sept. 2017, 22:43
par DreamL
J'ai été un peu brute dans mon explication

en gros du définie une liste avec pour chaque objet de ta liste, une structure correspondante.

--Tu définies tes pièces ( A gauche du = ) dans une liste avec les paramétrages pour chaques pièces ( A droite du = )
local PiecesDeLaMaison={}
PiecesDeLaMaison['Chambre1'] = {'NomSonde1','NomModule1','NomCompteur1'}
PiecesDeLaMaison['Chambre2'] = {'NomSonde2','NomModule2','NomCompteur2'}
PiecesDeLaMaison['Chambre3'] = {'NomSonde3','NomModule3','NomCompteur3'}

--Ensuite tu parcours ta liste avec la boucle for (pratique dans un script_time)

for piece in pairs(PiecesDeLaMaison) do
--Tu accèdes au paramètre de la liste de cette manière

PiecesDeLaMaison[piece][1] --recupere le nom de la sonde de la chambre 1
PiecesDeLaMaison[piece][2] --recupere le nom du module de la chambre 1
etc...
--ensuite la boucle passe à la seconde pièce et ainsi de suite
end

j'espère que j'ai été plus clair

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 12 sept. 2017, 21:13
par Dim33
Bonjour et merci DreamL.

Effectivement c'est un peu plus clair mais il faut que je regarde d'autres script pour bien comprendre .....à moins que tu ai le temps de modifier le mien :mrgreen:

Re: Encore un ! Mon script pour la gestion d'un chauffage électrique

Publié : 13 sept. 2017, 17:32
par Snake29
J'ai juste fait quelques petites modifs...
- Ajout d'une condition d'exécution du script 'ssi' mon interrupteur virtuel de chauffage est en marche ;
- Modification de l'hysteresis car j'utilise une valeur à la mise en service et une valeur au stop (radiateurs à inertie...)
- Ajout d'une condition pour ne pas que le script renvoie un ordre de mise en marche si le radiateur est déjà allumé (idem si éteint) ;
- Ajout d'une vérification d'état du radiateur en début de gestion de conso, pour que l'item de conso se mettre à jour si on a stoppé le radiateur en "manu" (sans passer par le script)...


En tous cas pour le moment, cela fonctionne bien chez moi :)