Aller au contenu

Messages recommandés

Posté(e) (modifié)
Il y a 9 heures, Lazer a dit :

J'ai pas trop le temps de relire ton code en ce moment, si tu es pressé, regarde ce que fait le code source de mon QuickApp, dans le fichier Library - Enphase v2.00.lua dans la function Enphase:getToken()

Salut Lazer,

Merci d'avoir répondu.

J'ai déjà pas mal étudié ton code tout le dimanche. Je n'ai pas les compétences pour tout comprendre et l'adapter à la HC2.

 

Mais je ne suis pas pressé, donc quand tu auras le temps à l'occaz ;)

 

 

Modifié par stipower
Posté(e)

Oui mais il ne s"agit pas de comprendre tout le code, je t'ai juste indiqué le nom de la fonction dans mon code qui fait ce que tu demandes, à savoir l'obtention du token, ça devrait te donner une bonne piste.

Par ailleurs, la HC2, j'ai laissé tombé il y a 3 ans, donc difficile d'adapter du code LUA dessus pour moi...

Posté(e) (modifié)

Salut Lazer,

 

Je comprends.

 

Bon, un collègue m'a débloqué, j'ai pu terminé mon script.

 

Je poste mon Code pour scène HC2 qui est maintenant fonctionnel. Ca peut toujours servir à quelqu'un :

 

-- GetEnphaseToken
--[[
%% autostart
%% properties
%% events
%% globals
--]]
-- récupère le Token de Enphase pour faire les connexion sur le boitier Envoy

local IDNotifMailAdmin = 2
local TempsDeBoucle = 24 * 3600 * 1000 -- 1 journée

function RequestHTTP()

-- ************************************	 Get SessionID ************************************

	local EnphaseURLlogin = "https://enlighten.enphaseenergy.com/login/login.json?"
	local EnphaseURLToken = "https://entrez.enphaseenergy.com/tokens"
	local envoy_serial = "XXXXXXXX" -- sérial de l'installation Enphase
	local user ="XXXXXXXX"
	local password = "XXXXXXXX"
	local SessionID
	local http = net.HTTPClient()

	local DataEnphaseURLlogin = '{"user": {"email": "'.. user .. '", "password": "' .. password .. '"}}'  
		-- attendu : DataEnphaseURLlogin = '{"user": {"email": "XXXX", "password": "XXXX"}}' 
	
	fibaro:debug("Get session_id")

	http:request(EnphaseURLlogin, {
		options = {
			checkCertificate = false,
			method = 'POST',
			headers = {
				['Accept'] = 'application/json',
				['Content-Type'] = 'application/json',
				},
			data = DataEnphaseURLlogin,
			timeout = 10000
			},

		success = function(response)
			--fibaro:debug(response.status)
			if (response.status == 200 or response.status == 201) and type(response.data) == "string" and response.data ~= "" then
				-- réponse OK
				--fibaro:debug(response.data)
				--[[ reponse attendue : 
					{"message":"success",
					"session_id":"9beb21c28d7893090e9c42746830bdba",
					"manager_token":"eyJhbGciOiJIUzI......1NiJ9.eyJkYXRh",
					"is_consumer":true,"system_id":2438074}
					--]]
				SessionID = json.decode(response.data)
				SessionID = SessionID.session_id
				fibaro:debug("session_id = " .. SessionID)

-- ************************************	 Get Token ************************************
				fibaro:debug("Get Token")

				local DataEnphaseURLToken = '{"session_id" : "' .. SessionID .. '", "serial_num" : "' .. envoy_serial .. '", "username" : "' .. user .. '"}'
					-- attendu : DataEnphaseURLToken = '{"session_id" : "XXXX", "serial_num" : "XXXX", "username" : "XXXX"}'

				http:request(EnphaseURLToken, {
						options = {
							checkCertificate = false,
							method = 'POST',
							headers = {
								['Accept'] = 'application/json',
								['Content-Type'] = 'application/json',
								 },
							data = DataEnphaseURLToken,
							timeout = 10000
							},

						success = function(response)
							--fibaro:debug(response.status)
							if (response.status == 200 or response.status == 201) and type(response.data) == "string" and response.data ~= "" then
								if type(response.data) == "string" and response.data ~= "" then	
									-- réponse OK
									--fibaro:debug(response.data)
									local Token = response.data
									fibaro:debug("Token = " .. Token)
									fibaro:setGlobal("TokenEnphase",Token) --> envoie du Token dans une variable globale
								else
									-- réponse Pas OK
									fibaro:debug('GetEnphaseToken response code : ' .. response.status)
									local msg = 'GetEnphaseToken response code : ' .. response.data
									fibaro:debug(msg)
									SendMail(msg)
								end
							end
						end,

						error = function(err)
							local msg = "GetEnphaseToken Erreur : " .. err
							fibaro:debug(msg)
							SendMail(msg)
						end,
						}
					)
					
			else
				-- réponse Pas OK
				fibaro:debug('GetEnphaseSession response code : ' .. response.status)
				local msg = 'GetEnphaseSession response code : ' .. response.data
				fibaro:debug(msg)
				SendMail(msg)			
			end
		end,
		
		error = function(err)
			local msg = "GetEnphaseSession Erreur : " .. err
			fibaro:debug(msg)
			SendMail(msg)
		end,
		}
	)
