Shelly, Dzvents, json and syntax

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
MarsaultP
Posts: 33
Joined: Wednesday 27 November 2019 13:31
Target OS: Linux
Domoticz version: 2024.7
Location: France
Contact:

Shelly, Dzvents, json and syntax

Post by MarsaultP »

Hi,
I use a WiFi relay Shelly 1, command via device Switch and action with http and json like this :

Code: Select all

return
--[[
Shelly_SDB controller with an independent temperature sensor and a virtual thermostat

Dependencies :
Dummy device -> Thermostat set point
Dummy device -> Switch On/Off
Device temperature -> reference room temperature (NOT internal Shelly_SDB temperature)

doc : 
https://shelly-api-docs.shelly.cloud/#shelly-family-overview   => communications au format json
https://www.domoticz.com/forum/viewtopic.php?f=34&t=21126&sid=6eef839efc599b4eb44db319e1435060&start=20
https://www.domoticz.com/wiki/DzVents:_next_generation_Lua_scripting
https://en.wikipedia.org/wiki/PID_controller
https://www.domoticz.com/wiki/Daikin_wifi

https://www.domoticz.com/wiki/Plugins/Smart_Virtual_Thermostat.html
	  
Philippe Marsault 11/04/2021
]]-- 
{
	active = true,

	on = {
		timer 			= {'every 5 minutes'}
	},

	execute = function(dz, item)
	
		function round(x)
			return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
		end
		
		local IP_Shelly_SDB		= '192.168.2.27'
		local Idx_sonde_T		= 92    -- reference room temperature
		local Idx_thermostat	= 118   -- Room thermostat
		local Idx_SDB_selector	= 121   -- Switch for manual command
		local Idx_SDB_Power		= 120   -- Power counter and energy
		local Power				= 750	-- Heater power
		local Idx_ther_OnOff	= 100   -- Global swith for this script, example : use for holidays
		local relay_Shelly_SDB
		
		local ther_setpoint		= dz.devices(Idx_thermostat).setPoint    -- Read thermostat set point
		local room_temperature	= dz.devices(Idx_sonde_T).temperature -- Read room temperature
		local selecteur_SDB		= dz.devices(Idx_SDB_selector).levelName -- Read SDB selector (Off, Manuel, Auto)
		
		if (item.isTimer) then
			if (selecteur_SDB == 'Off') then
				ther_setpoint = dz.variables('T_SDB_Off').value  -- temperature hors gel
				dz.log ('Salle de bain mode OFF - '..ther_setpoint..'°C')
			end
			if (selecteur_SDB == 'Manuel') then
				ther_setpoint = dz.variables('T_SDB_manuel').value -- temperature marche manuel
				dz.log ('Salle de bain mode MANUEL - '..ther_setpoint..'°C')
			end
			if (selecteur_SDB == 'Auto') then
				dz.log ('Salle de bain mode AUTO')
			end
			-- traitement genetic de regulation
			if (room_temperature > ther_setpoint) then
				relay_Shelly_SDB	= 'off' -- command to relay
				dz.devices(Idx_SDB_Power).updateElectricity(0.0, 0.0)	-- Update computed power
				dz.log ('Radiateur SDB etat Off')
			else
				relay_Shelly_SDB	= 'on' -- command to relay to heat
				dz.devices(Idx_SDB_Power).updateElectricity(Power, 0.0)	-- Update computed power
				dz.log ('Radiateur SDB etat On')
			end
		end
		
		local command_shelly = 'http://'..IP_Shelly_SDB..'/relay/0?turn='..relay_Shelly_SDB
				-- dz.log ('command_write setpoint ->'..command_setpoint)																
		dz.openURL({url = command_shelly})							-- send command to Shelly_SDB server
		
	end
}
No problem : that work well !!!

BUT, now, I am testing a other relay Shelly 1PM with a Dallas add-on, so it's possible to retrieve power, energie and Dallas temperature
I can read power and energie, but impossible to obtain the temperature in Dzvents !!!

When I test in a web browser the Shelly command with :
http://192.168.2.126/status

The json result is :

{"wifi_sta":{"connected":true,"ssid":"NETGEAR25_EXT","ip":"192.168.2.126","rssi":-70},"cloud":{"enabled":true,"connected":true},"mqtt":{"connected":false},"time":"17:39","unixtime":1619365158,"serial":789,"has_update":false,"mac":"E8DB84D79D89","cfg_changed_cnt":0,"actions_stats":{"skipped":0},"relays":[{"ison":false,"has_timer":false,"timer_started":0,"timer_duration":0,"timer_remaining":0,"overpower":false,"source":"http"}],"meters":[{"power":0.00,"overpower":0.00,"is_valid":true,"timestamp":1619372358,"counters":[0.000, 0.000, 0.000],"total":15615}],"inputs":[{"input":0,"event":"","event_cnt":0}],"temperature":39.86,"overtemperature":false,"tmp":{"tC":39.86,"tF":103.75, "is_valid":true},"temperature_status":"Normal","ext_sensors":{"temperature_unit":"C"},"ext_temperature":{"0":{"hwID":"285ca347321901c7","tC":19.06,"tF":66.31}},"ext_humidity":{},"update":{"status":"idle","has_update":false,"new_version":"20210415-131256/v1.10.3-g23074d0","old_version":"20210415-131256/v1.10.3-g23074d0"},"ram_total":49800,"ram_free":37532,"fs_size":233681,"fs_free":149094,"uptime":35937}

