Aller au contenu

Recommended Posts

Oui mais là on se heurte à nouveau au problème du plugin (cf. quelques pages avant dans ce fil de discussion). Chez moi, il ne voit rien, il ne lit rien.

 

C'est pour ça que j'étais hypercontent d'avoir une solution qui commandait le thermostat via la box uniquement par un script qui utilise l'API, et non obligé de passer par le plugin.

Partager ce message


Lien à poster
Partager sur d’autres sites

Evidemment, même en remplaçant write par read, ça ne marche pas mieux.

 

Je vais retourner bosser mon LUA...

Partager ce message


Lien à poster
Partager sur d’autres sites

Voilà une autre scène pour lire les données du thermostat, je l'ai faites rapidement pour que tu puisse jouer avec. Elle ne renseigne que la température mais

tu peux l'améliorer à ta guise et renvoyer les données collectées à un VD par exemple.

 

--[[
%% properties
%% globals
%% killOtherInstances
--]]
local idg=json.decode((fibaro:getGlobal('idTable')))
local client_id = 'xxxxxxxxxxxxxxxxxxxxxxxx'
local client_secret = 'xxxxxxxxxxxxxxxxxxxxxx'
local username = 'xxxxxxxxxxxxx'
local password = 'xxxxx'
--local homeId = 'xxxxxxxxxxxxxxxxxxxxxx'
-- homeId trouver sur site : https://my.netatmo.com/app/camera
-- a droite profil puis survol maison regarder sur barre chrome
local relay_idDefault="xx:xx:xx:xx:xx:xx" --Relay
-- Relay trouvé sur site : https://my.netatmo.com/app/energy
-- Il suffit de remplacer le g par 70:ee:50.
--Par example g002460 a pour adresse MAC 70:ee:50:00:24:60
local device_idDefault="xx:xx:xx:xx:xx:xx"	--Thermostat
-- Thermostat trouvé sur site : https://dev.netatmo.com/resources/technical/reference/thermostat/getthermostatsdata
-- try it et dans le resultat aller à body devices _id modules _id
local debug = 1

local token = ''
local request_body = ''

Debug = function ( color, message )
  if (debug == 1) then
  	fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
  elseif (debug == 0) then
  end
end

DebugChange = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

DebugError = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

local sourceTrigger = fibaro:getSourceTrigger();

function oAuth(nextFunction)
	local request_body = 'grant_type=password&client_id=' .. client_id .. '&client_secret=' .. client_secret .. '&username=' .. username .. '&password=' .. password .. '&scope=read_thermostat'
	getResponseData('https://api.netatmo.net/oauth2/token', request_body, 
    	function(data) 
      		if (data.access_token ~= nil) then
        		token = data.access_token
       			getDatas()
     	 	else
       		 	DebugError( "red", "oAuth-API-Call n'a donné aucune valeur de retour");
      		end
    	end
    )
end

function getResponseData(url, body, func)
 local http = net.HTTPClient()
 http:request(url, { 
 options = { 
 method = 'POST', 
         headers = {
 ['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 },
 data = body
 },
 success = function(response)
 func(json.decode(response.data))
 end
 })   
end

function getDatas()
	DebugChange( "green", "Get Datas")
	request_body = 'access_token=' ..token.. '&device_id='..relay_id
  	getResponseData('https://api.netatmo.net/api/getthermostatsdata', request_body, 
    function(getData)
		Debug( "white", 'Status checking')
		if (getData.body ~= nil) then
			tDevices=getData.body.devices
   			for w, relays in pairs(tDevices) do
				Debug( "white", 'Id Relay : '..relays._id)
           		if relays._id==relay_id then
					for a, devices in pairs(relays.modules) do
						Debug( "white", 'Id Thermostat : '..devices._id)
   		         		if devices._id==device_id then
							--pour les autres datas voir
                			-- https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata
        	      			curtemp=devices.measured.temperature
							Debug( "white", 'Temperature courante : '..curtemp)
              			end
        			end
            	end
        	end
      	end
     end
	)
end

--recupération des arguments
local params = fibaro:args()
if (params) then
  for k, v in ipairs(params) do
    if (v.relay_id) then relay_id = v.relay_id end
    if (v.device_id) then device_id = v.device_id end
  end
end
if relay_id==nil then relay_id=relay_idDefault end	--Required mac address of the relay
if device_id==nil then device_id=device_idDefault end	--Required mac address of the thermostat

DebugChange( "green", "device_id : "..device_id)

oAuth()

 

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Merci beaucoup, mais ça ne marche pas chez moi.

 

Ça marche très bien, j'avais juste par flemme pas changé mes variables locales au début qui sont légèrement différentes du script précédent. Quand on lit bien TOUT, et qu'on corrige comme il faut, ça marche TRES bien.

 

Merci.

 

Je vais essayer de jouer un peu avec.

 

 

 

Modifié par pedia

Partager ce message


Lien à poster
Partager sur d’autres sites

Nickel, n'oublie surtout pas de publier ton script une fois complet et fonctionnel ;-)

Sent from my SM-N910F using Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

Yes ça serait pas mal que qq un publie un me version complète avec un beau Tuto ( et un VD pour jouer avec ?)

Est ce que vous avez le plugin d installer ?
Et / ou comment le virer sans virer la station météo ?

Partager ce message


Lien à poster
Partager sur d’autres sites

@Sakkhho,

Avec la derniere modification de @Titof_44 pour la lecture, ça sent bon ;-), installer le plugin devient inutile ;-) 

 

la scène permettra de tout faire en fonction de l'envoi des bons "args".

 

Pendant que tu es en train de bosser sur la scene @Titof_44, quelles pourraient être les données nécessaires de lire à par le mode et la température ? 

 

Arrêter messieurs, je vais être obligé d'acheter un thermostat netatmo...faudra que je verifie si il fonctionne avec ma chaudière..jamais fait ;-)

 

un tuto, un tuto, un tuto :-)

  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Je confirme : Plugin non installé, récupère très bien toutes les infos qu'on veut. J'essaie de les envoyer vers un VD afin de récupérer les infos.

 

 

 

Capture d’écran 2017-04-30 à 18.31.27.png

Capture d’écran 2017-04-30 à 18.55.47.png

Modifié par pedia
  • Upvote 2

Partager ce message


Lien à poster
Partager sur d’autres sites

Ok.
Pensez vous que si je supprime via X le thermostat mais je touche pas le plugin (car j ai la station météo) ca sera ok ?

Partager ce message


Lien à poster
Partager sur d’autres sites

Alors là...

 

Vu la grande estime que j'ai pour ce plugin, je ne me permettrai pas d'avoir un avis sur les conséquences engendrées par celui-ci...

 

Une bonne sauvegarde me parait le plus judicieux quand même.

Partager ce message


Lien à poster
Partager sur d’autres sites

Voici donc un début de tuto, sans aucune prétention vu que je ne fais que reprendre les scripts de Titof_44.

 

On va donc utiliser :

- une scène qui sert à récupérer les données du thermostat

- une scène qui sert commander le thermostat

- un VD pour permettre de tout mettre en oeuvre

 

On commence par créer un VD afin d'avoir son ID de prêt. On créée par exemple 4 étiquettes, et 3 boutons.

 

590648a2686f5_Capturedcran2017-04-3022_25_22.png.55fcc4e7a8e99c7005eee39ab7ae332c.png

 

 

 

La scène de récupération des données (ID33 chez moi) : 

--[[
%% properties
%% globals
%% killOtherInstances
--]]

local client_id = 'XXXXX'
local client_secret = 'XXXXXX'
local username = 'XXXXX'
local password = 'XXXXXXX'
local relay_idDefault="XXXXXX" --Relay
local device_idDefault="XXXXXX"	--Thermostat
--Toutes  ces infos se trouvent dans https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata
local debug = 1

local token = ''
local request_body = ''

Debug = function ( color, message )
  if (debug == 1) then
  	fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
  elseif (debug == 0) then
  end
end

DebugChange = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

DebugError = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

local sourceTrigger = fibaro:getSourceTrigger();

function oAuth(nextFunction)
	local request_body = 'grant_type=password&client_id=' .. client_id .. '&client_secret=' .. client_secret .. '&username=' .. username .. '&password=' .. password .. '&scope=read_thermostat'
	getResponseData('https://api.netatmo.net/oauth2/token', request_body, 
    	function(data) 
      		if (data.access_token ~= nil) then
        		token = data.access_token
       			getDatas()
     	 	else
       		 	DebugError( "red", "oAuth-API-Call n'a donné aucune valeur de retour");
      		end
    	end
    )
end