end

function SendMail(MsgErr)
	fibaro:call(IDNotifMailAdmin, 'sendEmail', 'HC2 Erreur EnphaseToken', os.date("%x " .. "%X") .. " " .. MsgErr)
end

function loop()
	
	fibaro:debug(os.date("%x " .. "%X"))
	RequestHTTP()

	setTimeout(loop,TempsDeBoucle)
	
end
setTimeout(loop,0)

Code corrigé le 23/03/2024

Modifié par stipower
  • Like 2
  • 3 semaines après...
Posté(e) (modifié)

J'ai corrigé mon code de scène HD2 et ai ajouté un envoi de mail en cas de mauvais logins/password.

Modifié par stipower
  • 7 mois après...
Posté(e)

Salut Lazer,

 

Je suis passé sur HC3. Je m'intéresse donc à ta Qapp qui me va très bien.

J'ai néanmoins ces messages d'erreur dès que je passe à moins de 60 secondes de refresh (RefreshInterval)

 

[07.11.2024] [22:01:29] [WARNING] [QA_ENPHASE_73]: Using old token
[07.11.2024] [22:01:39] [ERROR] [QA_ENPHASE_73]: Can't get Enphase inventory : Operation canceled
[07.11.2024] [22:01:54] [ERROR] [QA_ENPHASE_73]: Can't get new token : Operation canceled

 

Et forcément, les childs sont sans valeur.

 

J'ai réussis à porter mon code de HC2 vers HC3. Et j'ai bien un refresh de 3 secondes comme sur mon HC2 sans souci qui me donne les valeurs de conso, productions, etc.

Je n'ai pas toutes les compétences pour décortiquer tout ton code qui est bien plus propre que le mien Et il y a surement des contraintes que je n'ai pas comprises,  mais du coup je m'interroge sur pourquoi ta Qapp ne marche pas chez moi :( .

Qu'en penses tu ?

 

Posté(e)

Ah c'est dommage ça, tu aurais donc le même problème que @TitiXsi dont on a parlé également sur les topics des 2 autres QuickApps dédiés à cette passerelle Envoy...


Franchement je ne sais pas quoi en penser, il y a la piste de la connexion réseau Ethernet versus Wi-Fi, mais aussi la piste de la présence, ou non, des 2 pinces de mesure de courant.... à moins que ça ne soit encore autre chose ?

Posté(e) (modifié)

Ce n'est pas un problème réseau.

J'ai les même symptômes en WIFI (ping 3ms) et LAN (ping 1ms).

Et j'aurais aussi les problème avec mon code.

 

Peut-être plus sur net.HTTPClient() ?

 

