Netatmo + Synology : récupération status de chauffe en cours

Vous avez crée 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.
Soyez précis quant aux prérequis, les manips à faire pour que votre bijou fonctionne (des chmod ?, un apt-get à faire ...)
Décrivez précisément son fonctionnement
Placez votre code entre [Quote] et {/Quote]
Répondre
froglock30
Messages : 17
Enregistré le : 21 oct. 2019, 09:31
Localisation : Gard
Contact :

Netatmo + Synology : récupération status de chauffe en cours

Message par froglock30 » 07 nov. 2019, 17:18

Salut à tous,

J'ai intégré sans soucis mon thermostat et mes vannes connectées dans Domoticz. Par contre, je n'arrive pas à récupérer le status "Chauffe en cours".

J'ai une installation mixte, solaire + bois + gaz afin de chauffer ma maison (toutes les sources de chaleur chauffent un ballon tampon)

L'année dernière je n'avais pas les vannes connectées, j'avais fais un petit un script LUA qui déclenchait la chauffe de ma chaudière en fonction de la température de l'eau de mon ballon, de la température extérieure et de la différence de température entre la consigne Netatmo et la température du thermostat.

Avec 7 vannes connectées, cela devient trop pénible. En récupérant le status "en chauffe" de Netatmo, je pourrais simplifier mon script et lancer la chauffe de la chaudière uniquement si j'ai un besoin détecté par Netatmo et que la réserve d'eau de mon ballon est trop froide.

Je n'ai pas trouvé de dispositif dans le module Netatmo qui corresponde à ce status, y'aurait-il un moyen simple de récupérer cette information ?

Merci d'avance,

Fred.

Disable adblock

This site is supported by ads and donations.
If you see this text you are blocking our ads.
Please consider a Donation to support the site.


froglock30
Messages : 17
Enregistré le : 21 oct. 2019, 09:31
Localisation : Gard
Contact :

Re: Netatmo + Synology : récupération status de chauffe en cours

Message par froglock30 » 12 nov. 2019, 13:56

Bonjour à tous,

En prenant des bouts de code de ci, de là j'ai réussi à trouver une solution.

1) script : En python pour récupérer le status du thermostat principal Netatmo : j'utilise l'API homeStatus (valeur de boiler_status) et je mets à jour un switch on/off virtuel dans Domoticz.

2) En script LUA (Time) dans Domoticz, j'utilse le status de ce bouton + la température de mon ballon pour déclencher (ou pas) le démarrage de la chaudière.

Pour l'instant le code est un peu "brut" si jamais cela intéresse quelqu'un, je le mettrais au propre.

Fred.

froglock30
Messages : 17
Enregistré le : 21 oct. 2019, 09:31
Localisation : Gard
Contact :

Re: Netatmo + Synology : récupération status de chauffe en cours

Message par froglock30 » 12 nov. 2019, 22:11

Voici le code du module. Je l'intègre directement dans un évènement Domoticz (nouveau => python) en déclenchement "Time"

Il faut personnaliser username, password, client_id et client_secret pour se connecter à votre appli Netatmo (à créer sur leur site)

Pour la partie domoticz, il faudra personnaliser les requêtes 127.0.0.1:8084 pour moi et le n° de device (un switch on/off n° 126 chez moi)

Toutes les minutes, Domoticz va interroger le site de Netatmo afin de connaitre le status du thermostat (en chauffe ou pas) et si nécessaire on mettra à jour le status du switch.

Un deuxième script vient tester l'état du switch afin de déclencher dans mon cas le démarrage de ma chaudière au gaz.

Code : Tout sélectionner

import sys
sys.path.append('/volume1/@appstore/py3k/usr/local/lib/python3.5/site-packages')
import requests
import domoticz
import random
## authentication code based on netatmo sample code
payload = {'grant_type': 'password',
           'username': "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
           'password': "xxxxxxxxxxxxxxxxxxxx",
           'client_id':"xxxxxxxxxxxxxxxxxxxxxxxx",
           'client_secret': "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
           'scope': 'read_thermostat'}