function getResponseData(url, body, func)
 local http = net.HTTPClient()
 http:request(url, { 
 options = { 
 method = 'POST', 
         headers = {
 ['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 },
 data = body
 },
 success = function(response)
 func(json.decode(response.data))
 end
 })   
end

function getDatas()
	DebugChange( "green", "Get Datas")
	request_body = 'access_token=' ..token.. '&device_id='..relay_id
  	getResponseData('https://api.netatmo.net/api/getthermostatsdata', request_body, 
    function(getData)
		Debug( "white", 'Status checking')
		if (getData.body ~= nil) then
			tDevices=getData.body.devices
   			for w, relays in pairs(tDevices) do
				Debug( "white", 'Id Relay : '..relays._id)
           		if relays._id==relay_id then
					for a, devices in pairs(relays.modules) do
						Debug( "white", 'Id Thermostat : '..devices._id)
                        Debug( "white", 'Temprature cible : '..devices.measured.setpoint_temp)
                        fibaro:call(113, "setProperty", "ui.Label3.value", devices.measured.setpoint_temp)
   		         		
                          if devices._id==device_id then
							--pour les autres datas voir
                			-- https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata
        	    
                            curtemp=devices.measured.temperature
							Debug( "white", 'Temperature courante : '..curtemp)
                            fibaro:setGlobal("Temp_Salon", curtemp)
                            batterylvl=devices.battery_percent
                            Debug( "white", 'Niveau des piles : '..batterylvl)
                            Debug( "white", 'Temprature cible : '..devices.measured.setpoint_temp)
                            fibaro:getValue(batterylvl, "value")
                            fibaro:getValue(devices.measured.setpoint_temp, "value")
                            Debug( "white", 'Programme : '..devices.setpoint.setpoint_mode)
                            fibaro:call(113, "setProperty", "ui.Label2.value", batterylvl .." % ")
                            fibaro:call(113, "setProperty", "ui.Label4.value", devices.setpoint.setpoint_mode)         
              end
        			end
            	end
        	end
      	end
     end
	)
end

--recupération des arguments
local params = fibaro:args()
if (params) then
  for k, v in ipairs(params) do
    if (v.relay_id) then relay_id = v.relay_id end
    if (v.device_id) then device_id = v.device_id end
    if (v.devices.measured.setpoint_temp) then devices.measured.setpoint_temp = v.devices.measured.setpoint_temp end

    if (v.devices.measured.temperature) then devices.measured.temperature = v.devices.measured.temperature end
  end
end
if relay_id==nil then relay_id=relay_idDefault end	--Required mac address of the relay
if device_id==nil then device_id=device_idDefault end	--Required mac address of the thermostat



oAuth()

Il n'est pas encore nickel, il y a des redondances et autres probables améliorations.

 

Pour le nom des variables (j'enfonce peut-être des portes ouvertes) il faut se fier à l'arborescence que l'on trouve sur https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata dans la section Try It, avec des subtilités :

devices : c'est relay

modules : c'est devices

Par exemple la température mesurée qui est sous l'arborescence modules/measured/temperature, la variable sera devices.measured.temperature

Le pourcentage des piles qui est juste sous modules/battery_percent, la variable sera devices.battery_percent

Dans la fonction getDatas on récupère les données qui nous intéressent et on les envoie à l'étiquette de notre VD correspondant.

 

Exemple pour le pourcentage des piles : 

                            fibaro:call(ID[VD], "setProperty", "ui.Label2.value", batterylvl .." % ")

J'ai mis la température mesurée également dans une variable globale pour essayer.

 

 

Pour la scène qui commande le thermostat, ID30 chez moi, (encore une fois je ne fais que recopier le script de Titoff_44)

 

--[[
%% properties
%% globals
%% killOtherInstances
--]]
local idg=json.decode((fibaro:getGlobal('idTable')))	--ids de mes modules
local client_id = 'XXXXXXXXXXXXXXXXXXXX'
local client_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
local username = 'xxxxxxxxxxxxxxx'
local password = 'xxxxxxxxxxxxxxxxxxxxx'
--local homeId = 'xxxxxxxxxxxxxxxxxxxxxxx'
-- homeId trouver sur site : https://my.netatmo.com/app/camera
-- a droite profil puis survol maison regarder sur barre chrome
local device_idDefault="xx:xx:xx:xx:xx:xx" --Relay
-- Relay trouvé sur site : https://my.netatmo.com/app/energy
-- Il suffit de remplacer le g par 70:ee:50.
--Par example g002460 a pour adresse MAC 70:ee:50:00:24:60
local module_idDefault="xx:xx:xx:xx:xx:xx"	--Thermostat
-- Thermostat trouvé sur site : https://dev.netatmo.com/resources/technical/reference/thermostat/getthermostatsdata
-- try it et dans le resultat aller à body devices _id modules _id
local debug = 1

local token = ''
local request_body = ''

Debug = function ( color, message )
  if (debug == 1) then
  	fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
  elseif (debug == 0) then
  end
end

DebugChange = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

DebugError = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

local sourceTrigger = fibaro:getSourceTrigger();

function oAuth(nextFunction)
	local request_body = 'grant_type=password&client_id=' .. client_id .. '&client_secret=' .. client_secret .. '&username=' .. username .. '&password=' .. password .. '&scope=write_thermostat'
	getResponseData('https://api.netatmo.net/oauth2/token', request_body, 
    	function(data) 
      		if (data.access_token ~= nil) then
        		token = data.access_token
       			SetAction()
     	 	else
       		 	DebugError( "red", "oAuth-API-Call n'a donné aucune valeur de retour");
      		end
    	end
    )
end

function getResponseData(url, body, func)
 local http = net.HTTPClient()
 http:request(url, { 
 options = { 
 method = 'POST', 
         headers = {
 ['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 },
 data = body
 },
 success = function(response)
 func(json.decode(response.data))
 end
 })   
end

function SetAction()
	DebugChange( "green", "Action : "..setpoint_mode)
	request_body_cam = 'access_token=' ..token.. '&device_id='..device_id ..'&module_id='..module_id ..'&setpoint_mode='..setpoint_mode
   	--Not Required
  	if setpoint_endtime~=nil then
    	request_body_cam =request_body_cam ..'&setpoint_endtime='..setpoint_endtime
    end
  	if setpoint_temp~=nil then
    	request_body_cam =request_body_cam ..'&setpoint_temp='..setpoint_temp
    end
  	getResponseData('https://api.netatmo.net/api/setthermpoint', request_body_cam, 
    function(getData)
 	end
	)
end

--recupération des arguments
local params = fibaro:args()
if (params) then
  for k, v in ipairs(params) do
    if (v.device_id) then device_id = v.device_id end
    if (v.module_id) then module_id = v.module_id end
    if (v.setpoint_mode) then setpoint_mode = v.setpoint_mode end
    if (v.setpoint_endtime) then setpoint_endtime = v.setpoint_endtime end
    if (v.setpoint_temp) then setpoint_temp = v.setpoint_temp end
  end
end

if setpoint_mode==nil then
  	fibaro:debug("Abort")
	fibaro:abort()
end

if device_id==nil then device_id=device_idDefault end	--Required mac address of the relay
if module_id==nil then module_id=module_idDefault end	--Required mac address of the thermostat
--setpoint_mode	--Required
--program 	: Currently following a weekly schedule
--away		: Currently applying the "away" temperature as defined by the user
--hg		: Frost-guard
--manual	: Currently applying a manually set temperature setpoint
--off		: Currently off
--max		: eating continuously
--setpoint_endtime --Not Required
--If setpoint_mode is max or manual, defines the validity period of the setpoint. Default is null.
--setpoint_temp --Not Required
--If setpoint_mode is manual, returns the temperature setpoint in °C.

DebugChange( "green", "device_id : "..device_id)
DebugChange( "green", "module_id : "..module_id)
DebugChange( "green", "setpoint_mode : "..setpoint_mode)

oAuth()

Attention subtilité les variables locales du début du script sont légèrement différentes de l'autre scène de récupération des données. Bien les remplir et ne pas faire un simple copier-coller.

 

 

Ensuite pour le commander au niveau des boutons du VD on rentre les commandes comme spécifiées dans le post de Titoff_44.

Par exemple : 

59064adcede21_Capturedcran2017-04-3022_35_50.png.a5a7f12c8dde9e85163c84e48f2b4a1f.png

La scène 30 est ma scène de commande du Thermostat. La scène 33 est celle qui récupère les données.

 

59064dc4d1a7a_Capturedcran2017-04-3022_48_35.png.9f4cf9f6a0083ea41c9bea5a9f96a24d.png

 

 

Voilà. J'ai remarqué une certaine latence chez moi pour la température cible qui se mettait à jour plusieurs secondes voire quelques minutes après le mise à jour du programme par exemple, mais même sur le site de Netatmo. Je ne sais pas s'il y a un moyen de forcer l'actualisation.

 

C'est assez fonctionnel, même si ça mérite de nombreuses améliorations comme de pouvoir choisir la température cible. Mais ça à le mérite de marcher chez moi, alors que le plugin de Netatmo avait été incapable jusque là de simplement trouver le thermostat sur mon réseau et ce malgré de nombreuses et infructueuses tentatives (cf. mes posts précédents désespérés).

 

J'ai retrouvé le sourire, et oui, ceux qui hésitait à acheter ce thermostat, peuvent franchir le pas à présent.

Partager ce message


Lien à poster
Partager sur d’autres sites

La latence est normal, c'est du au fonctionnement même de la partie cloud de leur thermostat, ce n'est pas modifiable.

Partager ce message


Lien à poster
Partager sur d’autres sites

doit avoir moyen de toute mettre dans la même scène non ?

 

j'hésite toujours à supprimer le plugin thermostat :)

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 1 heure, Nico a dit :

La latence est normal, c'est du au fonctionnement même de la partie cloud de leur thermostat, ce n'est pas modifiable.

Je me doute mais, ce qui est étonnant est que ça réagit très vite sur le thermostat lui-même et sur l'app Netatmo. Et la variable setpoint_mode se met à jour immédiatement. Ça doit être que les données que l'on récupère par cette méthode ne sont pas poussées dans le cloud aussi vite.

 

Du coup ça complique un peu le choix de la température cible en manuel. J'essaie en faisant dans le VD quelque chose comme ça :

local temp_cible = fibaro:getGlobalValue("Temp_Cible_Netatmo")
local nvtemp = temp_cible - 0.5

fibaro:debug("nouvelle temp :" ..nvtemp)
fibaro:call(113, "setProperty", "ui.Label3.value", nvtemp .." °C ")
fibaro:setGlobal("Temp_Cible_Netatmo", nvtemp)
fibaro:call(113, "setProperty", "ui.Label4.value", "Manuel")

fibaro:sleep(3000)
fibaro:startScene(30,{ {setpoint_mode="manual"}, {setpoint_temp= nvtemp}  })

Mais ça marche moyen et ce n'est pas très élégant.

J'ai essayé avec le slider, mais je me heurte au problème des valeurs qui sont soit au centième type 20,38 ou en nombre entier avec la fonction math.floor, je n'ai pas trouvé le moyen de faire de 0.5 en 0.5 (qui doit surement exister)

 

Il suffit de l'écrire pour le trouver, il faut faire simplement:

local Slider = math.floor(2*V_Slider)/2

 

 

 

il y a 46 minutes, Sakkhho a dit :

doit avoir moyen de toute mettre dans la même scène non ?

 

j'hésite toujours à supprimer le plugin thermostat :)

Essaye de le laisser, je ne pense pas que ça rentre vraiment en conflit, et tu le caches simplement du moins au début.

Modifié par pedia

Partager ce message


Lien à poster
Partager sur d’autres sites

Salut@pedia,
Merci pour le boulot, je ne peux que regarder de loin ton travail pour le moment​, mais dès que j'aurai un peu de temps je l'implémenterai.
Pour le traitement des données, n'hésite pas à étudier mon code, car j'ai déjà fait tout ces traitements comme les arrondis par exemple.


Sent from my SM-N910F using Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

Bonjour, beau boulot merci :-)
Tu dois pouvoir tout mettre dans une scène :-) certainement.
Oui, bonne idée pour les optimisations dont tu parles, jette un oeil au code de seb, plus celui de titot et le tien, ça va être aux petits oignons :-)

Envoyé de mon Nexus 5X en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

Un peu mono maniaque en ce moment, j'essaie d'extraire le programme sélectionné qui se cache derrière/dans un object sur le site de dev.netatmo. Et là... Ça ne répond pas à la règle que j'avais donnée dans le petit tuto. Il faut surement utiliser une table, et là encore mes maigres connaissances en LUA/programmation ne me permettent pas d'y arriver... pour le moment...

 

Si pour quelqu'un c'est une évidence.

590796b376fb7_Capturedcran2017-05-0122_00_32.png.56823e398d6d5d88ced1f764acf3b206.png

590796b23943d_Capturedcran2017-05-0122_00_45.png.fbe7e5ff53b2aee51afdcc42403e26cd.png

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 17 heures, pedia a dit :

Un peu mono maniaque en ce moment, j'essaie d'extraire le programme sélectionné qui se cache derrière/dans un object sur le site de dev.netatmo. Et là... Ça ne répond pas à la règle que j'avais donnée dans le petit tuto. Il faut surement utiliser une table, et là encore mes maigres connaissances en LUA/programmation ne me permettent pas d'y arriver... pour le moment...

 

Si pour quelqu'un c'est une évidence.

590796b376fb7_Capturedcran2017-05-0122_00_32.png.56823e398d6d5d88ced1f764acf3b206.png

590796b23943d_Capturedcran2017-05-0122_00_45.png.fbe7e5ff53b2aee51afdcc42403e26cd.png

Ca démontre juste une fois de plus que même un mec comme toi talentueux, ingénieux etc se heurte à un produit pas fini tributaire de mise à jour en beta toute plus dangereuses les unes que les autres.

 

C'est moi ou la version 4.1 devait déjà à l'époque résoudre le problème pour Netatmo ?

 

Du coup mon détecteur Nest de Monoxyde ne marche pas via ma fibaro et ma station météo et mon thermostat Netatmo remontent au bon vouloir (ainsi que d'autres add on mais bon je ne vais pas détailler ici). Même avec un script pour des raisons que j'ignore les scripts etc sont bloqués il faut rebooter pour retrouver une solution à jour de ses données.

 

On devrait être dans l'usage et des solutions conviviales, des problèmes de riche certes mais pas prêt de racheter du Fibaro...

Modifié par Daktari59

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 17 heures, Daktari59 a dit :

Ca démontre juste une fois de plus que même un mec comme toi talentueux, ingénieux etc se heurte à un produit pas fini tributaire de mise à jour en beta toute plus dangereuses les unes que les autres.

 

Du coup mon détecteur Nest de Monoxyde ne marche pas via ma fibaro et ma station météo et mon thermostat Netatmo remontent au bon vouloir (ainsi que d'autres add on mais bon je ne vais pas détailler ici).

Oui, mais ça reste assez souple quand on maitrise la bête. Je suis un Appleaddict depuis l'Apple II, et force est de constater que la solution Homekit par exemple ne me permet absolument pas toutes les subtilités de réglages qui se "veulent intelligents" comme je peux avoir avec le genialissime GEA entre autre. Et le défi intellectuel de temps en temps ça me plait, même si par rapport à ce fameux plugin, j'avais plus envie de meurtre et de casse de matériel qu'autre chose.

 

Après je te rejoins quand même sur un point, les "professionnels" de Netatmo/Fibaro auraient pu faire un plugin fonctionnel, ou en tout cas essayer de le mettre à jour au vu des nombreux retours de bugs...

 

Pour en revenir à mes moutons, je n'arrive toujours pas extraire le programme sélectionné, schedule_id. Mais j'arrive maintenant à le faire changer en utilisant une autre scène où je remplace la fonction SetAction de @Titof_44 par : 

function SetAction()
	DebugChange( "green", "Action : "..setpoint_mode)
	request_body_cam = 'access_token=' ..token.. '&device_id='..device_id ..'&module_id='..module_id ..'&setpoint_mode='..setpoint_mode
   	--Not Required
  	if setpoint_endtime~=nil then
    	request_body_cam =request_body_cam ..'&setpoint_endtime='..setpoint_endtime
    end
  	if setpoint_temp~=nil then
    	request_body_cam =request_body_cam ..'&setpoint_temp='..setpoint_temp
    end
    if schedule_id~=nil then
    	request_body_cam =request_body_cam ..'&schedule_id='..schedule_id
    end
  	getResponseData('https://api.netatmo.net/api/switchschedule', request_body_cam..'&schedule_id='.."57f8c4aac8bd001b678b50f0", 
    function(getData)
 	end
	)
end

avec, en fait, le changement d'adresse qui est /api/switchschedule, et je mets en "dur" l'id du programme. Ce n'est pas très élégant, mais au moins ça fait quelque chose. Je ne suis pas sur d'ailleurs que le if schedule_id sert à quelque chose, mais j'ai essayé... Le problème est que ça me fait faire 2 scènes par type de programme, une déclenchante et une où il y a la variable. Je pourrais utiliser une variable globale

 

Je n'arrive pas bien à comprendre en fait comment la scène trigger qui envoie la commande dans le script initial de Titoff_44 par exemple : 

fibaro:startScene(30,{ {setpoint_mode="program"} })

envoie à la scène 30, la valeur de la variable setpoint_mode. Je n'arrive pas le repérer dans le script, si c'est vraiment ça que ça fait. car j'ai essayé d'utiliser une scène trigger comme : 

fibaro:startScene(30,{ {setpoint_mode="program"}, {schedule_id="57f8c4aac8bd001b678b50f0"} })

bah ça ne marche pas.

 

L'idée sous-jacente est de faire un changement automatique de programme en fonction d'une variable globale Travail/Vacances scolaires qui se met déjà automatiquement à jour avec la technique décrite par  @pinou https://www.domotique-fibaro.fr/topic/2513-google-calendar-vers-hc2hcl/#entry35028 que j'utilise. Elle pourrait être vérifiée et mettre le programme adapté, en vérifiant auparavant qu'on n'est pas en mode away/absent, afin que ça ne change pas à l'insu de notre plein gré.

 

Je vous livre les fruits de mes reflexions actuelles, s'il y en a qui veulent phosphorer avec moi.

Modifié par pedia

Partager ce message


Lien à poster
Partager sur d’autres sites
Il y a 20 heures, pedia a dit :

Un peu mono maniaque en ce moment, j'essaie d'extraire le programme sélectionné qui se cache derrière/dans un object sur le site de dev.netatmo. Et là... Ça ne répond pas à la règle que j'avais donnée dans le petit tuto. Il faut surement utiliser une table, et là encore mes maigres connaissances en LUA/programmation ne me permettent pas d'y arriver... pour le moment...

 

A y est !!!!!!!

N'hésitez pas à rectifier si je dis des bêtises, mais dans ce que j'ai compris, les fameux objets sont des tables à ouvrir, c'est pour ça que je ne pouvais y avoir accès directement. J'ai donc fait :

for k, schedule in pairs(devices.therm_program_list) do
                  if schedule.program_id=="57f8c4aac8bd001b678b50f0" then
                    if schedule.selected==true then
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                    end
                  if schedule.program_id=="57f91fbde6da231c9c8b4f56" then
                    if schedule.selected==true then
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                    end
                  if schedule.program_id=="57f920aa1d7759f8988b4b10" then
                    if schedule.selected==true then
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                    end

La subtilité est que dans ces objets, on sait s'ils sont sélectionnés (variable selected) qui est une variable booléenne d'où la vérification si elle est true et pas simplement savoir si elle existe comme j'avais tenté de faire.

 

Je remets donc l'intégralité de la fonction getData :

function getDatas()
	DebugChange( "green", "Get Datas")
	request_body = 'access_token=' ..token.. '&device_id='..relay_id
  	getResponseData('https://api.netatmo.net/api/getthermostatsdata', request_body, 
    function(getData)
		Debug( "white", 'Status checking')
		if (getData.body ~= nil) then
			tDevices=getData.body.devices
   			for w, relays in pairs(tDevices) do
				Debug( "white", 'Id Relay : '..relays._id)
            

           		if relays._id==relay_id then
					for a, devices in pairs(relays.modules) do
						Debug( "white", 'Id Thermostat : '..devices._id)
                        Debug( "white", 'Temprature cible : '..devices.measured.setpoint_temp)
                        fibaro:call(113, "setProperty", "ui.Label3.value", devices.measured.setpoint_temp .." °C")

                          if devices._id==device_id then
							--pour les autres datas voir
                			-- https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata
        	    
                            curtemp=devices.measured.temperature
							Debug( "white", 'Temperature courante : '..curtemp)
                            fibaro:setGlobal("Temp_Salon", curtemp)
                            fibaro:setGlobal("Temp_Cible_Netatmo", devices.measured.setpoint_temp) 
                            batterylvl=devices.battery_percent
                            Debug( "white", 'Niveau des piles : '..batterylvl)
                            Debug( "white", 'Temprature cible : '..devices.measured.setpoint_temp)
                            fibaro:getValue(batterylvl, "value")
                            fibaro:getValue(devices.measured.setpoint_temp, "value")
                            Debug( "white", 'Mode : '..devices.setpoint.setpoint_mode)
                            fibaro:call(113, "setProperty", "ui.Label2.value", batterylvl .." % ")
                            fibaro:call(113, "setProperty", "ui.Label9.value", "Max.")
                           
                
                            if devices.therm_program_list.program_id=="57f8c4aac8bd001b678b50f0" then
                     		   Debug( "white", 'Nom du programme : '..devices.therm_program_list.selected) end

                            if devices.setpoint.setpoint_mode == "program" then
                               fibaro:call(113, "setProperty", "ui.Label4.value", "Programmé")    end  
                            if devices.setpoint.setpoint_mode == "away" then
                               fibaro:call(113, "setProperty", "ui.Label4.value", "Absent")    end
                            if devices.setpoint.setpoint_mode == "manual" then
                               fibaro:call(113, "setProperty", "ui.Label4.value", "Manuel")    end
                
                 for k, schedule in pairs(devices.therm_program_list) do
                  if schedule.program_id=="57f8c4aac8bd001b678b50f0" then
                    if schedule.selected==true then
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                    end
                  if schedule.program_id=="57f91fbde6da231c9c8b4f56" then
                    if schedule.selected==true then
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                    end
                  if schedule.program_id=="57f920aa1d7759f8988b4b10" then
                    if schedule.selected==true then
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                    end
                  end   
                  end
        			end
            	end
        	end
      	end
     end
      
	)
end

5908bdb786cf1_Capturedcran2017-05-0218_49_23.png.824507a9cde9da313db5150d031f87d8.png

 

Ça avance, ça avance...

Modifié par pedia
  • Upvote 1

Partager ce message


Lien à poster
Partager sur d’autres sites

Voici donc mon tuto en V2, toujours sans prétention vu que je ne fais que reprendre les scripts de Titof_44.

 

On va créer :

- un VD qui pour le moment permet de visualiser les principales données du thermostat, et commander les grandes fonctions.

- Mettre à jour automatiquement les programmes du thermostat (travail/vacances) en fonction de nos vacances si vous fonctionnez comme ça.

 

Je ne me suis pas encore lancé dans le réglage manuel de la température, car la récupération de la température cible avec latence ne me permet d'avoir un réglage aussi précis que je veux avec des boutons + / -

 

 

On va donc utiliser :

- une scène qui sert à récupérer les données du thermostat

- une scène qui sert commander le thermostat

- une scène pour le switch de programme

- un VD pour permettre de tout mettre en oeuvre

- Des variables globales : Mode_Thermostat, Nom_Prog_Thermo, Temp_Cible_Netatmo, Temp_Salon, Vacances

 

On commence par créer un VD afin d'avoir son ID de prêt. On créée par exemple 5 étiquettes, et 3 boutons.

 

5908ffb30fffa_Capturedcran2017-05-0223_51_48.png.a9b36532f776b1c7aded52d176b47b7c.png

 

 

 

La scène de récupération des données (ID33 chez moi) : 

--[[
%% properties
%% globals
%% killOtherInstances
--]]

local client_id = 'XXXXX'
local client_secret = 'XXXXXX'
local username = 'XXXXX'
local password = 'XXXXXXX'
local relay_idDefault="XXXXXX" --Relay
local device_idDefault="XXXXXX"	--Thermostat
--Toutes  ces infos se trouvent dans https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata
local debug = 1

local token = ''
local request_body = ''

Debug = function ( color, message )
  if (debug == 1) then
  	fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
  elseif (debug == 0) then
  end
end

DebugChange = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

DebugError = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

local sourceTrigger = fibaro:getSourceTrigger();

function oAuth(nextFunction)
	local request_body = 'grant_type=password&client_id=' .. client_id .. '&client_secret=' .. client_secret .. '&username=' .. username .. '&password=' .. password .. '&scope=read_thermostat'
	getResponseData('https://api.netatmo.net/oauth2/token', request_body, 
    	function(data) 
      		if (data.access_token ~= nil) then
        		token = data.access_token
       			getDatas()
     	 	else
       		 	DebugError( "red", "oAuth-API-Call n'a donné aucune valeur de retour");
      		end
    	end
    )
end

function getResponseData(url, body, func)
 local http = net.HTTPClient()
 http:request(url, { 
 options = { 
 method = 'POST', 
         headers = {
 ['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 },
 data = body
 },
 success = function(response)
 func(json.decode(response.data))
 end
 })   
end



function getDatas()
	DebugChange( "green", "Get Datas")
	request_body = 'access_token=' ..token.. '&device_id='..relay_id
  	getResponseData('https://api.netatmo.net/api/getthermostatsdata', request_body, 
    function(getData)
		Debug( "white", 'Status checking')
		if (getData.body ~= nil) then
			tDevices=getData.body.devices
   			for w, relays in pairs(tDevices) do
				Debug( "white", 'Id Relay : '..relays._id)
            

           		if relays._id==relay_id then
					for a, devices in pairs(relays.modules) do
						Debug( "white", 'Id Thermostat : '..devices._id)
                        
                        fibaro:call(113, "setProperty", "ui.Label3.value", devices.measured.setpoint_temp .." °C")

                          if devices._id==device_id then
							--pour les autres datas voir
                			-- https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata
        	    
                            curtemp=devices.measured.temperature
							Debug( "white", 'Temperature courante : '..curtemp)
                            fibaro:setGlobal("Temp_Salon", curtemp) --je mets  la température mesurée en variable globale
                            fibaro:setGlobal("Temp_Cible_Netatmo", devices.measured.setpoint_temp)  --je mets  la température cible en variable globale
                            batterylvl=devices.battery_percent
                            Debug( "white", 'Niveau des piles : '..batterylvl)
                            Debug( "white", 'Temprature cible : '..devices.measured.setpoint_temp)
                            Debug( "white", 'Mode : '..devices.setpoint.setpoint_mode)
                            fibaro:setGlobal("Mode_Thermostat", devices.setpoint.setpoint_mode)
                            fibaro:call(113, "setProperty", "ui.Label2.value", batterylvl .." % ")
                            
                        --je mets à jour les étiquettes du VD
                        --si on n est pas en mode Programmé, j'efface l'étiquette du nom du programme
      
                            if devices.setpoint.setpoint_mode == "program" then
                               fibaro:call(113, "setProperty", "ui.Label4.value", "Programmé")  end  
                            if devices.setpoint.setpoint_mode == "away" then
                               fibaro:call(113, "setProperty", "ui.Label4.value", "Absent")
                               fibaro:call(113, "setProperty", "ui.Label7.value", " ") end
                            if devices.setpoint.setpoint_mode == "manual" then
                               fibaro:call(113, "setProperty", "ui.Label4.value", "Manuel")
                               fibaro:call(113, "setProperty", "ui.Label7.value", " ") end
                
                 --On récupère le nom du programme  sélectionné, et on le met en plus dans une variable globale
      
                 for k, schedule in pairs(devices.therm_program_list) do
                     if schedule.program_id=="57f8c4aac8bd001b678b50f0" then
                             if schedule.selected==true and devices.setpoint.setpoint_mode == "program" then
                                fibaro:call(113, "setProperty", "ui.Label7.value", schedule.name)
                                fibaro:setGlobal("Nom_Prog_Thermo", schedule.name)
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                     end
                     if schedule.program_id=="57f91fbde6da231c9c8b4f56"  then
                             if schedule.selected==true and devices.setpoint.setpoint_mode == "program" then
                                fibaro:setGlobal("Nom_Prog_Thermo", schedule.name)
                                fibaro:call(113, "setProperty", "ui.Label7.value", schedule.name)
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                     end
                     if schedule.program_id=="57f920aa1d7759f8988b4b10" then
                             if schedule.selected==true and devices.setpoint.setpoint_mode == "program" then
                                fibaro:setGlobal("Nom_Prog_Thermo", schedule.name)
                                fibaro:call(113, "setProperty", "ui.Label7.value", schedule.name)
                                Debug( "white", 'Nom du programme : '..schedule.name) end 
                    end
                  end   
                  end
        			end
            	end
        	end
      	end
     end
      
	)
end

--recupération des arguments
local params = fibaro:args()
if (params) then
  for k, v in ipairs(params) do
    if (v.relay_id) then relay_id = v.relay_id end
    if (v.device_id) then device_id = v.device_id end
    if (v.devices.measured.setpoint_temp) then devices.measured.setpoint_temp = v.devices.measured.setpoint_temp end
	if (v.therm_program_list) then therm_program_list = v.therm_program_list end
    if (v.devices.measured.temperature) then devices.measured.temperature = v.devices.measured.temperature end
  end
end
if relay_id==nil then relay_id=relay_idDefault end	--Required mac address of the relay
if device_id==nil then device_id=device_idDefault end	--Required mac address of the thermostat



oAuth()

Il n'est pas encore nickel, il y a des redondances et autres probables améliorations.

 

Pour le nom des variables (j'enfonce peut-être des portes ouvertes) il faut se fier à l'arborescence que l'on trouve sur https://dev.netatmo.com/en-US/resources/technical/reference/thermostat/getthermostatsdata dans la section Try It, avec des subtilités :

devices : c'est relay

modules : c'est devices

Par exemple la température mesurée qui est sous l'arborescence modules/measured/temperature, la variable sera devices.measured.temperature

Le pourcentage des piles qui est juste sous modules/battery_percent, la variable sera devices.battery_percent

Dans la fonction getDatas on récupère les données qui nous intéressent et on les envoie à l'étiquette de notre VD correspondant.

 

Exemple pour le pourcentage des piles : 

                            fibaro:call(ID[VD], "setProperty", "ui.Label2.value", batterylvl .." % ")

J'ai mis la température mesurée également dans une variable globale pour essayer.

 

 

Pour la scène qui commande le thermostat, ID30 chez moi, (encore une fois je ne fais que recopier le script de Titoff_44)

 

--[[
%% properties
%% globals
%% killOtherInstances
--]]
local idg=json.decode((fibaro:getGlobal('idTable')))	--ids de mes modules
local client_id = 'XXXXXXXXXXXXXXXXXXXX'
local client_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
local username = 'xxxxxxxxxxxxxxx'
local password = 'xxxxxxxxxxxxxxxxxxxxx'
--local homeId = 'xxxxxxxxxxxxxxxxxxxxxxx'
-- homeId trouver sur site : https://my.netatmo.com/app/camera
-- a droite profil puis survol maison regarder sur barre chrome
local device_idDefault="xx:xx:xx:xx:xx:xx" --Relay
-- Relay trouvé sur site : https://my.netatmo.com/app/energy
-- Il suffit de remplacer le g par 70:ee:50.
--Par example g002460 a pour adresse MAC 70:ee:50:00:24:60
local module_idDefault="xx:xx:xx:xx:xx:xx"	--Thermostat
-- Thermostat trouvé sur site : https://dev.netatmo.com/resources/technical/reference/thermostat/getthermostatsdata
-- try it et dans le resultat aller à body devices _id modules _id
local debug = 1

local token = ''
local request_body = ''

Debug = function ( color, message )
  if (debug == 1) then
  	fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
  elseif (debug == 0) then
  end
end

DebugChange = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

DebugError = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

local sourceTrigger = fibaro:getSourceTrigger();

function oAuth(nextFunction)
	local request_body = 'grant_type=password&client_id=' .. client_id .. '&client_secret=' .. client_secret .. '&username=' .. username .. '&password=' .. password .. '&scope=write_thermostat'
	getResponseData('https://api.netatmo.net/oauth2/token', request_body, 
    	function(data) 
      		if (data.access_token ~= nil) then
        		token = data.access_token
       			SetAction()
     	 	else
       		 	DebugError( "red", "oAuth-API-Call n'a donné aucune valeur de retour");
      		end
    	end
    )
end

function getResponseData(url, body, func)
 local http = net.HTTPClient()
 http:request(url, { 
 options = { 
 method = 'POST', 
         headers = {
 ['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 },
 data = body
 },
 success = function(response)
 func(json.decode(response.data))
 end
 })   
end

function SetAction()
	DebugChange( "green", "Action : "..setpoint_mode)
	request_body_cam = 'access_token=' ..token.. '&device_id='..device_id ..'&module_id='..module_id ..'&setpoint_mode='..setpoint_mode
   	--Not Required
  	if setpoint_endtime~=nil then
    	request_body_cam =request_body_cam ..'&setpoint_endtime='..setpoint_endtime
    end
  	if setpoint_temp~=nil then
    	request_body_cam =request_body_cam ..'&setpoint_temp='..setpoint_temp
    end
  	getResponseData('https://api.netatmo.net/api/setthermpoint', request_body_cam, 
    function(getData)
 	end
	)
end

--recupération des arguments
local params = fibaro:args()
if (params) then
  for k, v in ipairs(params) do
    if (v.device_id) then device_id = v.device_id end
    if (v.module_id) then module_id = v.module_id end
    if (v.setpoint_mode) then setpoint_mode = v.setpoint_mode end
    if (v.setpoint_endtime) then setpoint_endtime = v.setpoint_endtime end
    if (v.setpoint_temp) then setpoint_temp = v.setpoint_temp end
  end
end

if setpoint_mode==nil then
  	fibaro:debug("Abort")
	fibaro:abort()
end

if device_id==nil then device_id=device_idDefault end	--Required mac address of the relay
if module_id==nil then module_id=module_idDefault end	--Required mac address of the thermostat
--setpoint_mode	--Required
--program 	: Currently following a weekly schedule
--away		: Currently applying the "away" temperature as defined by the user
--hg		: Frost-guard
--manual	: Currently applying a manually set temperature setpoint
--off		: Currently off
--max		: eating continuously
--setpoint_endtime --Not Required
--If setpoint_mode is max or manual, defines the validity period of the setpoint. Default is null.
--setpoint_temp --Not Required
--If setpoint_mode is manual, returns the temperature setpoint in °C.

DebugChange( "green", "device_id : "..device_id)
DebugChange( "green", "module_id : "..module_id)
DebugChange( "green", "setpoint_mode : "..setpoint_mode)

oAuth()

Attention subtilité les variables locales du début du script sont légèrement différentes de l'autre scène de récupération des données. Bien les remplir et ne pas faire un simple copier-coller.

 

 

Ensuite pour le commander au niveau des boutons du VD on rentre les commandes comme spécifiées dans le post de Titoff_44.

Par exemple : 

59064adcede21_Capturedcran2017-04-3022_35_50.png.a5a7f12c8dde9e85163c84e48f2b4a1f.png

La scène 30 est ma scène de commande du Thermostat. La scène 33 est celle qui récupère les données.

 

59064dc4d1a7a_Capturedcran2017-04-3022_48_35.png.9f4cf9f6a0083ea41c9bea5a9f96a24d.png

 

 

Voilà. J'ai remarqué une certaine latence chez moi pour la température cible qui se mettait à jour plusieurs secondes voire quelques minutes après le mise à jour du programme par exemple, mais même sur le site de Netatmo. Je ne sais pas s'il y a un moyen de forcer l'actualisation.

Je fais un petit refresh automatique des données avec GEA :

GEA.add( true , 60*60, "", {{"Scenario", 33}, {"Repeat"}})

 

Pour la scène de changement de programme, qui sera déclenchée via GEA (scène 37 chez moi) : 

--[[
%% properties
%% globals
%% killOtherInstances
--]]

local client_id = 'XXXXX'
local client_secret = 'XXXXX'
local username = 'xxxx'
local password = 'xxxxx'
--local homeId = 'xxxxxxxxxxxxxxxxxxxxxxx'
-- homeId trouver sur site : https://my.netatmo.com/app/camera
-- a droite profil puis survol maison regarder sur barre chrome
local device_idDefault="70:ee:50:1e:6b:70" --Relay
-- Relay trouvé sur site : https://my.netatmo.com/app/energy
-- Il suffit de remplacer le g par 70:ee:50.
--Par example g002460 a pour adresse MAC 70:ee:50:00:24:60
local module_idDefault="04:00:00:1e:8c:80"	--Thermostat
-- Thermostat trouvé sur site : https://dev.netatmo.com/resources/technical/reference/thermostat/getthermostatsdata
-- try it et dans le resultat aller à body devices _id modules _id
local debug = 1

local token = ''
local request_body = ''

Debug = function ( color, message )
  if (debug == 1) then
  	fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
  elseif (debug == 0) then
  end
end

DebugChange = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

DebugError = function ( color, message )
  fibaro:debug(string.format('<%s style="color:%s;">%s', "span", color, message, "span"))
end

local sourceTrigger = fibaro:getSourceTrigger();

function oAuth(nextFunction)
	local request_body = 'grant_type=password&client_id=' .. client_id .. '&client_secret=' .. client_secret .. '&username=' .. username .. '&password=' .. password .. '&scope=write_thermostat'
	getResponseData('https://api.netatmo.net/oauth2/token', request_body, 
    	function(data) 
      		if (data.access_token ~= nil) then
        		token = data.access_token
       			fibaro:sleep(500) 
                       --j attends un peu pour ne pas le précipiter et attendre que la box mette à jour ces varibales globales
                SetAction()
                fibaro:sleep(1000)
                fibaro:startScene(33) --je rafraichis mon VD
     	 	else
       		 	DebugError( "red", "oAuth-API-Call n'a donné aucune valeur de retour");
      		end
    	end
    )
end

function getResponseData(url, body, func)
 local http = net.HTTPClient()
 http:request(url, { 
 options = { 
 method = 'POST', 
         headers = {
 ['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
 },
 data = body
 },
 success = function(response)
 func(json.decode(response.data))
 end
 })   
end
--j'appelle l'id du nouveau programme désiré
local newprog = fibaro:getGlobalValue("Nom_Prog_Thermo")
if newprog == "Vacances scolaires" then
   newprog_id = "57f920aa1d7759f8988b4b10" end
if newprog == "Semaine Type" then
   newprog_id = "57f8c4aac8bd001b678b50f0" end

function SetAction()
	DebugChange( "green", "Action : changment de programme "..newprog)
    	
    request_body_cam = 'access_token=' ..token.. '&device_id='..device_id ..'&module_id='..module_id 
  	
  	getResponseData('https://api.netatmo.net/api/switchschedule', request_body_cam..'&schedule_id='..newprog_id, 
    function(getData)
 	end
	)
end


--recupération des arguments
local params = fibaro:args()
if (params) then
  for k, v in ipairs(params) do
    if (v.device_id) then device_id = v.device_id end
    if (v.module_id) then module_id = v.module_id end
    if (v.setpoint_mode) then setpoint_mode = v.setpoint_mode end
    if (v.setpoint_endtime) then setpoint_endtime = v.setpoint_endtime end
    if (v.setpoint_temp) then setpoint_temp = v.setpoint_temp end
    if (v.schedul_id) then schedule_id = v.schedule_id end
  end
end



if device_id==nil then device_id=device_idDefault end	--Required mac address of the relay
if module_id==nil then module_id=module_idDefault end	--Required mac address of the thermostat
--setpoint_mode	--Required
--program 	: Currently following a weekly schedule
--away		: Currently applying the "away" temperature as defined by the user
--hg		: Frost-guard
--manual	: Currently applying a manually set temperature setpoint
--off		: Currently off
--max		: eating continuously
--setpoint_endtime --Not Required
--If setpoint_mode is max or manual, defines the validity period of the setpoint. Default is null.
--setpoint_temp --Not Required
--If setpoint_mode is manual, returns the temperature setpoint in °C.


oAuth()

 

Avec la technique de @pinou, j'ai une variable globale "Vacances" qui se met à jour automatiquement via mon calendrier en Travail / Vacances scolaires.

 

Pour la synchro des mes vacances avec le bon mode programmé, j'utilise GEA : 

GEA.add({{"Global", "Vacances", "Travail"}, {"Global", "Mode_Thermostat", "program"}}, -1, "Changement programme Netatmo Travail", {{"Global", "Nom_Prog_Thermo", "Semaine Type"}, {"Scenario", 37}})
GEA.add({{"Global", "Vacances", "Scolaire"}, {"Global", "Mode_Thermostat", "program"}}, -1, "Changement programme Netatmo Vacances", {{"Global", "Nom_Prog_Thermo", "Vacances scolaires"}, {"Scenario", 37}})

Je précise bien dans les conditions que je dois être en mode "program", car supposons que je parte hors vacances scolaires et que je mette volontairement en mode absence (away), je ne voudrais pas qu'il me rebascule sur un mode programmé. Le scenario 37 est chez moi la scène de changement de programme.

 

 

C'est assez fonctionnel, même si ça mérite de nombreuses améliorations comme de pouvoir choisir la température cible. Mais ça à le mérite de marcher chez moi, alors que le plugin de Netatmo avait été incapable jusque là de simplement trouver le thermostat sur mon réseau et ce malgré de nombreuses et infructueuses tentatives (cf. mes posts précédents désespérés).

 

Prochaine étape, le réglage en manuel de la température via le VD.

 

J'ai retrouvé le sourire, et oui, ceux qui hésitait à acheter ce thermostat, peuvent franchir le pas à présent.

Modifié par pedia
  • Upvote 3

Partager ce message


Lien à poster
Partager sur d’autres sites

Félicitations !! Top. A voir sil peut y avoir d'autres éléments du tableau.
Reste plus qu a faire une seule scène pour la lecture et l'écriture :-).
Merci pour le boulot.

Envoyé de mon Nexus 5X en utilisant Tapatalk

Partager ce message


Lien à poster
Partager sur d’autres sites

indeed ca serait plus pratique de tout mettre dans 1 seule scene. possible ?

je devrai avoir le temps de tester ce weekend

Partager ce message


Lien à poster
Partager sur d’autres sites

En attendant les optimisations de scènes, j'ai fait quelques icônes pour le VD. J'ai créée un album dans la section icône (je n'ai pas réussi à l'ajouter dans l'album Netatmo déjà existant).

 

Quelques exemples.

Thermo_manuel_20_0.png

Thermo_Max.png

Thermo_Away.png

Thermo_Prog.png

  • Upvote 2

Partager ce message


Lien à poster
Partager sur d’autres sites

Tiens question, si on ajoute des modules additionnels sur la station, ils sont bien reconnu par la HC2 ensuite au niveau du plugin (Je parle module intérieur temp/hygro/co2) ?

Partager ce message


Lien à poster
Partager sur d’autres sites

×