So, item temperature exist under "ext_temperature" and "tC":19.06
But impossible to define the right syntax to retrieve tC value in the following code :

Code: Select all

return
--[[
Shelly controller with an independent temperature sensor and a virtual thermostat

Dependencies :
Dummy device -> Thermostat set point
Dummy device -> Switch On/Off
Device temperature -> reference room temperature (add-on Dallas on Shelly)

doc : 
https://shelly-api-docs.shelly.cloud/#shelly-family-overview   => communications au format json
https://www.domoticz.com/wiki/DzVents:_next_generation_Lua_scripting
https://www.domoticz.com/wiki/Plugins/Smart_Virtual_Thermostat.html
	  
Philippe Marsault 25/04/2021
]]-- 

{
	active = true,
	on = {
		timer = { 'every 1 minutes' },            -- every minute for testing, 10 minutes when active
		httpResponses = { 'Shelly1PMRetrieved' }  -- matches callback string below
	},
		logging =   {
		level   =   domoticz.LOG_DEBUG,      -- change to LOG_ERROR when script runs without problems otherwise LOG_DEBUG / LOG_ERROR                           
		marker  =   "Dallas-Temperatures" },   
		
	execute = function(dz, item)
	
		local function logWrite(str,level)
            dz.log(tostring(str),level or dz.LOG_DEBUG)
        end

		if (item.isTimer) then
			dz.openURL({
				url = 'http://192.168.2.126/status',
				method = 'GET',
				callback = 'Shelly1PMRetrieved'
			})

		elseif (item.isHTTPResponse) then
			if (item.ok and item.isJSON) then
			dz.log("Reponse Shelly OK")
				local power = item.json.meters[1].power
				dz.log ('Puissance ->'..power)
				local energie = item.json.meters[1].total
				dz.log ('Energie ->'..energie)
				--dz.log(item.data)
				--dz.utils.dumpTable(item.json)
				local room_temperature = item.json.ext_temperature[1].tC
				dz.log ('room_temperature ->'..room_temperature)
		else
				-- oops
				dz.log('Error fetching Shelly data', domoticz.LOG_ERROR)
				dz.log(item.data, domoticz.LOG_ERROR)
			end
		end
	end
}
Domoticz log show this error :

2021-04-25 18:32:01.282 Status: dzVents: Info: Dallas-Temperatures: ------ Start external script: script-time_regul_Chambre1.lua: HTTPResponse: "Shelly1PMRetrieved"
2021-04-25 18:32:01.285 Status: dzVents: Info: Dallas-Temperatures: Reponse Shelly OK
2021-04-25 18:32:01.285 Status: dzVents: Info: Dallas-Temperatures: Puissance ->0.0
2021-04-25 18:32:01.285 Status: dzVents: Info: Dallas-Temperatures: Energie ->15615
2021-04-25 18:32:01.285 Status: dzVents: Info: Dallas-Temperatures: ------ Finished script-time_regul_Chambre1.lua
2021-04-25 18:32:01.285 Error: dzVents: Error: (3.0.2) Dallas-Temperatures: An error occurred when calling event handler script-time_regul_Chambre1
2021-04-25 18:32:01.285 Error: dzVents: Error: (3.0.2) Dallas-Temperatures: ...z/scripts/dzVents/scripts/script-time_regul_Chambre1.lua:50: attempt to index a nil value (field '?')

I am a newbie with json and Dzvents ..... thank in advance for your help (!)

Philippe
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Shelly, Dzvents, json and syntax

Post by waaren »

MarsaultP wrote: Sunday 25 April 2021 18:44 BUT, now, I am testing a other relay Shelly 1PM with a Dallas add-on, so it's possible to retrieve power, energie and Dallas temperature
I can read power and energie, but impossible to obtain the temperature in Dzvents !!!
Try with item.json.ext_temperature[0].tC
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
MarsaultP
Posts: 33
Joined: Wednesday 27 November 2019 13:31
Target OS: Linux
Domoticz version: 2024.7
Location: France
Contact:

Re: Shelly, Dzvents, json and syntax

Post by MarsaultP »

No success ... always the same error ...
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Shelly, Dzvents, json and syntax

Post by waaren »

MarsaultP wrote: Sunday 25 April 2021 19:16 No success ... always the same error ...
Indeed. Should be string