Ca c'est ma fonction qui choppe le token toutes les heures.

 

	local EnphaseURLlogin = "https://enlighten.enphaseenergy.com/login/login.json?"
	local EnphaseURLToken = "https://entrez.enphaseenergy.com/tokens"
	local envoy_serial = "XXXXXXX" -- sérial de l'installation Enphase
	local user ="XXXXXX"
	local password = "XXXXX"
	local SessionID
	local http = net.HTTPClient()

	local DataEnphaseURLlogin = '{"user": {"email": "'.. user .. '", "password": "' .. password .. '"}}'  
		-- attendu : DataEnphaseURLlogin = '{"user": {"email": "XXXX", "password": "XXXX"}}' 
	
	--fibaro.debug("test","Get session_id")

	http:request(EnphaseURLlogin, {
		options = {
			checkCertificate = false,
			method = 'POST',
			headers = {
				['Accept'] = 'application/json',
				['Content-Type'] = 'application/json',
				},
			data = DataEnphaseURLlogin,
			timeout = 10000
			},

		success = function(response)
			--fibaro.debug("test",response.status)
			if (response.status == 200 or response.status == 201) and type(response.data) == "string" and response.data ~= "" then
				-- réponse OK
				--.debug("test",response.data)
				--[[ reponse attendue : 
					{"message":"success",
					"session_id":"XXXXXXXXXXX",
					"manager_token":"eyJhbGciOiJIUzI......1NiJ9.eyJkYXRh",
					"is_consumer":true,"system_id":XXXXXXXX}
					--]]
				SessionID = json.decode(response.data)
				SessionID = SessionID.session_id
				--fibaro.debug("test","session_id = " .. SessionID)

-- ************************************	 Get Token ************************************
				--fibaro.debug("test","Get Token")

				local DataEnphaseURLToken = '{"session_id" : "' .. SessionID .. '", "serial_num" : "' .. envoy_serial .. '", "username" : "' .. user .. '"}'
					-- attendu : DataEnphaseURLToken = '{"session_id" : "XXXX", "serial_num" : "XXXX", "username" : "XXXX"}'

				http:request(EnphaseURLToken, {
						options = {
							checkCertificate = false,
							method = 'POST',
							headers = {
								['Accept'] = 'application/json',
								['Content-Type'] = 'application/json',
								 },
							data = DataEnphaseURLToken,
							timeout = 10000
							},

						success = function(response)
							--fibaro.debug("test",response.status)
							if (response.status == 200 or response.status == 201) and type(response.data) == "string" and response.data ~= "" then
								if type(response.data) == "string" and response.data ~= "" then	
									-- réponse OK
									--fibaro.debug("test",response.data)
									local Token = response.data
									fibaro.debug("test","Token = " .. string.format("Token ok","01"))
									self:setVariable("TokenEnphase",Token) --> envoie du Token dans une variable globale
								else
									-- réponse Pas OK
									fibaro.debug("test",'GetEnphaseToken response code : ' .. response.status)
									local msg = 'GetEnphaseToken response code : ' .. response.data
									fibaro.debug("test",msg)
									SendMail(msg)
								end
							end
						end,

						error = function(err)
							local msg = "GetEnphaseToken Erreur : " .. err
							fibaro.debug("test",msg)
							SendMail(msg)
						end,
						}
					)
					
			else
				-- réponse Pas OK
				fibaro.debug("test",'GetEnphaseSession response code : ' .. response.status)
				local msg = 'GetEnphaseSession response code : ' .. response.data
				fibaro.debug("test",msg)
				SendMail(msg)			
			end
		end,
		
		error = function(err)
			local msg = "GetEnphaseSession Erreur : " .. err
			fibaro.debug("test",msg)
			SendMail(msg)
		end,
		}
	)

	fibaro.setTimeout(60 * 60 * 1000, function() GetEnvoyToken(self) end)

end

 

Ca c'est ma fonction qui choppe la table de l'envoy toutes les 3 secondes pour la mettre dans une variable :

 

function GetEnvoyLive(self)
	-- TableEnvoyLive

	local Token = self:getVariable("TokenEnphase")
	--fibaro.debug("test","Token = " .. Token)

	local Bearer = 'Bearer ' .. Token
	local URL = "https://192.168.X.X"
	local API = "/ivp/meters/readings"

	local http = net.HTTPClient()
	http:request(URL .. API, {
		options = {
			checkCertificate = false,
			method = 'GET',
			headers = {
				['Accept'] = 'application/json',
				['Content-Type'] = 'application/json',
				['Authorization'] = Bearer },
			timeout = 10000
			},
		success = function(response)
			local result = response.data;

			if response.status == 200 or response.status == 201 then
			-- réponse OK	
				self:setVariable("TableEnvoy", response.data)
				--fibaro.debug("test",response.data) 
				TableEnvoy = json.decode(response.data)
				--fibaro.debug("test","activePower = " .. TableEnvoy[2].activePower)
				self:updateProperty("value", TableEnvoy[2].activePower)
			else
			-- réponse Pas OK
				fibaro.debug("test",'response code : ' .. response.status)
				fibaro.debug("test","TableEnvoy -> False")	
				self:setVariable("TableEnvoy", "False")
				fibaro.debug("test",response.data)			
			end
		end,
		
		-- Erreur sur la fonction
		error = function(err)
			fibaro.debug("test",'function(err) : ' .. err)
			fibaro.debug("test","TableEnvoy -> False")	
			self:setVariable("TableEnvoy", "False")
		end
	})
	
	fibaro.setTimeout(3 * 1000, function() GetEnvoyLive(self) end)
