Page 2 of 3

Re: Toon thermostat combined Get and Set script

Posted: Saturday 23 February 2019 8:31
by hoeby
i am using a toon, but without a registration from enexis. therefor i can't add it to domoticz. but can this script work without having the toon connect to domoticz? by written the asked toon info to dummy devices?

Re: Toon thermostat combined Get and Set script

Posted: Sunday 03 March 2019 21:32
by jbr79
waaren wrote: Monday 18 February 2019 20:13
jbr79 wrote: Monday 18 February 2019 19:46 irrespective of setting local LAN access to true or not, the error message is:

Code: Select all

Error opening url: http://<IP>/happ_thermstat?action=getThermostatInfo
The IP number of your Toon need to be entered in the uservariable UV_ToonIP. Look at the first post of this topic.
It would help if you show the loglines produced by this script.
Thanks for the reply, but the <IP> is just for posting purposes. I already went ahead and changed the code so that my IP is in there instead of putting into a domoticz var.

Rather than changing the script though, I guess the issue is that I need a hacked Toon for it to work...

Re: Toon thermostat combined Get and Set script

Posted: Tuesday 09 April 2019 12:33
by imdos
Hi everybody,

I liked the script and made an addition to be aware when my Toon is heating. I want to smart control my thermostat when I'm working from home. Since sharing is caring; hereby the updated script.

Code: Select all

--[[

    Sync Domoticz sensors / switches with Toon in case the value is changed on the physical device.
    Updates
        Thermostat Sensor
        Temperature Sensor
        Scenes switch based on program set on Toon
        (Auto)program switch to value set on Toon
        Program information text to value set on Toon

Van: https://www.domoticz.com/forum/viewtopic.php?f=59&t=26662
    ]] --