try:
	response = requests.post("https://api.netatmo.com/oauth2/token", data=payload)
	response.raise_for_status()
	access_token=response.json()["access_token"]
	refresh_token=response.json()["refresh_token"]
	expires_in=response.json()["expires_in"]
	scope=response.json()["scope"]
	# print("Your refresh token is       : ", refresh_token)
	# print("Your access token is        : ", access_token)
	# print("Your access token expires in: ", expires_in)
	# print("Your scopes are:", scope)
except requests.exceptions.HTTPError as error:
	print(error.response.status_code)
	print(error.response.text)

headers = { 
	'Authorization': 'Bearer ' + access_token
}
params = {
	'home_id': 'xxxxxxxxxxxxxxxxxxxxxxxx' #, On peut récupérer cette information sur le site dev de Netatmo en faisant le test de l'API homeData
	#'device_id': '[YOUR_DEVICE_ID]'
	}
	
try:
	# On récupère le status du switch virtuel (N° 126 chez moi)
    lStatusBrut = requests.get("http://127.0.0.1:8084/json.htm?type=devices&rid=126")
    lStatusBrut.raise_for_status()
    lStatusJSon = lStatusBrut.json()
    lStatusBoiler = lStatusJSon["result"][0]["Status"]
	# Récupération de la valeur "boiler_status" qui indique si le thermostat ou une vanne à un besoin de chauffe
    response = requests.post("https://api.netatmo.com/api/homestatus", params=params, headers=headers)
    response.raise_for_status()
    data = response.json()
    # Si le status à changé, on envoi la requete de mise à jour (personnaliser le n° de switch)
    if str(data["body"]["home"]["modules"][1]["boiler_status"]) == 'False' :
    	if lStatusBoiler == "On" : 
            requests.get("http://127.0.0.1:8084/json.htm?type=command&param=switchlight&idx=126&switchcmd=Off")
		#else:
			#domoticz.log("Pas de changement (Off)")
    else:
        if lStatusBoiler == "Off" : 
            requests.get("http://127.0.0.1:8084/json.htm?type=command&param=switchlight&idx=126&switchcmd=On")
		#else:
			#domoticz.log("Pas de changement (On)")
	
except requests.exceptions.HTTPError as error:
    domoticz.log(error.response.status_code, error.response.text)


froglock30
Messages : 17
Enregistré le : 21 oct. 2019, 09:31
Localisation : Gard
Contact :

Re: Netatmo + Synology : récupération status de chauffe en cours

Message par froglock30 » 18 nov. 2019, 15:19

Voici la version 3.

J'ai regroupé les divers modules que j'avais fait en un seul, cela me permet une gestion plus séquentielle (alarme, thermostat, ...) et donc plus réactive.