end

 

Et ca ma fonction qui choppe les values de la table toutes les 3 secondes (et qui les colle pour l'instant dans un label de ma Qapp).

 

function GetTableEnvoy(self)
	 -- récupération des valeur de l'Envoy  ********************************************************************************************************

	local JsonTableEnvoy = self:getVariable("TableEnvoy") -- donwload de la table en string
	--fibaro.debug("test",string.sub(JsonTableEnvoy,1,400)) -- affiche les 400 premiers caractères
		
	if JsonTableEnvoy == nil or string.len(JsonTableEnvoy) < 50 then -- creation de la variable global si necessaire (variable nulle ou corrompue)
		fibaro.debug("test","Table JsonTableEnvoy Corrompu")
		fibaro.debug("test",JsonTableEnvoy)
	else
		local TableEnvoy = json.decode(JsonTableEnvoy) -- conversion table string en table
		PowerPVautoconsoW = math.floor(TableEnvoy[1].activePower,'PowerPVautoconsoW')		-- production solaire autoconsommation
		EnergieCompteurW = -math.floor(TableEnvoy[2].activePower,'EnergieCompteurW')	-- Compteur linky puissance actrive en watts
		EnergieCompteurVA = math.floor(TableEnvoy[2].apparentPower,'EnergieCompteurVA')	-- Compteur linky Puissance apparente en VA
		cosphi = TableEnvoy[2].pwrFactor,'cosphi'						-- cosphi
		--fibaro.debug("test","EnergieCompteurW = " ..EnergieCompteurW)
		self:updateView("label_ID_0", "text", "PowerPVautoconsoW = "..PowerPVautoconsoW..", EnergieCompteurW = "..EnergieCompteurW)
	end

	fibaro.setTimeout(3 * 1000, function() GetTableEnvoy(self) end)
end

 

Si tu as un episte, je peux t'aider à faire des tests.

Sinon, je vais chercher comment faire des childs (j'ai pas encore trouvé) pour me faire mon propre Qapp. Mais c'est dommage de refaire le même design que toi :/

 

 

Modifié par stipower
Posté(e)

Hum... tu veux dire que sur HC2, tu arrives à interroger l'Envoy avec un intervalle très court, tandis que ça ne fonctionne pas sur HC3 ?

Dans ce cas, alors il doit y avoir un souci avec le code LUA.... j'ai pas lu ton code (déjà met la coloration syntaxique, ça sera plus avenant), et ça fait maintenant des années que j'ai codé mon QuickApp donc je n'ai plus tout ça en tête... il faudrait que je me replonge dedans pour voir de quel façon l'optimiser... un jour peut être... dans quelques mois.... sachant que je n'ai pas le problème chez moi, donc difficile à reproduire.

Sinon tu peux prendre le code de mon QuickApp et faire tes tests à partir de ça, l'avantage c'est que la gestion des child devices est déjà en place.

Posté(e)

Non pas du tout. Mon code marche dans une QA sur HC3 (et aussi ma HC2) toutes les 3 secondes.

C'est ca que je trouve bizarre.

Posté(e)

Ah OK... bon bah alors c'est vraiment la faute de mon code.

Ce qui est étonnant alors, car les 2 autres QA du forum, qui sont complètement différents, ont le même problème.... ce qui est étonnant aussi, c'est que le problème n'apparait pas chez moi.
A devenir fou....


 

Posté(e) (modifié)

Tu 'as aucun message d'erreur avec ton QA même à 3 secondes de refresh ?

 

Ca peut aussi être du à la passerelle qui serait différente ou avec un autre firmware.

Quelle est la version de firmware de ta passerelle Envoy ?

La mienne est en D8.2.4264 (882efd) du 27 juin 2024

 

 

Modifié par stipower
Posté(e)

Je suis à 5 secondes, et non absolument aucune erreur.

Comme je le disais sur l'autre topic, temps de réponse inférieur à la seconde, parfois 2s.

 

Firmware D8.2.4264 apparemment, donc comme toi.

De toute façon chez Enphase on ne choisi pas (plus), les mises à jour sont poussées à distance depuis leur cloud.

Posté(e) (modifié)

Hello. Sous 30sd, j'avais vu un impact des requêtes qui s'emplafonnent. Le callback n'attend pas le retour de la précédente et balance déjà la suivante. Dans ma qa j'ai codé une fonction qui permet de vérifier qu'il n'y a pas déjà une requête en cours,si c'est le cas je bypass. Tu n'as pas répondu petite question est-ce que tu as une pince de consommation ?

Modifié par TitiXsi
Posté(e)

Salut TitiXsi,

 

Ton hypothèse sur les requêtes qui s'emplafonnent semble cohérente.

 

J'ai effectivement 2 pinces. Une pour le prod et une sur mon linky.

 

Posté(e)

Effectivement, bonne remarque sur les requêtes qui s'empilent... comme dit, je n'ai plus mon code en tête, mais c'est une idée de vérification et d'optimisation potentielle.

 

J'avais eu ce souci sur un autre QA plus récent (celui des PAC Mitsu avec ESPHome), et j'avais développé tout une gestion de file d'attente des requêtes. C'est une idée à creuser... d'autant plus qu'entre temps, il me semble que mon QA Yamaha Musiccast fait face au même problème dans certaines circonstances...

Posté(e)

C'est assez à mettre en place sur cette qa qui fait toujours la même requête... Donc on peut en abandonner une sans soucis. Pas besoin de file d'attente.

J'avais expliqué ma démarche je soumais une requête compteur incrémenté je quitte, je décremente. Pour le besoin, si mon compteur est >1, je passe...

C'est devenu ultra fiable 😉

Posté(e) (modifié)

@Lazer it's seems that my token created the 06nov2023 has been revoked this day. (1year + 9 days)

Our QA was not abble to generate a new token. I have do it by hands and filled it into the variables.

 

This date is corresponding to the date given as expired date into the token

 

 

Modifié par TitiXsi
Posté(e) (modifié)

Hum.... comment tu t'es rendu compte du changement de token ?
Je viens de regarder les logs de mon QA, tout tourne, et dans l'historique (quelques heures seulement) pas de trace de changement de token.
Après peut être que mon token a été généré après le tient et que je vais avoir le même problème dans les jours qui viennent...

 

EDIT : bon bah j'ai la réponse, j'ai décodé le token en base64 et il expire le 03/03/2025... ça me laisse de la marge.

 

N'empêche, ça n'explique pas pourquoi le tiens n'a pas été rafraichis automatiquement par le QA.

Mais dis-moi... tu utilises ton QA, pas le miens ?

 

Modifié par Lazer
Posté(e)

Oui c'est ma qa, mais c'est ton code pour toutes les requêtes http. J'ai juste rajouté des extractions pour les mo... 😉. J'ai oublié de copier le log. C'était "Bad connection, impossible to get new token." Par contre, je n'ai pas essayé en effaçant le token dans les variables. Car de mémoire, ça marche très pour initialiser la qa.

Posté(e)

Ah OK, je n'ai pas lu ton code, mais tu n'as peut être pas intégré de routine de détection du token expiré, puis demande d'un nouveau ?

En redémarrant ton QA, c'est à ce moment là que le token aurait pu être régénéré.

 

La mise à jour de mon QA date de juillet 2023.
En mars 2024, il a certainement renouvelé tout seul le token, en tout cas je n'ai eu aucun dysfonctionnement, je ne m'en suis pas rendu compte.

Et donc vu la validité de 1 an, il devrait être renouvelé automatiquement en mars 2025.

Il faudrait que je me mette une alarme pour surveiller le log ce jour là.

 

×
×
  • Créer...