[LUA] YASDC (Yes Another Script De Chauffage) !

Vous avez créé un script LUA dont vous êtes fier, un .sh génial, un programme Python hors du commun, un Tuto, c'est ici que vous pouvez les partager.
garycooper
Messages : 453
Inscription : 07 août 2017, 23:58

Re: YASDC (Yes Another Script De Chauffage) !

Message par garycooper »

Bonjour, tout d'abord merci pour le partage de ce script qui est très intéressant et correspond à ce que je recherche ! Je suis en train d'installer le script pour gérer le chauffage avec Domoticz et j'ai quelques difficultés interrogations :

Premièrement, j'ai l'erreur "bad argument #1 to 'match' (string expected, got nil)" à la ligne "npower, energy = string.match(otherdevices_svalues[conso], "(%d+%.*%d*);(%d+%.*%d*)")"
Ensuite, est-il possible de gérer tous les radaiteurs avec 1 seul calendrier (je voudrais limiter le nombre de switch) ?
Enfin, les signes "_" sont ils obligatoires ou peut-on mettre un espace à la place (c'est juste parce que je trouve plus lisible) ?

Désolé pour ces questions "lourdingues" mais je débute sur les scripts
denis_brasseur
Messages : 898
Inscription : 24 déc. 2018, 17:05
Localisation : (26)

Re: YASDC (Yes Another Script De Chauffage) !

Message par denis_brasseur »

Premièrement, j'ai l'erreur "bad argument #1 to 'match' (string expected, got nil)" à la ligne "npower, energy = string.match(otherdevices_svalues[conso], "(%d+%.*%d*);(%d+%.*%d*)")"
Tu a bien créé ton compteur sur ce modele ?

Nissa a écrit : 21 oct. 2016, 16:48 ....................................................
Et pour finir un compteur qui cumule la quantité d’énergie consommée à partir du « wattage » de chaque radiateur.
- Réglages/Matériel
 Créer capteurs virtuels
o Type de capteur : Electrique (Instant + Counter)
Image
Et nommé ainsi :

Code : Tout sélectionner

local conso = 'Chauffage_conso'         -- nom du capteur virtuel de consommation électrique (type= instant + counter)
Enfin, les signes "_" sont ils obligatoires ou peut-on mettre un espace à la place (c'est juste parce que je trouve plus lisible) ?
Si tu parle par exemple du nom du capteur virtuel de conso, tu peux le nommer Chauffage conso, à condition évidement de le nommer ainsi dans le code
Pi3 + DD PiDrive - RFXtrx433 - AEON Labs ZW090
garycooper
Messages : 453
Inscription : 07 août 2017, 23:58

Re: YASDC (Yes Another Script De Chauffage) !

Message par garycooper »

Du coup j'ai essayé de refaire le script avec les modifications suivantes :
retirer les "_" dans les noms d'interrupteurs et capteurs (juste pour l'esthétique)
gérer avec 1 seul calendrier de chauffage (appelé "Programmateur chauffage") et une seule consigne de thermostat valable pour tous les radiateurs.
Pour l'instant, c'est pas trop lourd parce que je n'ai domotisé que 2 radiateurs. Et ben malgré ça, j'ai réussi à me planter ... car il ne se passe rien ...
J'ai donc 3 thermostats : "Confort", "Eco", "Hors gel"
Un programmateur pour planification du thermostat en mode confort : "Programmateur chauffage"
Un interrupteur "Chauffage"
Un interrupteur "Radiateur chambre Dorian"
Un interrupteur "Radiateur SdB enfants"
Un capteur de température "Temperature chambre Dorian"
Un capteur de température "Temperature SdB enfants"

En plus qu'il ne se passe rien, j'ai l'erreur :
"2019-02-09 19:03:09.536 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_chauffage.lua: /home/pi/domoticz/scripts/lua/script_time_chauffage.lua:197: 'end' expected (to close 'for' at line 78) near <eof>"

La ligne 197 correspond à la dernière ligne

"mon" script est le suivant :

Code : Tout sélectionner

--[[ 
par Nissa MAJ du 19/11/2017
Ajout de la verification de l'état du poele avant action
Ajout de variables d'état pour rendre le code plus lisible

Type:          time
Name:          chauffage
Algorythme :
			Si Chauffage=ON et Programmateur chauffage=ON	
					Consigne=confort (22)
				sinon
					Consigne=eco(19)
				sinon   Consigne=hors gel(17)
							
NOTA : Ce script est volontairement tres verbeux afin d'avoir dans les logs le statut de chaque radiateur
(toutes les minutes !). On peut l eviter en initialisant la variable 'verbose' a false.  
Sinon, il est fortement conseille de commenter l option log de domoticz (dans domoticz.sh) afin de ne pas 
saturer l espace de stockage  par un fichier log trop important
--]]
 
----------------------------------------------
------          Configuration          ------
----------------------------------------------
local piece={}     -- Tableau Rajouter ici les radiateurs 
	piece['0']='chambre Dorian'
	piece['1']='SdB enfants'


local watt={}     -- Tableau Rajouter ici la puissance en watts du radiateur (L'index doit correspondre a celui de la piece ci-dessus)
	watt['0']='1250'
	watt['1']='1000'

local presence = 'Chauffage'
local calendrier = 'Programmateur chauffage'
	
-- consignes de thermostat virtuels
local consigne_confort = 'Confort'           
local consigne_eco = 'Eco'
local consigne_horsgel = 'Hors gel'
local conso = 'Consommation chauffage'         -- nom du capteur virtuel de consommation électrique (type= instant + counter)
local conso_id = 80                    -- 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 hysteresis = 0.4 					-- Valeur seuil pour éviter que le relais ne cesse de commuter dans les 2 sens
local debug = false 	                   -- true or false pour voir tous les messages debug dans le log
local verbose = true					   -- Print ou non des logs
-- email
local mail = 'xxxxx'  -- pour réception alerte sonde muette (chauffage coupé)

-- domoticz
local url = '192.168.x.xx:xxxx'         -- user:pass@ip:port de domoticz, pour la création des variables

----------------------------------------------
--       Fin de la partie configuration       --
----------------------------------------------

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)
   if  (year > '2000') and (year < '2099')
   and (month >= '01') and (month <= '12')
   and (day >= '01') and (day <= '31')
   and (hour >= '00') and (hour <= '23')
   and (minutes >= '00') and (minutes <= '59')
   and (seconds >= '00') and (seconds <= '59') then
   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

for key, valeur in pairs(piece) do
	-- Maj des variables en fonction de la valeur de la table 
	local le_radiateur_est_sur_ON = false      -- Etat du radiateur false ou true
  	local sonde_KO = false                     -- Sonde de temperature HS
	local sonde = string.format("%s%s", "Temperature ", valeur)                   -- Nom de la sonde de température
	local radiateur = string.format("%s%s", "Radiateur ", valeur)       -- Nom de l'interrupteur de chauffage
	log = '***'
	log2 = '***'
	
	local heure = string.sub(os.date("%X"), 1, 5)	-- Recuperation de l'heure du systeme
	local lastSeen = string.sub(os.date("!%X", timedifference(sonde)), 1, 5) 	-- Heure de la derniere releve de la sonde de temperature
	
	puissance=tonumber(watt[key])  -- Puissance en watt du radiateur
	
	commandArray = {}
	
	if (debug) then print ('>>>>>>>>>>>>>>>Initialisation '..puissance..' Radiateur>'..valeur)
	
----------------------------------------------
------         Alerte mail              ------
--     si la sonde est muette depuis 30'    --
----------------------------------------------

	if (lastSeen >= '00:30' and lastSeen < '00:32') then
		commandArray['SendEmail']='Domoticz Alerte#Alerte sonde chambre '..piece..' muette#'..mail
		if (debug) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Envoi mail probleme de sonde ') end
	end

----------------------------------------------
------          Gestion consigne        ------
----------------------------------------------
      
   -- récupération de la valeur du thermostat
   
    if (otherdevices[presence] == 'On') then 			-- si la presence est active (interrupteur manuel 'Chauffage')

		if (otherdevices[calendrier] == 'On') then 		-- ET calendrier ON (Programmateur chauffage)
			consigne = tonumber(otherdevices_svalues[consigne_confort])
		else
			consigne = tonumber(otherdevices_svalues[consigne_eco])
        end
    
	else     -- presence = OFF
		consigne = tonumber(otherdevices_svalues[consigne_horsgel])
	end

	if (debug) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Initialisation Consigne chambre '..valeur..' > '..consigne) end
	
   -- on récupère la température fournie par la sonde
   local temperature = otherdevices_temperature[sonde]
   	
    if (debug) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Recup valeur sonde chambre '..valeur..' > '..temperature) end

----------------------------------------------
--  Inititialisation des Variables d etat  --
----------------------------------------------

	if (otherdevices[radiateur] == 'On') then le_radiateur_est_sur_ON = true end 
	
	if lastSeen > '00:10' then 
		local sonde_KO = true 
		log2 = '***        Sonde muette '
	end

----------------------------------------------
------       Gestion du radiateur       ------
--- selon temperature relevee et consigne   --
----------------------------------------------
   
	if (le_radiateur_est_sur_ON) and not (sonde_KO) then
		log = '*** IF 1 >                        Le Radiateur est en marche'
		status = 1
		if temperature >= (consigne + hysteresis) then
			commandArray[radiateur]='Off'  
			log = '*** IF 2 >                    Arret du Radiateur'
			status = 0  -- Pour eviter le delai de la Maj du device (variable utilisee dans le if du calcul de conso)
		end
	else
		log = '*** IF 3 >                 Le Radiateur est arrete'
		status = 0
		if temperature <= (consigne - hysteresis) and not (sonde_KO) then
			commandArray[radiateur]='On'
			log = '*** IF 4 >                 Allumage du Radiateur'
			status = 1
		end
	end
		
	  -- 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[3]={['UpdateDevice'] = conso_id .. '|0|' .. power .. ';' .. energy}
   
   -- logs
   if (verbose) then
		print ' '
		print('********************* Chauffage '..valeur..' *********************')
		print('***                 Il fait '..temperature..'°C pour une consigne de '..consigne..'°C souhaités')
		print(log,log2)
		print('********************************************************************')
	end

end -- fin de tableau
return commandArray
Je sêche complètement ... En plus de cela, j'ai le bandeau des thermostas qui restent en rouge systématiquement. J'ai vu dans ce sujet un script pour l'enlever mais je n'ai pas compris s'il fallait créer un nouveau script ou si je pouvais l'intégrer directement dans celuis-ci.
Dernière modification par garycooper le 09 févr. 2019, 23:41, modifié 3 fois.
denis_brasseur
Messages : 898
Inscription : 24 déc. 2018, 17:05
Localisation : (26)

Re: YASDC (Yes Another Script De Chauffage) !

Message par denis_brasseur »

En plus qu'il ne se passe rien, j'ai l'erreur :
Il ne se passe rien, parce qu'il y a au moins 2 erreurs.

Il manque un end dans ta fonction

Code : Tout sélectionner

function timedifference(d)
puisque il y a un if.
A ajouter juste après

Code : Tout sélectionner

t1 = os.time()
Idem pour la ligne

Code : Tout sélectionner

if (debug) then print ('>>>>>>>>>>>>>>>Initialisation '..puissance..' Radiateur>'..valeur)
il manque un end à la fin puisque il y a un if.

Pour remplacer

Code : Tout sélectionner

if (debug) then print ('>>>>>>>>>>>>>>>Initialisation '..puissance..' Radiateur>'..valeur) end
tu peux utiliser cette fonction

Code : Tout sélectionner

function voir_les_logs (s, debugging)
	if (debugging ~= false) then 
		if s ~= nil then
			print (s);
		else
			print ("aucune valeur affichable");
		end
	end
end 
que tu utilise ensuite comme ceci

Code : Tout sélectionner

if (debug) then print ('>>>>>>>>>>>>>>>Initialisation '..puissance..' Radiateur>'..valeur) end
devient

Code : Tout sélectionner

voir_les_logs('>>>>>>>>>>>>>>>Initialisation '..puissance..' Radiateur>'..valeur,debugging)
Il faut au préalable avoir ajouter ceci en début de ton code

Code : Tout sélectionner

local debugging = false -- true pour voir les logs dans la console log Dz ou false pour ne pas les voir
Pi3 + DD PiDrive - RFXtrx433 - AEON Labs ZW090
garycooper
Messages : 453
Inscription : 07 août 2017, 23:58

Re: YASDC (Yes Another Script De Chauffage) !

Message par garycooper »

Terrible ! Ca marche nickel maintenant !

Merci !

Je poste le script "corrigé" si d'autres veulent aussi gérer leur chauffage électrique avec 1 seule consigne pour tous les radiateurs :

Code : Tout sélectionner

--[[ 
par Nissa MAJ du 09/02/2019
Ajout de la verification de l'état du poele avant action
Ajout de variables d'état pour rendre le code plus lisible

Type:          time
Name:          chauffage
Algorythme :
			Si Chauffage=ON et Programmateur chauffage=ON	
					Consigne=Confort (22)
				sinon
					Consigne=Eco(19)
				sinon   Consigne=Hors gel(17)
							
NOTA : Ce script est volontairement tres verbeux afin d'avoir dans les logs le statut de chaque radiateur
(toutes les minutes !). On peut l eviter en initialisant la variable 'verbose' a false.  
Sinon, il est fortement conseille de commenter l option log de domoticz (dans domoticz.sh) afin de ne pas 
saturer l espace de stockage  par un fichier log trop important
--]]
 
----------------------------------------------
------          Configuration          ------
----------------------------------------------
local piece={}     -- Tableau Rajouter ici les radiateurs 
	piece['0']='chambre Dorian'
	piece['1']='SdB enfants'


local watt={}     -- Tableau Rajouter ici la puissance en watts du radiateur (L'index doit correspondre a celui de la piece ci-dessus)
	watt['0']='1250'
	watt['1']='1000'

local presence = 'Chauffage'
local calendrier = 'Programmateur chauffage'
local debugging = false -- true pour voir les logs dans la console log Dz ou false pour ne pas les voir	
-- consignes de thermostat virtuels
local consigne_confort = 'Confort'           
local consigne_eco = 'Eco'
local consigne_horsgel = 'Hors gel'
local conso = 'Consommation chauffage'         -- nom du capteur virtuel de consommation électrique (type= instant + counter)
local conso_id = 80                    -- 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 hysteresis = 0.4 					-- Valeur seuil pour éviter que le relais ne cesse de commuter dans les 2 sens
local debug = false 	                   -- true or false pour voir tous les messages debug dans le log
local verbose = true					   -- Print ou non des logs
-- email
local mail = 'xxxxx'  -- pour réception alerte sonde muette (chauffage coupé)

-- domoticz
local url = '192.168.x.xx:xxxx'         -- user:pass@ip:port de domoticz, pour la création des variables

----------------------------------------------
--       Fin de la partie configuration       --
----------------------------------------------

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)
   if  (year > '2000') and (year < '2099')
   and (month >= '01') and (month <= '12')
   and (day >= '01') and (day <= '31')
   and (hour >= '00') and (hour <= '23')
   and (minutes >= '00') and (minutes <= '59')
   and (seconds >= '00') and (seconds <= '59') then
   t1 = os.time()
   end
   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

for key, valeur in pairs(piece) do
	-- Maj des variables en fonction de la valeur de la table 
	local le_radiateur_est_sur_ON = false      -- Etat du radiateur false ou true
  	local sonde_KO = false                     -- Sonde de temperature HS
	local sonde = string.format("%s%s", "Temperature ", valeur)                   -- Nom de la sonde de température
	local radiateur = string.format("%s%s", "Radiateur ", valeur)       -- Nom de l'interrupteur de chauffage
	log = '***'
	log2 = '***'
	
	local heure = string.sub(os.date("%X"), 1, 5)	-- Recuperation de l'heure du systeme
	local lastSeen = string.sub(os.date("!%X", timedifference(sonde)), 1, 5) 	-- Heure de la derniere releve de la sonde de temperature
	
	puissance=tonumber(watt[key])  -- Puissance en watt du radiateur
	
	commandArray = {}

function voir_les_logs (s, debugging)
	if (debugging ~= false) then 
		if s ~= nil then
			print (s);
		else
			print ("aucune valeur affichable");
		end
	end
end 	

voir_les_logs('>>>>>>>>>>>>>>>Initialisation '..puissance..' Radiateur>'..valeur,debugging)

----------------------------------------------
------         Alerte mail              ------
--     si la sonde est muette depuis 30'    --
----------------------------------------------

	if (lastSeen >= '00:30' and lastSeen < '00:32') then
		commandArray['SendEmail']='Domoticz Alerte#Alerte sonde chambre '..piece..' muette#'..mail
		if (debug) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Envoi mail probleme de sonde ') end
	end

----------------------------------------------
------          Gestion consigne        ------
----------------------------------------------
      
   -- récupération de la valeur du thermostat
   
    if (otherdevices[presence] == 'On') then 			-- si la presence est active (interrupteur manuel 'Chauffage')

		if (otherdevices[calendrier] == 'On') then 		-- ET calendrier ON (Programmateur chauffage)
			consigne = tonumber(otherdevices_svalues[consigne_confort])
		else
			consigne = tonumber(otherdevices_svalues[consigne_eco])
        end
    
	else     -- presence = OFF
		consigne = tonumber(otherdevices_svalues[consigne_horsgel])
	end

	if (debug) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Initialisation Consigne chambre '..valeur..' > '..consigne) end
	
   -- on récupère la température fournie par la sonde
   local temperature = otherdevices_temperature[sonde]
   	
    if (debug) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Recup valeur sonde chambre '..valeur..' > '..temperature) end

----------------------------------------------
--  Inititialisation des Variables d etat  --
----------------------------------------------

	if (otherdevices[radiateur] == 'On') then le_radiateur_est_sur_ON = true end 
	
	if lastSeen > '00:10' then 
		local sonde_KO = true 
		log2 = '***        Sonde muette '
	end

----------------------------------------------
------       Gestion du radiateur       ------
--- selon temperature relevee et consigne   --
----------------------------------------------
   
	if (le_radiateur_est_sur_ON) and not (sonde_KO) then
		log = '*** IF 1 >                        Le Radiateur est en marche'
		status = 1
		if temperature >= (consigne + hysteresis) then
			commandArray[radiateur]='Off'  
			log = '*** IF 2 >                    Arret du Radiateur'
			status = 0  -- Pour eviter le delai de la Maj du device (variable utilisee dans le if du calcul de conso)
		end
	else
		log = '*** IF 3 >                 Le Radiateur est arrete'
		status = 0
		if temperature <= (consigne - hysteresis) and not (sonde_KO) then
			commandArray[radiateur]='On'
			log = '*** IF 4 >                 Allumage du Radiateur'
			status = 1
		end
	end
		
	  -- 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[3]={['UpdateDevice'] = conso_id .. '|0|' .. power .. ';' .. energy}
   
   -- logs
   if (verbose) then
		print ' '
		print('********************* Chauffage '..valeur..' *********************')
		print('***                 Il fait '..temperature..'°C pour une consigne de '..consigne..'°C souhaités')
		print(log,log2)
		print('********************************************************************')
	end

end -- fin de tableau
return commandArray
Dernière modification par vil1driver le 11 févr. 2019, 18:01, modifié 2 fois.
Raison : Suppression email dans le script
denis_brasseur
Messages : 898
Inscription : 24 déc. 2018, 17:05
Localisation : (26)

Re: YASDC (Yes Another Script De Chauffage) !

Message par denis_brasseur »

Ta function voir_les_logs (s, debugging) ne doit pas être placé dans la boucle for key, mais avant, au niveau de l'autre fonction.

Idem pour

Code : Tout sélectionner

 
	commandArray = {}
cette ligne doit être placé en dehors de la boucle for key, avant.

La fonction voir_les_logs est destiné à remplacé tout les

Code : Tout sélectionner

if (debug) then print( 
afin d'éviter l'erreur d'oublier le end à la fin.

Inutile de ne l'utiliser qu'une seule fois, autant s'en passer dans ces conditions.


Ta fonction

Code : Tout sélectionner

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)
   if  (year > '2000') and (year < '2099')
   and (month >= '01') and (month <= '12')
   and (day >= '01') and (day <= '31')
   and (hour >= '00') and (hour <= '23')
   and (minutes >= '00') and (minutes <= '59')
   and (seconds >= '00') and (seconds <= '59') then
   t1 = os.time()
   end
   t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
   difference = os.difftime (t1, t2)
   return difference
end
dans laquelle tu a ajouté un test sur la valeur year, month day, hour, minutes et seconds ne te retourneras pas la valeur t1 = os.time() si les conditions ne sont pas respectées, la fonction te retournera donc une erreur.

Attention à l'utilisation de la variable log, j'utiliserais plutôt log1, il me semble que ça peux être autre chose qu'une variable nativement.

Idem pour le mot debug, utilise plutôt debugging par rexemple.

Pour l'utilisation de

Code : Tout sélectionner

Alerte mail             ------
--     si la sonde est muette depuis 30'
tu risque d’être notifié très souvent, ce qui était la cas chez moi.

Ta variable statut n'est pas déclaré et pas initialisé par défaut.

Attention également à l'utilisation de

Code : Tout sélectionner

commandArray[3]
Si je n'ai rien oublié, ceci est plus propre

Code : Tout sélectionner

--[[ 
par Nissa MAJ du 09/02/2019
Ajout de la verification de l'état du poele avant action
Ajout de variables d'état pour rendre le code plus lisible

Type:          time
Name:          chauffage
Algorythme :
			Si Chauffage=ON et Programmateur chauffage=ON	
					Consigne=Confort (22)
				sinon
					Consigne=Eco(19)
				sinon   Consigne=Hors gel(17)
							
NOTA : Ce script est volontairement tres verbeux afin d'avoir dans les logs le statut de chaque radiateur
(toutes les minutes !). On peut l eviter en initialisant la variable 'verbose' a false.  
Sinon, il est fortement conseille de commenter l option log de domoticz (dans domoticz.sh) afin de ne pas 
saturer l espace de stockage  par un fichier log trop important
--]]
 
----------------------------------------------
------          Configuration          ------
----------------------------------------------
local piece={}     -- Tableau Rajouter ici les radiateurs 
	piece['0']='chambre Dorian'
	piece['1']='SdB enfants'


local watt={}     -- Tableau Rajouter ici la puissance en watts du radiateur (L'index doit correspondre a celui de la piece ci-dessus)
	watt['0']='1250'
	watt['1']='1000'

local presence = 'Chauffage'
local calendrier = 'Programmateur chauffage'
-- consignes de thermostat virtuels
local consigne_confort = 'Confort'           
local consigne_eco = 'Eco'
local consigne_horsgel = 'Hors gel'
local conso = 'Consommation chauffage'         -- nom du capteur virtuel de consommation électrique (type= instant + counter)
local conso_id = 80                    -- 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 hysteresis = 0.4 					-- Valeur seuil pour éviter que le relais ne cesse de commuter dans les 2 sens
local debugging = false 	                   -- true or false pour voir tous les messages debug dans le log
local verbose = true					   -- Print ou non des logs
-- email
local mail = 'xxxx'  -- pour réception alerte sonde muette (chauffage coupé)

-- domoticz
local url = '192.168.x.xx:xxxx'         -- user:pass@ip:port de domoticz, pour la création des variables

local status = 0

local cumul_power = 0   -- initialisation de la puissance instantanee des radiateurs en fonctionnement
----------------------------------------------
--       Fin de la partie configuration       --
----------------------------------------------

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


commandArray = {}

for key, valeur in pairs(piece) do
	-- Maj des variables en fonction de la valeur de la table 
	local le_radiateur_est_sur_ON = false      -- Etat du radiateur false ou true
  	local sonde_KO = false                     -- Sonde de temperature HS
	local sonde = string.format("%s%s", "Temperature ", valeur)                   -- Nom de la sonde de température
	local radiateur = string.format("%s%s", "Radiateur ", valeur)       -- Nom de l'interrupteur de chauffage
	log1 = '***'
	log2 = '***'
	
	local heure = string.sub(os.date("%X"), 1, 5)	-- Recuperation de l'heure du systeme
	local lastSeen = string.sub(os.date("!%X", timedifference(sonde)), 1, 5) 	-- Heure de la derniere releve de la sonde de temperature
	
	puissance=tonumber(watt[key])  -- Puissance en watt du radiateur
	

	if (debugging) then print ('>>>>>>>>>>>>>>>Initialisation '..puissance..' Radiateur>'..valeur) end

----------------------------------------------
------         Alerte mail              ------
--     si la sonde est muette depuis 30'    --
----------------------------------------------

	if (lastSeen >= '00:30' and lastSeen < '00:32') then
		commandArray['SendEmail']='Domoticz Alerte#Alerte sonde chambre '..piece..' muette#'..mail
		if (debugging) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Envoi mail probleme de sonde ') end
	end

----------------------------------------------
------          Gestion consigne        ------
----------------------------------------------
      
   -- récupération de la valeur du thermostat
   
    if (otherdevices[presence] == 'On') then 			-- si la presence est active (interrupteur manuel 'Chauffage')

		if (otherdevices[calendrier] == 'On') then 		-- ET calendrier ON (Programmateur chauffage)
			consigne = tonumber(otherdevices_svalues[consigne_confort])
		else
			consigne = tonumber(otherdevices_svalues[consigne_eco])
        end
    
	else     -- presence = OFF
		consigne = tonumber(otherdevices_svalues[consigne_horsgel])
	end

	if (debugging) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Initialisation Consigne chambre '..valeur..' > '..consigne) end
	
   -- on récupère la température fournie par la sonde
   local temperature = otherdevices_temperature[sonde]
   	
    if (debugging) then print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Recup valeur sonde chambre '..valeur..' > '..temperature) end

----------------------------------------------
--  Inititialisation des Variables d etat  --
----------------------------------------------

	if (otherdevices[radiateur] == 'On') then le_radiateur_est_sur_ON = true end 
	
	if lastSeen > '00:10' then 
		local sonde_KO = true 
		log2 = '***        Sonde muette '
	end

----------------------------------------------
------       Gestion du radiateur       ------
--- selon temperature relevee et consigne   --
----------------------------------------------
   
	if (le_radiateur_est_sur_ON) and not (sonde_KO) then
		log1 = '*** IF 1 >                        Le Radiateur est en marche'
		status = 1
		if temperature >= (consigne + hysteresis) then
			commandArray[#commandArray + 1]={[radiateur]='Off'}			
			log1 = '*** IF 2 >                    Arret du Radiateur'
			status = 0  -- Pour eviter le delai de la Maj du device (variable utilisee dans le if du calcul de conso)
		end
	else
		log1 = '*** IF 3 >                 Le Radiateur est arrete'
		status = 0
		if temperature <= (consigne - hysteresis) and not (sonde_KO) then
			commandArray[#commandArray + 1]={[radiateur]='On'}	
			log1 = '*** IF 4 >                 Allumage du Radiateur'
			status = 1
		end
	end
		
	  -- 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[#commandArray + 1]={['UpdateDevice'] = conso_id .. '|0|' .. power .. ';' .. energy}
   
   -- logs
   if (verbose) then
		print ' '
		print('********************* Chauffage '..valeur..' *********************')
		print('***                 Il fait '..temperature..'°C pour une consigne de '..consigne..'°C souhaités')
		print(log1,log2)
		print('********************************************************************')
	end

end -- fin de tableau
return commandArray
Dernière modification par vil1driver le 11 févr. 2019, 18:00, modifié 3 fois.
Raison : Suppression email dans le script
Pi3 + DD PiDrive - RFXtrx433 - AEON Labs ZW090
garycooper
Messages : 453
Inscription : 07 août 2017, 23:58

Re: YASDC (Yes Another Script De Chauffage) !

Message par garycooper »

Merci pour ton aide et les corrections ! Je suis loin de ça ...

Je voudrais pouvoir y intégrer le script PID pour avoir une régulation du chauffage plus propre et sans faire un script par pièce mais visiblement, il va falloir que je progresse beaucoup avant d'y arriver ...
denis_brasseur
Messages : 898
Inscription : 24 déc. 2018, 17:05
Localisation : (26)

Re: YASDC (Yes Another Script De Chauffage) !

Message par denis_brasseur »

garycooper a écrit : 09 févr. 2019, 23:44 Merci pour ton aide et les corrections ! Je suis loin de ça ...

Je voudrais pouvoir y intégrer le script PID pour avoir une régulation du chauffage plus propre et sans faire un script par pièce mais visiblement, il va falloir que je progresse beaucoup avant d'y arriver ...
Tu a fait le plus dure, maintenant il te reste le plus long.

Pour l'implémentation d'un pid, tu a l'excellent post du non moins excellent vil1driver.

................chauffage PID..............

Ces scripts sont très bien écrit, très bien décrit.

Approprie toi tranquillement un code avant de le mettre en place, et essaye surtout d'en comprendre le fonctionnement en le modifiant et l'adaptant.
Pi3 + DD PiDrive - RFXtrx433 - AEON Labs ZW090
garycooper
Messages : 453
Inscription : 07 août 2017, 23:58

Re: YASDC (Yes Another Script De Chauffage) !

Message par garycooper »

Oui, c'est ce script que je comptais utiliser. Je pense l'avoir compris mais j'ai encore du mal à savoir comment concaténer les 2 scripts pour avoir la fonction "liste" des zones et le calcul d'énergie consommée sans devoir faire un script par pièce.
Répondre