Le script python par défaut (lorsqu'on créé un nouvel évènement python dans Domoticz) est buggé, j'ai par contre réussi à comprendre comment cela fonctionnait grâce à un post sur un autre forum Domoticz. J'ai donc replacé les commandes http pour interroger mes devices domoticz par un code plus natif. J'ai gagné 8 à 9 secondes sur l'exécution du script.

J'ai aussi rajouté un script python stocké dans les dossiers domoticz afin de déclarer tous mes mots de passe, ils ne sont plus visible directement depuis l'interface de domoticz et par un "import" ils sont disponible dans mon script (un simple print de la variable pourrait les affichers mais bon :) ça m'évitera de nettoyer le script à chaque fois que je voudrais le diffuser. )

J'ai essayé de commenter au maximum le code.

SI quelqu'un à le courage de le lire et de m'indiquer si d'autres optimisations seraient possibles.

Merci d'avance.

Fred.

Code : Tout sélectionner

import sys
sys.path.append('/volume1/@appstore/py3k/usr/local/lib/python3.5/site-packages') # A personnaliser peut être pour vous (domoticz sur un synology pour moi)
import requests
import DomoticzEvents as DE
import domoticz
import random
import visonic
from visonic import alarm
import mesdata 


# Le bloc ci dessous est stocké (avec mes identifiants) 
# dans un fichier mesdata.py stocké dans le sous-dossier pluggin\python 
# dans mon répertoire domoticz.
# Il n'est accessible que par putty en ssh et pas en clair dans l'interface de domoticz

# #---------------------------------------------
# # Accès Netatmo
# #---------------------------------------------
# payload = {'grant_type': 'password',
# 		   'username': "monemail@toto.Fr",				            # login Netatmo
# 		   'password': "motdepasse",						        # mot de passe netatmo
# 		   'client_id':"xxxxxxxxxxxxxxxxxxxxxxxxxxx",				# client_id & client_secret à récupérer sur le site https://www.netatmo.com/en-us/connect (créer une application)
# 		   'client_secret': "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",	  
# 		   'scope': 'read_thermostat write_thermostat'}

# #---------------------------------------------
# # Paramètres Netatmo
# #---------------------------------------------
# # depuis le site : https://dev.netatmo.com/resources/technical/reference/energy/homesdata
# # on peut récupérer le home_id et l'id des différents plannnings (therm_schedules)
# home_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# planning_Normal = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# planning_Absent = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# #---------------------------------------------
# # Paramètres visonic
# #---------------------------------------------
# # pluggin visonic : https://github.com/MikaelSchultz/visonicalarm
# hostname  = 'visonic.tycomonitor.com'
# user_code = '0000'								  # code utilisateur
# user_id   = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' # Attention, lire le process d'install, cet user_id unique est à générer sur un site.
# panel_id  = '123456'								# code de votre site
# partition = 'P1'

#---------------------------------------------
# modeDebug
#---------------------------------------------
# Dummy switch on/ff, pour activer / désactiver l'affichage des infos
modeDebug = DE.Devices["Mode debug"].n_value_string

# Procédure pour afficher des infos si le switch débug est activé
def monDebug(pTexte):
	if modeDebug == "On" : DE.Log(pTexte)

try: 
	#---------------------------------------------
	# Récupération des valeurs Domoticz
	#---------------------------------------------
	monDebug("-------------------------------------------")
	monDebug("      Informations Domoticz : ")
	monDebug("-------------------------------------------")
	# Temperature du ballon - Sonde zWave sur qubino
	lBallonHaut = float(DE.Devices["Ballon Haut"].n_value_string)
	monDebug("Temp ballon :" + str(lBallonHaut))
	# ChaudiereAllumee - Contacteur sec zWave pour pilotage chaudière gaz
	lChaudiereAllumee = DE.Devices["Chaudière ON/OFF"].n_value_string
	monDebug("ChaudiereAllumee : "+ lChaudiereAllumee)
	# Status du "Boiler" - Dummy switch on/off pour visualisation et comptable du temps de chauffe
	# Le thermostat netamo pilote le circulateur de mon chauffage central
	lStatusBoiler = DE.Devices["Netatmo Chauffe"].n_value_string
	monDebug("Boiler : " + lStatusBoiler)
	# Switch mode Netatmo Absent activé
	lStatusAbsent = DE.Devices["Netatmo Absent"].n_value_string
	# Autoriser la gestion de la chaudière en auto - dummy switch pour désactiver le pilotage de la chaudière
	lModeAutomatique = DE.Devices["Allumage Chaudiere Auto"].n_value_string
	monDebug("Mode Automatique : " + lModeAutomatique)
	# Interrupteur Autoriser le changement de planning - dummy switch pour désactiver le changement de planning Netatmo
	lPlanningAutomatique = DE.Devices["Autoriser Changement Planning"].n_value_string
	monDebug("Planning Automatique : " + lModeAutomatique)
	# Température extérieure - pas de sonde : récupération darksky
	lTempExt = DE.Devices["Extérieur"].n_value_string
	lTempExt = lTempExt.split(";")[4]
	monDebug("Extérieur : "+ lTempExt)
	# Calcul du delta temp pour l'ajustement de la température du ballon pour l'allumage / extinction de la chaudière
	# La température de référence (15°C) a été determiné empiriquement suite à des tests pour ma maison
	lDeltaTemp = (15.0 - float(lTempExt)) / 2
	monDebug("Delta Temp  : "+ str(lDeltaTemp))
	lMinBallon = 40 + lDeltaTemp
	lMaxBallon = 50 + lDeltaTemp
	monDebug("Ballon : Min " + str(lMinBallon) + " / Max "+ str(lMaxBallon))
	
	#---------------------------------------------
	# Lecture Status de l'alarme Visonic
	#---------------------------------------------
	monDebug("-------------------------------------------")
	monDebug("      Traitement des modules : ")
	monDebug("-------------------------------------------")
	api = alarm.API(hostname, user_code, user_id, panel_id, partition)
	res = api.login()
	if api.is_logged_in():
		# Status de l'alarme
		lRes = api.get_status()
		lEtat = str(lRes["partitions"][0]["state"])
		#Status de l'alarme
		lStatusAlarme = DE.Devices["Alarme"].n_value_string
		if lEtat == 'Disarm' :
			monDebug("Visonic : Alarme éteinte")
			if lStatusAlarme == "On" : 
				lStatusAlarme = "Off"
				DE.Command("Alarme", "Off")
		else:
			monDebug("Visonic : Alarme Allumée")
			if lStatusAlarme == "Off" :
				lStatusAlarme = "On"
				DE.Command("Alarme", "On")
	else:
		DE.Log(">>>>>>>> Visonic, aucune connection")


	#---------------------------------------------
	# Récupération du status du thermostat Netatmo
	#---------------------------------------------
	# 	Connection
	response = requests.post("https://api.netatmo.com/oauth2/token", data=payload)
	response.raise_for_status()
	access_token=response.json()["access_token"]
	refresh_token=response.json()["refresh_token"]
	expires_in=response.json()["expires_in"]
	scope=response.json()["scope"]

	headers = { 
		'Authorization': 'Bearer ' + access_token
	}

	params = {
		'home_id': home_id
	}

	# Netatmo
	response = requests.post("https://api.netatmo.com/api/homestatus", params=params, headers=headers)
	response.raise_for_status()
	data = response.json()
	# Selon le status du thermostat, on mets à jour le switch
	modeThermostat = str(data["body"]["home"]["rooms"][0]["therm_setpoint_mode"])
	if str(data["body"]["home"]["modules"][1]["boiler_status"]) == 'False' :
		if lStatusBoiler == "On" : 
			monDebug("Netatmo => Chauffage Off")
			DE.Command("Netatmo Chauffe", "Off")
		else:
		    monDebug("Netatmo => Chauffage déjà éteint")
	else:
		if lStatusBoiler == "Off" : 
			monDebug("Netatmo => Chauffage On")
			DE.Command("Netatmo Chauffe", "On")
		else:
		    monDebug("Netatmo => Chauffage déjà allumé")
	response = requests.post("https://api.netatmo.com/api/homesdata", params=params, headers=headers)
	response.raise_for_status()
	data = response.json()
	# On essaye de récuperer le planning actif
	planningNormal = "False"
	try:
		if str(data["body"]["homes"][0]["therm_schedules"][0]["selected"]) == "True":
			monDebug("Planning normal ")
			planningNormal = "True"
	except KeyError:
		planningNormal = "False"
		monDebug("Planning standard non selectionné")

	#---------------------------------------------
	# Gestion de mode "absent"
	#---------------------------------------------
	if lPlanningAutomatique == "On" :
		monDebug("[Gestion planning absent activée]")
		if lStatusAlarme == "On" :
			monDebug("		... Alarme allumée")
			if lStatusAbsent != "On" : 
			    DE.Command("Netatmo Absent", "On")
			if  planningNormal == 'True' : 
				# Alarme active et chauffage actif, on passe en mode absent
				# sinon on ne fait rien
				params = {
					'home_id': home_id,
					'schedule_id': planning_Absent
				}
				# params["home_id"] = home_id
				# params["schedule_id"] =  planning_Absent
				monDebug("		... Passage en mode absent")
				requests.get("https://api.netatmo.com/api/switchhomeschedule", params=params, headers=headers)
			else:
				monDebug("		... déjà en mode absent")
		else : 
			monDebug("		... Alarme éteinte")
			if lStatusAbsent == "On" : 
			    DE.Command("Netatmo Absent", "Off")
			if  planningNormal != 'True' : 
				# on passe en mode actif
				params = {
					'home_id': home_id,
					'schedule_id': planning_Normal
				}
				# params["home_id"] = home_id
				# params["schedule_id"] =  planning_Normal
				monDebug("		... Passage en mode Normal")
				res = requests.get("https://api.netatmo.com/api/switchhomeschedule", params=params, headers=headers)
			else:
				monDebug("		... déjà en mode Planning")
		monDebug("[Gestion absent FIN]")
	else:
		monDebug("[Planning automatique désactivé]")
	
	#---------------------------------------------
	# Gestion de l'allumage de la chaudière
	#---------------------------------------------
	if	lModeAutomatique == "On" :
		monDebug("[Gestion allumage chaudière activée]")
		if lBallonHaut < lMinBallon : 
			# Températur du ballon et température extiérieure faible
			if lStatusBoiler == "On" :
				# Le thermostat est en mode de chauffe
				if lChaudiereAllumee == "Off" :
					#  La chaudière est éteinte
					DE.Log("========> Température ballon insuffisante - Allumage chaudière [" + str(lMinBallon) + "]")
					if lModeAutomatique == "On" :
						 DE.Command("Chaudière ON/OFF", "On")
					else: 
						monDebug('=========> Chaudière [ON]/OFF : Mode automatique OFF')

		else:
			if lChaudiereAllumee == "On" and lBallonHaut > lMaxBallon :
				DE.Log("========> Température ballon correcte - extinction chaudière [" + str(lMaxBallon) + "]")
				if lModeAutomatique == "On" :
					DE.Command("Chaudière ON/OFF", "Off")
				else:
					monDebug('=========> Chaudière ON/[OFF] : Mode automatique OFF')
		monDebug("[Gestion allumage chaudière activée - Fin]")
	else:
		monDebug("Gestion chaudière automatique désactivé")



except requests.exceptions.HTTPError as error:
	DE.Log(error.response.status_code + " " + error.response.text)

exemple de log :

Code : Tout sélectionner

 2019-11-18 15:16:00.337 -------------------------------------------
2019-11-18 15:16:00.337 Informations Domoticz :
2019-11-18 15:16:00.337 -------------------------------------------
2019-11-18 15:16:00.344 Temp ballon :59.4
2019-11-18 15:16:00.345 ChaudiereAllumee : Off
2019-11-18 15:16:00.345 Boiler : Off
2019-11-18 15:16:00.345 Mode Automatique : On
2019-11-18 15:16:00.345 Planning Automatique : On
2019-11-18 15:16:00.346 Extérieur : 9.5
2019-11-18 15:16:00.346 Delta Temp : 2.75
2019-11-18 15:16:00.347 Ballon : Min 42.75 / Max 52.75
2019-11-18 15:16:00.347 -------------------------------------------
2019-11-18 15:16:00.347 Traitement des modules :
2019-11-18 15:16:00.347 -------------------------------------------
2019-11-18 15:16:02.022 Visonic : Alarme éteinte
2019-11-18 15:16:04.847 Netatmo => Chauffage déjà éteint
2019-11-18 15:16:06.076 Planning normal
2019-11-18 15:16:06.076 [Gestion planning absent activée]
2019-11-18 15:16:06.089 ... Alarme éteinte
2019-11-18 15:16:06.089 ... déjà en mode Planning
2019-11-18 15:16:06.089 [Gestion absent FIN]
2019-11-18 15:16:06.090 [Gestion allumage chaudière activée]
2019-11-18 15:16:06.090 [Gestion allumage chaudière activée - Fin] 

Disable adblock

This site is supported by ads and donations.
If you see this text you are blocking our ads.
Please consider a Donation to support the site.


Répondre