local toonResponse  = "toonResponse"
local ResponseOK    = "OK_toon_Response"
local scriptVersion = "version 0.2"
return {
                on  =   { timer         = { "every minute"      },
                          devices       = { "Toon Thermostaat","Toon Scenes"  },
                          httpResponses = { toonResponse , ResponseOK      }},

           logging  =   {
                            level       =       domoticz.LOG_INFO,
                            -- level       =       domoticz.LOG_DEBUG,
                            marker      =       scriptVersion .. " Toon"
                        },

               data =   {
                            lastActive    = { initial = 0     },
                            isActive      = { initial = false },
                            blockSetPoint = { initial = false },   -- Bug in TimedCommands (silent() does not work in updateSetPoint
                        },

    execute = function(dz, item)
        local now = os.time(os.date('*t'))                  -- seconds since 1/1/1970 00:00:01

        local function logWrite(str,level)
            dz.log(tostring(str),level or dz.LOG_DEBUG)
        end

        local function sendURL(url,callback)
            local toonIP = dz.variables("UV_ToonIP").value
            local url    = "http://" .. toonIP .. url
            dz.openURL({
                            url = url,
                            method = "GET",
                            callback = callback
                      })
        end

        local function setSetPoint(device,setPoint) -- update setPoint
            if device.setPoint ~= setPoint then
                logWrite("Updating thermostat sensor to new set point: " .. setPoint )
                device.updateSetPoint(setPoint)
            else
                dz.data.blockSetPoint = false
            end
        end

        local function setSelector(device,state,str) -- update selector
            if device.level ~= state and device.lastUpdate.secondsAgo > 59 then
                logWrite("Updating the " .. device.name .. " level to " .. str .. " (" .. state ..  ")")
                device.switchSelector(state).silent()
            end
        end

        local function setTemperature(device,temperature) -- Update temperature sensor
            if device.temperature ~= temperature then
                logWrite("Updating the temperature sensor to: " .. temperature)
                device.updateTemperature(temperature).silent()
            end
        end

        local function setText(device,text)    -- Update text sensor
            if device.text ~= text then
                logWrite("Updating " .. device.name .. " to: " .. text)
                device.updateText(text)
            end
        end

        local function setSetPointInfo(device,nextTime,setPoint)
            if nextTime == 0 or setPoint == 0 then
                newText = "Op " .. setPoint .. "▒"
            else
                newText = "Om " ..os.date("%H:%M", nextTime).. " naar " .. setPoint .. "▒"
            end
            setText(device,newText)
        end

        local function setSceneState(device,state)
            local states       = { 50,40,30,20,10}  -- Manual, Comfort, Home, Sleep , Away
            local stateStrings = { "Manual", "Comfort", "Home", "Sleep" , "Away"}
            local newState     = states[state + 2]
            local stateString  = stateStrings[state + 2]
            setSelector(device,newState,stateString)
        end

        local function setProgramState(device,state)
            local states       = { 10,20,30 }  -- No, Yes, Temporary
            local stateStrings = { "No", "Yes", "Temporary" }
            local newState     = states[state + 1]
            local stateString  = stateStrings[state + 1]
            setSelector(device,newState,stateString)
        end

        local function setBurnerState(device,state)
            local states       = { 0,10,20 }  -- Off, CV, WW
            local stateStrings = { "Off", "CV", "WW" }
            local newState     = states[state + 1]
            local stateString  = stateStrings[state + 1]
            setSelector(device,newState,stateString)
        end

        local function updateDevices(rt)
            local toonThermostat            = dz.devices(dz.variables("UV_ToonThermostatSensorName").value)           -- Sensor showing current setpoint
            local toonTemperature           = dz.devices(dz.variables("UV_ToonTemperatureSensorName").value)          -- Sensor showing current room temperature
            local toonScenes                = dz.devices(dz.variables("UV_ToonScenesSensorName").value)               -- Sensor showing current program
            local toonAutoProgram           = dz.devices(dz.variables("UV_ToonAutoProgramSensorName").value)          -- Sensor showing current auto program status
            local toonProgramInformation    = dz.devices(dz.variables("UV_ToonProgramInformationSensorName").value)   -- Sensor showing displaying program information status
            local toonBurner                = dz.devices(dz.variables("UV_ToonBurnerInfo").value)                                 -- Sensor showing current CV information status
            -- local toonModulation

            setSetPoint     (toonThermostat,          dz.utils.round(rt.currentSetpoint / 100,1          ))
            setTemperature  (toonTemperature,         dz.utils.round(rt.currentTemp / 100,1              ))
            setSceneState   (toonScenes,              rt.activeState                                      )  -- "activeState":"-1" ==> 50
            setProgramState (toonAutoProgram,         rt.programState                                     )  -- "programState":"0" ==> 10
                        setBurnerState  (toonBurner,  rt.burnerInfo                                       )  -- "burnerInfo":"0" ==> 0
            setText         (toonProgramInformation,  dz.utils.round(rt.nextTime,rt.nextSetpoint / 100,1 ))
        end

        local function procesToonResponse()
            logWrite(tostring(item.data))
            return dz.utils.fromJSON(item.data)
        end

        local function sendSetPoint(newSetPoint)

            logWrite("In function sendSetPoint; " .. item.name .. " wants to set setPoint to " .. newSetPoint)
            local calculatedSetPoint = newSetPoint * 100
            local urlString = "/happ_thermstat?action=setSetpoint&Setpoint=" .. calculatedSetPoint
            if not dz.data.blockSetPoint then
                sendURL(urlString, ResponseOK )
                logWrite("Toon setPoint send using " .. urlString)
            else
                logWrite("Toon setPoint not send ; unblocking now ")
                dz.data.blockSetPoint = false
            end
        end

        local function sendScene()
            local newstate
            logWrite("In function sendScene; " .. item.name .. "; level " .. item.level .. " ==>> " .. item.levelName)

            if item.level ==  0 then  -- Off
                sendSetPoint(60)
                return
            end

            if      item.level == 10 then newState = 3       -- Away
            elseif  item.level == 20 then newState = 2       -- Sleep
            elseif  item.level == 30 then newState = 1       -- Home
            elseif  item.level == 40 then newState = 0       -- Comfort
            else                          newState = -1      -- Invalid
            end

            local urlString = "/happ_thermstat?action=changeSchemeState&state=2&temperatureState=" .. newState
            sendURL(urlString, ResponseOK )
            logWrite("Toon SchemeState send using " .. urlString)
        end

        local function getInfo()
            sendURL("/happ_thermstat?action=getThermostatInfo",toonResponse)
        end

        -- Check for conflicts between timer and set Toon
        local function setActive(state)
            if state then
                logWrite("Triggered by device. Setting active")
                dz.data.isActive    = true
                dz.data.lastActive  = now
            else
                dz.data.isActive    = false
                logWrite("Answer from Toon. Unset active")
            end
        end

        local function isFree()
            return (( dz.data.lastActive + 90 ) < now ) or ( not dz.data.isActive )
        end

        local function writeStatus(origin)
            logWrite(origin .. "isFree:               " .. tostring(isFree()))
            logWrite(origin .. "lastActive:           " .. os.date("%X",dz.data.lastActive))
            logWrite(origin .. "blockSetPoint:        " .. tostring(dz.data.blockSetPoint))
        end

        -- main program
        writeStatus("-- start -- ")
        if item.isDevice then                               -- triggered by selector or setPoint
            if item.name == "Toon Scenes" then
                sendScene()
                setActive(true)
            else
                sendSetPoint(item.setPoint)
                setActive(true)
            end
        elseif item.isTimer and isFree() then                    -- triggered by timer
                dz.data.blockSetPoint = true
                getInfo()
        elseif item.isHTTPResponse then                              -- Triggered by Toon response
            if item.trigger == toonResponse then                 -- return from getInfo()
                if item.ok and isFree() then                     -- statusCode == 2xx
                    updateDevices(procesToonResponse())
                elseif isFree() then
                    logWrite("Toon did not return valid data. Please check what went wrong. Error code: " .. item.statusCode or 999  ,dz.LOG_ERROR)
                    logWrite("Invalid data: " .. tostring(item.data))
                else
                    logWrite("Toon is busy dealing with sendScene or sendSetPoint")
                end
            else
                logWrite("returned from sendScene or sendSetPoint: " .. tostring(item.data))
                setActive(false)
            end
        else
            logWrite("This should never happen")
        end
        writeStatus("-- end -- ")
    end
}
P.S. I couldn't properly diff it but only approximately 10 lines have changed.
P.S.2 One should add the required uservariable and selector switch as mentioned here in the manual with "ToonBranderInfo"
P.S.3 Toon only ever shows if it is heating or not and doesn't mention the usage of WW (in Dutch: warmwater) since it's not controlled through OTGW mode but pure simple on/off mode I geuss.

Re: Toon thermostat combined Get and Set script

Posted: Wednesday 10 April 2019 15:47
by jjnj
Does this work with the rooted Toon?

Verstuurd vanaf mijn LM-V405 met Tapatalk


Re: Toon thermostat combined Get and Set script

Posted: Saturday 20 April 2019 14:48
by imdos
Yes; @jjnj, only with a rooted Toon.

Re: Toon thermostat combined Get and Set script

Posted: Saturday 11 May 2019 20:17
by jonathan12
Nice script. After the latest domoticz update the original script did crash domoticz, so I had to disable it.
Now I will use your script. But when i use it I got this error:

Error: EventSystem: in Toon Thermostaat: [string "--[[
..."]:22: attempt to index global 'domoticz' (a nil value)

What does it mean?

Re: Toon thermostat combined Get and Set script

Posted: Sunday 12 May 2019 10:42
by waaren
@jonathan12
The script is to be set as a dzVents script. From what I see it looks like you tried to save it as a Lua script.

When not yet familiar with dzVents please start with reading Get started Before implementing. Special attention please for
"In Domoticz go to Setup > Settings > Other and in the section EventSystem make sure the checkbox 'dzVents disabled' is not checked. Also make sure that in the Security section in the settings you allow 127.0.0.1 to not need a password. dzVents uses that port to send certain commands to Domoticz. Finally make sure you have set your current location in Setup > Settings > System > Location, otherwise there is no way to determine nighttime/daytime state."

Re: Toon thermostat combined Get and Set script

Posted: Sunday 12 May 2019 12:22
by jonathan12
Hi Waaren,

Thanks for your answer! Now it is working.
Thanks a lot! :D :D :D

Re: Toon thermostat combined Get and Set script

Posted: Tuesday 20 August 2019 12:28
by annesdomotic
Hi, I'm new here, and for a while playing around with the above script. (versie imdos)
almost everything works but I get one error in my log namely:Error: EventSystem: in toon script: [string "commandArray = {}..."]:58: attempt to perform arithmetic on field '?' (a nil value)

i where to look for the error? the only thing my stand in that line is that there is a difference in Setpoint and SetPoint hear that so or is there a mistake somewhere?

thanks in advance

Re: Toon thermostat combined Get and Set script

Posted: Tuesday 20 August 2019 22:49
by waaren
annesdomotic wrote: Tuesday 20 August 2019 12:28 Hi, I'm new here, and for a while playing around with the above script. (versie imdos)
Do you mean changing something in the script with "playing around" ?
almost everything works but I get one error in my log namely:Error: EventSystem: in toon script: [string "commandArray = {}..."]:58: attempt to perform arithmetic on field '?' (a nil value)
There is no such line in the original script or in the version of @imdos. Because the script is in dzVents lua no commandarray manipulation is needed on the script-level.
So if you changed anything in the script please post it and also the complete loglines for this script.

Re: Toon thermostat combined Get and Set script

Posted: Wednesday 21 August 2019 8:59
by annesdomotic
good morning,

by playing I mean trying. Add xiaomi sensors via zigbee etc. and that went well. I only found 1 error in the log and that was in line 58:

Code: Select all

if currentBoilerSetPoint ~= nil then 
			-- Update the temperature of boiler
			if otherdevices_svalues[ToonBoilerTempSetpoint]*100 ~= currentBoilerSetPoint*100 then 
				print('Updating the boiler temperature to new value: ' ..currentBoilerSetPoint)
				commandArray[3] = {['UpdateDevice'] = string.format('%s|0|%s', otherdevices_idx[ToonBoilerTempSetpoint], currentBoilerSetPoint)}
			end
		end
what struck me in this line is that it says Setpoint and later SetPoint. I've changed both to Setpoint and now my domoticz has crashed. domoticz offline, I can approach m via putty but after restart the domoticz stays offline. new problem :-(

Re: Toon thermostat combined Get and Set script

Posted: Wednesday 21 August 2019 9:23
by annesdomotic
sudo /etc/init.d/domoticz.sh restart
my domoticz is online ;-)

Re: Toon thermostat combined Get and Set script

Posted: Wednesday 21 August 2019 10:43
by waaren
annesdomotic wrote: Wednesday 21 August 2019 8:59 by playing I mean trying. Add xiaomi sensors via zigbee etc. and that went well. I only found 1 error in the log and that was in line 58:
I cannot be sure because you only post part of your script but from what I see here it looks like you are playing with another script. This topic is about the dzVents version of the [hacked] Toon control combined in one script.

It is not a good idea to combine classic domoticz Lua with dzVents as the both change the commandArray object (used for communicating back to domoticz main program) different.

Re: Toon thermostat combined Get and Set script

Posted: Wednesday 21 August 2019 10:56
by annesdomotic
okay thanks for the tip not to combine script. it's idd another script i found out. sorry for the confusion. now i first have to find a solution for my domoticz, he is offline again. seems to be a problem with the new version: 4.10717

Re: Toon thermostat combined Get and Set script

Posted: Wednesday 28 August 2019 13:47
by HansieNL
A few questions... if you allow me:
1. Should the Toon Auto Program switch set the status on the Toon Thermostat itself or does it only read from the Toon Thermostat?
2. If I set temperature by Toon Scene the setpoint changes correcly. After another minute the scene jumps to manual state. Is this the way it should work?
3. Toon program Information shows only a number. Is this correct?

Re: Toon thermostat combined Get and Set script

Posted: Wednesday 28 August 2019 18:28
by waaren
HansieNL wrote: Wednesday 28 August 2019 13:47 A few questions... if you allow me:
1. Should the Toon Auto Program switch set the status on the Toon Thermostat itself or does it only read from the Toon Thermostat?
2. If I set temperature by Toon Scene the setpoint changes correcly. After another minute the scene jumps to manual state. Is this the way it should work?
3. Toon program Information shows only a number. Is this correct?
1. It only reads
2. Don't remember the details of this but do think Toon comes back with this state and the script follows.
3. Don't know this; As i do not own a Toon myself I developed this script together with @johan1974 who did all the testing and provided the required feedback. Best if he (or any other user of the script) could step in and answer this question and confirm or correct my answer on 2. and 3.

If you encounter an error that prevents the proper working of this script, I could off course try to work with you to get the script working error free again.

Re: Toon thermostat combined Get and Set script

Posted: Thursday 29 August 2019 2:27
by HansieNL
waaren wrote: Wednesday 28 August 2019 18:28
Spoiler: show
HansieNL wrote: Wednesday 28 August 2019 13:47 A few questions... if you allow me:
1. Should the Toon Auto Program switch set the status on the Toon Thermostat itself or does it only read from the Toon Thermostat?
2. If I set temperature by Toon Scene the setpoint changes correcly. After another minute the scene jumps to manual state. Is this the way it should work?
3. Toon program Information shows only a number. Is this correct?
1. It only reads
2. Don't remember the details of this but do think Toon comes back with this state and the script follows.
3. Don't know this; As i do not own a Toon myself I developed this script together with @johan1974 who did all the testing and provided the required feedback. Best if he (or any other user of the script) could step in and answer this question and confirm or correct my answer on 2. and 3.

If you encounter an error that prevents the proper working of this script, I could off course try to work with you to get the script working error free again.
I had a non rooted Toon and when I selected a scene the scene stayed selected till setpoint or scene was manually changed. How it’s working now is not logical to me. Don’t now why scene changes to manual after 1 minute. Would be great if you could help to solve this.

Re: Toon thermostat combined Get and Set script

Posted: Thursday 29 August 2019 10:37
by waaren
HansieNL wrote: Thursday 29 August 2019 2:27 I had a non rooted Toon and when I selected a scene the scene stayed selected till setpoint or scene was manually changed. How it’s working now is not logical to me. Don’t now why scene changes to manual after 1 minute. Would be great if you could help to solve this.
Assuming you use this script on a rooted Toon (it will only work on a rooted one)
Can you switch on debug in your script and the dzVents loglevel to "Errors + minimal execution info + generic info" in [settings] [other]
and send the loglines from the beginning to the end of where the script is triggered (multiple times) and the rooted Toon reacts with the steps you don't understand and send the loglines to me as PM ?
Also mark the lines where you see the script behaving different then expected.
Thx

Re: Toon thermostat combined Get and Set script

Posted: Thursday 29 August 2019 19:24
by madpatrick
HansieNL wrote: Wednesday 28 August 2019 13:47 A few questions... if you allow me:
1. Should the Toon Auto Program switch set the status on the Toon Thermostat itself or does it only read from the Toon Thermostat?
2. If I set temperature by Toon Scene the setpoint changes correcly. After another minute the scene jumps to manual state. Is this the way it should work?
3. Toon program Information shows only a number. Is this correct?
1. Not using Auto Program. Setting the scene by Domoticz on certain times or actions
2. This is correct. There is link between a temperature setpoint and Scene. Other way around of course is working
3. The number should be the temperature. You can add text your self
For example:

Code: Select all

-- Updates the toon program information text box
      local currentNextTime = jsonThermostatInfo.nextTime
      local currentNextSetPoint = tonumber(jsonThermostatInfo.nextSetpoint) / 100
        
      if currentNextTime == 0 or currentNextSetPoint == 0 then
          ToonProgramInformationSensorValue = 'Op ' ..currentSetpoint.. '°'
      else
          ToonProgramInformationSensorValue = 'Om ' ..os.date('%H:%M', currentNextTime).. ' op ' ..currentNextSetPoint.. '°'
      end

Re: Toon thermostat combined Get and Set script

Posted: Saturday 31 August 2019 12:59
by HansieNL
Thanks @madpatrick and @waaren for your help.
I use 2 scripts. Don't know how to make it using just one script. But it works for me ok. I'm using only 3 devices: Thermostat, Scenes and Temperature. I don't use scene states, so decided to use setpoint temperature to let switch the scenes.
toon_setpoint .lua

Code: Select all

return {
	on = {
		devices = {
			'Thermostaat'
				  }
		 },

	execute = function(domoticz, device)
		domoticz.openURL(string.format('http://192.168.2.17/happ_thermstat?action=setSetpoint&Setpoint=%s', device.setPoint*100))
		domoticz.log('Setting Toon setpoint to '.. device.setPoint)

	end
}
toon_script.lua

Code: Select all

return {
	logging = {
		level = domoticz.LOG_FORCE, -- Select one of LOG_INFO, LOG_DEBUG, LOG_ERROR, LOG_FORCE to override system log level
		marker = "(Toon) "
			  },
	on = {
		timer = {
			'every minute'
				}
		 },

	execute = function(domoticz)
		local ToonThermostat	= 'Thermostaat' -- Sensor showing current setpoint
		local ToonScenes		= 'Toons' -- Sensor showing current program
		local ToonTemperature	= 'Binnen' -- Sensor showing current room temperature
		local ToonIP			= '192.168.2.17'

-- Handle json
		local json = assert(loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()  -- For Linux

		local handle = assert(io.popen(string.format('curl http://%s/happ_thermstat?action=getThermostatInfo', ToonIP)))
		local ThermostatInfo = handle:read('*all')
		handle:close()

		local jsonThermostatInfo = json:decode(ThermostatInfo)

		if jsonThermostatInfo == nil then
			return
		end

-- Update the current temperature setpoint
		local currentSetpoint = tonumber(jsonThermostatInfo.currentSetpoint) / 100
		local currentTemperature = tonumber(jsonThermostatInfo.currentTemp) / 100
			  currentTemperature = tonumber(string.format("%.1f", currentTemperature))  -- 1 decimaal is voldoende [PdB]

-- Update the current scene
		local currentActiveTemp = tonumber(jsonThermostatInfo.currentSetpoint) / 100
		    if currentActiveTemp == 21 then currentActiveState = 40 -- Comfort
		elseif currentActiveTemp == 19 then currentActiveState = 30 -- Home
		elseif currentActiveTemp == 15 then currentActiveState = 20 -- Sleep
		elseif currentActiveTemp == 12 then currentActiveState = 10 -- Away
		else	currentActiveState = 50 -- Manual
		end        

-- Update the thermostat sensor to current setpoint
		if domoticz.devices(ToonThermostat).setPoint*100 ~= currentSetpoint*100 then
			domoticz.log('Updating thermostat sensor to new set point: ' ..currentSetpoint)
			domoticz.devices(ToonThermostat).updateSetPoint(currentSetpoint).silent()
		end

-- Update the temperature sensor to current room temperature
		if domoticz.utils.round(domoticz.devices(ToonTemperature).temperature, 1) ~= domoticz.utils.round(currentTemperature, 1) then 
			domoticz.log('Updating the temperature sensor to new value: ' ..currentTemperature)
			domoticz.devices(ToonTemperature).updateTemperature(currentTemperature)
		end

-- Update the toon scene selector sensor to current program state
		if domoticz.devices(ToonScenes).level ~= currentActiveState then  -- Update toon selector if it has changed
			domoticz.log('Updating Toon Scenes selector to: '..currentActiveState)
			domoticz.devices(ToonScenes).switchSelector(currentActiveState).silent()
		end

	end
}