local room_temperature = item.json.ext_temperature['0'].tC -- 0 is here not a numeric index but the name of a subtable. Very confusing :)
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
MarsaultP
Posts: 33
Joined: Wednesday 27 November 2019 13:31
Target OS: Linux
Domoticz version: 2024.7
Location: France
Contact:

Re: Shelly, Dzvents, json and syntax

Post by MarsaultP »

Hin hin hin : you are very gooooood !

Yesss, that work well now !!!!

Thank you !
MarsaultP
Posts: 33
Joined: Wednesday 27 November 2019 13:31
Target OS: Linux
Domoticz version: 2024.7
Location: France
Contact:

Re: Shelly, Dzvents, json and syntax

Post by MarsaultP »

Finally, the Shelly 1PM is a cheaper wifi relay (Esp8266 inside ...), it's possible to connect a temperature sensor Dallas ds18b20 (this example). I use it as replacement of a builtin heater thermostat : remote control, better temperature loop control and record of power and energie.... tip top .. :D
So, the final code is (thanks to Waaren !) :

Code: Select all

return
--[[
Shelly controller with an independent temperature sensor and a virtual thermostat

Dependencies :
Dummy device -> Thermostat set point
Dummy device -> Switch On/Off
Device temperature -> reference room temperature (add-on Dallas on Shelly)

doc : 
https://shelly-api-docs.shelly.cloud/#shelly-family-overview   => communications au format json
https://www.domoticz.com/wiki/DzVents:_next_generation_Lua_scripting
https://www.domoticz.com/wiki/Plugins/Smart_Virtual_Thermostat.html
	  
Philippe Marsault 25/04/2021
]]-- 

{
	active = true,
	on = {
		timer = { 'every 1 minutes' },            -- every minute for testing, 10 minutes when active
		httpResponses = { 'Shelly1PMRetrieved' }  -- matches callback string below
	},  
		
	execute = function(dz, item)
	
		function round(x)
			return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
		end
		
		local IP_Shelly_Chb1	= '192.168.2.126'
		local Idx_sonde_T		= 125   -- reference room temperature
		local Idx_thermostat	= 123   -- Room thermostat
		local Idx_Chb1_selector	= 122   -- Switch for Off, manual or auto command
		local Idx_Chb1_Power	= 124   -- Power counter and energy
		local Idx_ther_OnOff	= 100   -- Global swith for this script, example : use for holidays
		local relay_Shelly_Chb1
		
		local ther_setpoint		= dz.devices(Idx_thermostat).setPoint    -- Read thermostat set point
		local selecteur_Chb1	= dz.devices(Idx_Chb1_selector).levelName -- Read Chb1 selector (Off, Manuel, Auto)

		if (item.isTimer) then
			dz.openURL({
				url = 'http://192.168.2.126/status',
				method = 'GET',
				callback = 'Shelly1PMRetrieved'
			})

		elseif (item.isHTTPResponse) then
			if (item.ok and item.isJSON) then
				dz.log("Reponse Shelly OK")
				local power = item.json.meters[1].power   -- Watt
				--dz.log ('Puissance ->'..power)
				local energie = item.json.meters[1].total/60.0  -- Watt*minute/60
				--dz.log ('Energie ->'..energie)
				dz.devices(Idx_Chb1_Power).updateElectricity(power, energie)	-- Update power & energie (Watt, Watt*heure)
				local room_temperature = item.json.ext_temperature["0"].tC
				--dz.log ('room_temperature ->'..room_temperature)
				dz.devices(Idx_sonde_T).updateTemperature(room_temperature)	-- Update temperature
				
				if (selecteur_Chb1 == 'Off') then
					ther_setpoint = dz.variables('T_Chb1_Off').value  -- temperature hors gel
					--dz.log ('Chambre 1 mode OFF - '..ther_setpoint..'°C')
				end
				if (selecteur_Chb1 == 'Manuel') then
					ther_setpoint = dz.variables('T_Chb1_manuel').value -- temperature marche manuel
					--dz.log ('Chambre 1 mode MANUEL - '..ther_setpoint..'°C')
				end
				if (selecteur_Chb1 == 'Auto') then
					--dz.log ('Chambre 1 mode AUTO - '..ther_setpoint..'°C')
				end
				-- traitement genetic de regulation
				if (room_temperature > ther_setpoint) then
					relay_Shelly_Chb1	= 'off' -- command to relay
					--dz.log ('Radiateur Chambre 1 etat Off')
				else
					relay_Shelly_Chb1	= 'on' -- command to relay to heat
					--dz.log ('Radiateur Chambre 1 etat On')
				end

				local command_shelly = 'http://'..IP_Shelly_Chb1..'/relay/0?turn='..relay_Shelly_Chb1
				dz.openURL({url = command_shelly})							-- send command to Shelly_SDB server				
				
			else
				-- oops
				dz.log('Error fetching Shelly data', domoticz.LOG_ERROR)
				dz.log(item.data, domoticz.LOG_ERROR)
			end
		end
	end
}
Philippe
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest