Page 2 of 3

Re: Heating finally automated using HomeEasy HE105

Posted: Tuesday 10 March 2015 20:47
by thebeetleuk
Latest Version of the code updated : 10/03/2015 V0.4 <- Latest version updated to support new temperature set point switch. this removes the need for lots of the code and additional switches. Enjoy :)

Re: Heating finally automated using HomeEasy HE105

Posted: Sunday 22 March 2015 17:35
by Tom
Nice one.

while reading this I noticed that the HE105 looked exactly like the Boiler switch that I have in my house which is branded as a 'Horstmann HRFS1' - Like this one http://www.screwfix.com/p/horstmann-hrf ... stat/93829.

It turns out that it is the same receiver/switch unit as the HE105 and that I can also switch it with rfxmgr and have just managed to add a switch in my domoticz to control it :)

I have had this thermostat for years (using the seperate LCD display to control it), and never realised that the 'thermostat' tab was there in rfxmgr or that I could control it! Now I can start playing with it!

Re: Heating finally automated using HomeEasy HE105

Posted: Thursday 07 May 2015 17:34
by CaptainBirdseye
I've just implemented this script and have been having problems with the heating switching on and off too frequently. Even increasing the heatercommanddelay you then have to balance introducing artificial latency into the system so it still switches on when you want it to but doesn't switch on/off too frequently. With an aging oil fired boiler I was keen to avoid too frequent switching but to also optimise runtime to save oil consumption. As such I've made some modifications to the excellent work done by thebeetleuk. This version samples the three thermostats I have scattered around the house and takes an average but more importantly adds some hysteresis to the switching process. It takes the set point and then establishes a range either side, the lower point of which is the trigger to switch the heating on and the top point to switch the heating off. If the measured temperature is anywhere between the top and bottom it will leave the system as is (we assume that the system is either running to warm the house up towards the top threshold or cooling down towards the lower threshold). I've found that 0.5 degrees either side of the set point isn't noticeable from a comfort perspective, boiler firing times are in the 20 - 30 min range which allows the system to heat all radiators evenly around the house and because they aren't being governed by the heatercommanddelay value I can drop this value down to a couple of minutes meaning the script reacts promptly to valid changes in temperature. Hope all that makes sense. Updated to v0.4.1

Code: Select all

     -----------------------------------------------------------------------------------------------
    -- Heating Control
    -- Version 0.4.1
    -- Author - Martin Rourke

    -- This library is free software: you can redistribute it and/or modify it under the terms of
    -- the GNU Lesser General Public License as published by the Free Software Foundation, either
    -- version 3 of the License, or (at your option) any later version. This library is distributed
    -- in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
    -- Public License for more details. You should have received a copy of the GNU Lesser General
    -- Public License along with this library.  If not, see <http://www.gnu.org/licenses/>.
    -----------------------------------------------------------------------------------------------

    -----------------------------------------------------------------------------------------------
    -- Setup
    -----------------------------------------------------------------------------------------------
    -- To use this script you need to have a few devices already setup in Domoticz
    -- 1. A physical switch to operate (On/Off Switch)
    -- 2. A physical temperature sensor (Temperature)
    -- 3. A virtual switch to tun on and off the heating (On/Off Switch)
    -- 4. A virtual switch to set the target temperature (Temperature)
    -- 5. Define a User Variable as 'Debug', Integer and set to 1 or 0 to show/hide entries in the log

    -----------------------------------------------------------------------------------------------
    -- 1. A physical switch to operate (On/Off Switch)
    -----------------------------------------------------------------------------------------------
    local physicalheater = 'Heating House (Boiler)'

    -----------------------------------------------------------------------------------------------
    -- 2. A physical temperature sensor (Temperature)
    -----------------------------------------------------------------------------------------------
    local currenttemperature = 'Lounge temp'
    local currenttemperature1 = 'Lounge temp'
    local currenttemperature2 = 'Bedroom2'
    local currenttemperature3 = 'Bedroom1'

    -----------------------------------------------------------------------------------------------
    -- 3. A virtual switch to tun on and off the heating (On/Off Switch)
    -----------------------------------------------------------------------------------------------
    local virtualheater = 'Heating House'

    -----------------------------------------------------------------------------------------------
    -- 4. A virtual switch to set the target temperature (Temperature)
    -- Assumes you are using a dummy switch "Thermostat Setpoint" to move temperature up and down
    -----------------------------------------------------------------------------------------------
    local targettemperature = 'Thermostat House'

    -----------------------------------------------------------------------------------------------
    -- 5. UserVariable - Set debug to 1 for testing. 0 for live running.
    -----------------------------------------------------------------------------------------------

    -----------------------------------------------------------------------------------------------
    -- OPTIONS
    -----------------------------------------------------------------------------------------------

    -----------------------------------------------------------------------------------------------
    -- After this time the heating will automatically turn off as a temperature was not detected
    -- from the temperature sensor. this helps protect against the heating being left on all the
    -- time if the signal is lost.
    -----------------------------------------------------------------------------------------------
    local lostsignaltime = 3600 -- 60 minutes

    -----------------------------------------------------------------------------------------------
    -- Helps protect against multiple quick changes to the physical switch
    -----------------------------------------------------------------------------------------------
    local heatercommanddelay = 120 -- 2 minutes

    -----------------------------------------------------------------------------------------------
    -- Repeats the On or Off command after a set time for devices that don't have a handshake
    -- Should always be bigger than heatercommanddelay
    -----------------------------------------------------------------------------------------------
    local heaterrepeatdelay = 300 -- 5 minutes

    -----------------------------------------------------------------------------------------------
    -- Defines the temperature range above and below the set point where the heating will left in
    -- the current state to avoid frequent switching 
    -----------------------------------------------------------------------------------------------
    local temprange = 0.5 -- 0.5 degrees

    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -- NOTHING SHOULD NEED TO CHANGE BELOW THIS LINE
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------

    local thermostatchgnagedetected = 0

    commandArray = {}
    function debuglog (s)
       if uservariables["Debug"] == 1 then print("DEBUG - THERMOSTAT " .. physicalheater .. s) end
       return true
    end

    function timedifference (s)
      year = string.sub(s, 1, 4)
      month = string.sub(s, 6, 7)
      day = string.sub(s, 9, 10)
      hour = string.sub(s, 12, 13)
      minutes = string.sub(s, 15, 16)
      seconds = string.sub(s, 18, 19)
      t1 = os.time()
      t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
      difference = os.difftime (t1, t2)
      return difference
    end

    function round(num, idp)
      local mult = 10^(idp or 0)
      return math.floor(num * mult + 0.5) / mult
    end

    -----------------------------------------------------------------------------------------------
    -- Controls the heating based on the target and current temperatures
    -----------------------------------------------------------------------------------------------

     -- Is the heating scheduled to be on?
     if (otherdevices[virtualheater]=='On') then
     debuglog('Heating - Heating Is Scheduled To Be On: ' .. virtualheater )

       -- what is the target temperature and the top/bottom range?
       target = round(tonumber(otherdevices_svalues[targettemperature]), 1)
       targethigh = (target + tonumber(temprange))
       targetlow = (target - tonumber(temprange))

       -- test to see if we can still see the thermostat. If not force the heating off          
       if ( timedifference(otherdevices_lastupdate[currenttemperature]) > lostsignaltime ) then
          -- this section to handle loss of signal with thermostat and turns off boiler
          debuglog('Heating - WARNING: Last seen temperature sensor: '.. currenttemperature ..' ' .. tostring(otherdevices_lastupdate[currenttemperature]))
          debuglog('Heating - WARNING: Signal Lost with temperature sensor for over '.. lostsignaltime ..' seconds: '.. currenttemperature)
          debuglog('Heating - WARNING: forcing Heating OFF : '.. physicalheater)
             
          if( timedifference(otherdevices_lastupdate[physicalheater]) > heaterrepeatdelay) then -- checks to see if the command needs to be repeated
            if (otherdevices[physicalheater]=='Off') then
                debuglog('Heating - WARNING - Turning Physical Heater On: '.. physicalheater)
             else
                debuglog('Heating - WARNING - Turning Physical Heater On (Repeat Command): '.. physicalheater)
             end
             commandArray[physicalheater] = 'On'
          else
             debuglog('Heating - INFO: Not enough time has passed before issuing repeat command to switch: Only '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heaterrepeatdelay .. ' seconds')
          end
         -- end of section for turning off boiler if no comms with thermostat
       else
          -- this section runs only if we have received temp info from the stat
          debuglog('Heating - Last seen temperature sensor: '.. currenttemperature ..' ' .. tostring(otherdevices_lastupdate[currenttemperature]))
          
          -- What is the current temperature? We sample three stats and take an average and round to one DP
          -- As some temperature devices also return other values as humidity this assumes the first value is the temperature in all cases
          current1 = tonumber(string.gmatch(otherdevices_svalues[currenttemperature1], '([^;]+)')(1))
          current2 = tonumber(string.gmatch(otherdevices_svalues[currenttemperature2], '([^;]+)')(1))
          current3 = tonumber(string.gmatch(otherdevices_svalues[currenttemperature3], '([^;]+)')(1))
	  current = round(((current1 + current2 + current3) / 3), 1)
 
	  debuglog('Heating - Lounge temperature: ' .. tostring(current1))
	  debuglog('Heating - Bedroom2 temperature: ' .. tostring(current2))
	  debuglog('Heating - Bedroom1 temperature: ' .. tostring(current3))
	  debuglog('Heating - Average temperature: ' .. tostring(current))
          debuglog('Heating - Target: ' .. tostring(target) .. ' Current: ' .. tostring(current))
          debuglog('Heating - TargetHigh: ' .. tostring(targethigh) .. ' TargetLow: ' .. tostring(targetlow))

          if( timedifference(otherdevices_lastupdate[physicalheater]) > heatercommanddelay ) then -- checks to see if the heater has been turned off recently
             debuglog('Heating - Enough time has passed since last change to switch: '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heatercommanddelay .. ' seconds')

             if (current < targetlow) then -- test if current temp is below target low threshold - need to turn heater on	     
                debuglog('Heating - Current temp is below TargetLow. Turning Physical Heater On: '.. physicalheater)
                if( timedifference(otherdevices_lastupdate[physicalheater]) > heaterrepeatdelay or devicechanged[remoteup] or devicechanged[remotedown] or devicechanged[virtualheater]) then -- checks to see if the command needs to be repeated
                   if (otherdevices[physicalheater]=='Off') then
                      debuglog('Heating - Current below TargetLow. Turning Physical Heater On: '.. physicalheater)
                   else
                      debuglog('Heating - Current below TargetLow. Turning Physical Heater On (Repeat Command): '.. physicalheater)
                   end
                   commandArray[physicalheater] = 'On'
                else
                   debuglog('Heating - INFO: Not enough time has passed before issuing repeat command to switch: Only '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heaterrepeatdelay .. ' seconds')
                end
             else
		if (current > targethigh) then -- test if current temp is above top threshold - need to turn heater off
                  debuglog('Heating - Current temp is above Targethigh. Turning Physical Heater Off: '.. physicalheater)
                  if( timedifference(otherdevices_lastupdate[physicalheater]) > heaterrepeatdelay or devicechanged[remoteup] or devicechanged[remotedown] or devicechanged[virtualheater]) then -- checks to see if the command needs to be repeated
                     if (otherdevices[physicalheater]=='On') then
                        debuglog('Heating - Current above TargetHigh. Turning Physical Heater Off: '.. physicalheater)
                     else
                        debuglog('Heating - Current above TargetHigh. Turning Physical Heater Off (Repeat Command): '.. physicalheater)
                     end
                     commandArray[physicalheater] = 'Off'
                  else
                     debuglog('Heating - INFO: Not enough time has passed before issuing repeat command to switch: Only '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heaterrepeatdelay .. ' seconds')
                  end
                else
                   debuglog('Heating - Current temp between TargetHigh and Targetlow. Leaving boiler in current state') -- leave boiler either on as house warms up or off as house cools down
                end
              end
 

          else
             debuglog('Heating - INFO: Not enough time has passed before issuing command to switch: Only '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heatercommanddelay .. ' seconds')
          end
       end



     else
        debuglog('Heating - Turning Heating Off As Scheduled To Be Off')   
        if( timedifference(otherdevices_lastupdate[physicalheater]) > heatercommanddelay ) then
           debuglog('Heating - Enough time has passed before issuing command to switch: '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heatercommanddelay .. ' seconds')
              if( timedifference(otherdevices_lastupdate[physicalheater]) > heaterrepeatdelay or devicechanged[remoteup] or devicechanged[remotedown] or devicechanged[virtualheater]) then -- checks to see if the command needs to be repeated
                 if (otherdevices[physicalheater]=='On') then
                    debuglog('Heating - Turning Physical Heater Off: '.. physicalheater)
                 else
                    debuglog('Heating - Turning Physical Heater Off (Repeat Command): '.. physicalheater)
                 end
                 commandArray[physicalheater] = 'Off'
              else
                 debuglog('Heating - INFO: Not enough time has passed before issuing repeat command to switch: Only '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heaterrepeatdelay .. ' seconds')
              end   
        else
           debuglog('Heating - INFO: Not enough time has passed before issuing command to switch: Only '.. timedifference(otherdevices_lastupdate[physicalheater]) .. ' seconds out of ' .. heatercommanddelay .. ' seconds')
        end
     end

Re: Heating finally automated using HomeEasy HE105

Posted: Friday 23 October 2015 21:20
by mikejclark
Evening, could someone please explain how to enable debug for this script?
The instructions say to add a user variable but I do not know what this looks like, or where in the code to add it.
Is it simply:

Code: Select all

-----------------------------------------------------------------------------------------------
-- 5. UserVariable - Set debug to 1 for testing. 0 for live running.
-----------------------------------------------------------------------------------------------
debug = 1
And once enabled where is the debug log located?
Many thanks in advance

Re: Heating finally automated using HomeEasy HE105

Posted: Saturday 24 October 2015 22:37
by thebeetleuk
Hi Mike,

the function calls the "Debug" variable which isnt sent within the lua script itself. Its set within domoticz. From the Web interface go to Setup->More Options->User Variables. From here just create a new entry called Debug as an integer and set it to 1 to tun on the debugging.

Code: Select all

function debuglog (s)
       if uservariables["Debug"] == 1 then print("DEBUG - THERMOSTAT " .. physicalheater .. s) end
       return true
end
Hope this helps!!

Re: Heating finally automated using HomeEasy HE105

Posted: Sunday 25 October 2015 19:16
by mikejclark
thebeetleuk wrote:Hi Mike,

the function calls the "Debug" variable which isnt sent within the lua script itself. Its set within domoticz. From the Web interface go to Setup->More Options->User Variables. From here just create a new entry called Debug as an integer and set it to 1 to tun on the debugging.

Code: Select all

function debuglog (s)
       if uservariables["Debug"] == 1 then print("DEBUG - THERMOSTAT " .. physicalheater .. s) end
       return true
end
Hope this helps!!
It does! That was the missing piece of the puzzle. Thank you for your help and script.

Re: Heating finally automated using HomeEasy HE105

Posted: Monday 26 October 2015 21:40
by thebeetleuk
Np. I'll update the notes at some point to make it clearer.

Re: Heating finally automated using HomeEasy HE105

Posted: Saturday 07 November 2015 21:31
by Backbone
Hello Martin,

I used the 4.0 script and at first it could not understand why the status was not chaging.
Then I found out in the sript there is a typo which confused me :-)
local heaterrepeatdelay = 600 -- 1 minute where 600 secs is certainly not 1 minute ;-)
So I changed the 600 to 60 and voila we have 1 minute.

My other question is how you get the yellow marked dropdown menu in the top right hand corner that says " Room ; Heating House " ?
I assume you have the dashboard devided in several pages?
Knipsel7.JPG
Knipsel7.JPG (76.19 KiB) Viewed 4229 times
Paco

Heating finally automated using HomeEasy HE105

Posted: Sunday 08 November 2015 1:12
by thebeetleuk
To setup rooms just go to the following location in the web interface

Setup-->More Options-->Plans-->Room Plan

Now just create a room and add items to it :)

P.s. I'll change the 600 :)

Re: Heating finally automated using HomeEasy HE105

Posted: Sunday 08 November 2015 6:33
by Backbone
Thanks Martin,

Roomplans now added....:-)

Paco

Re: Heating finally automated using HomeEasy HE105

Posted: Friday 04 December 2015 10:44
by MajorJ
So, been having a go at trying to get v0.4.1 to work but getting some errors in the log file. It's probably me not RTFM-ing but if anyone could help.....

Code: Select all

2015-12-04 09:41:00.413 Error: EventSystem: /home/pi/domoticz/scripts/lua/script_time_heating-0.1.lua:165: attempt to index global 'devicechanged' (a nil value)
I *think* this is due to this line

Code: Select all

if( timedifference(otherdevices_lastupdate[physicalheater]) > heaterrepeatdelay or devicechanged[remoteup] or devicechanged[remotedown] or devicechanged[virtualheater]) then -- checks to see if the command needs to be repeated
and the

Code: Select all

devicechanged[remoteup]
and

Code: Select all

devicechanged[remotedown]
what are the remoteup and remotedown and where are they defined? I couldn't find any definitions....?

Thanks
Andy

Re: Heating finally automated using HomeEasy HE105

Posted: Friday 04 December 2015 17:57
by thebeetleuk
Andy, looks like you have found some redundant code! Bad me!!

"Latest Version of the code updated : 10/03/2015 V0.4 <- Latest version updated to support new temperature set point switch. this removes the need for lots of the code and additional switches. Enjoy :)"

I have made some additional changes over the last month so will upload the latest version when I get home.

Strange thing however is that I am not getting the same error (I don't think!). This makes me wonder if the code is ever getting to that point to throw the error (investigation required).

Out of interest have you created the virtual switch as defined in step 4?
-- 4. A virtual switch to set the target temperature (Temperature)

Re: Heating finally automated using HomeEasy HE105

Posted: Friday 04 December 2015 21:08
by MajorJ
Ah that may explain it :-)

I suspect my setup maybe one of the 'edge cases' (I always seem to be a bit odd...) but I thought I'd followed all the instructions.

I do have a virtual switch (but not sure how or what it's used for). I think need to read the code in a bit more detail.

Thanks for taking the time and effort to post!
Andy

Re: Heating finally automated using HomeEasy HE105

Posted: Friday 04 December 2015 23:33
by thebeetleuk
I have checked my latest code tonight and I do still have the redundant code in place :oops:

I was in the process of updating to run off some variables and if possible set itself up automatically (so you don't need to read all the instructions)

Looks like I need to be slightly more detailed in the instructions. I'll post the latest code asap once I have remove the errors.

Re: Heating finally automated using HomeEasy HE105

Posted: Friday 04 December 2015 23:38
by thebeetleuk
MajorJ wrote:
I do have a virtual switch (but not sure how or what it's used for). I think need to read the code in a bit more detail.
-----------------------------------------------------------------------------------------------
-- 4. A virtual switch to set the target temperature (Temperature)
-- Assumes you are using a dummy switch "Thermostat Setpoint" to move temperature up and down
-----------------------------------------------------------------------------------------------
local targettemperature = 'Thermostat House'

This is used for moving the target temperature. See the first post in the thread.

Re: Heating finally automated using HomeEasy HE105

Posted: Saturday 05 December 2015 17:14
by MajorJ
It was this one I was confused about

-----------------------------------------------------------------------------------------------
-- 3. A virtual switch to tun on and off the heating (On/Off Switch)
-----------------------------------------------------------------------------------------------
local virtualheater = '(CH) Virtual'

If I've got a 'real' switch to control my Central Heating why do I need a virtual one too?

Re: Heating finally automated using HomeEasy HE105

Posted: Thursday 10 December 2015 21:30
by thebeetleuk
The virtual switch is just to say you want the heating on and off. While the heating might be on (via the virtual switch) the physical switch might be off as the temperature might have reached the value you want to get to. when the temperature drops then the script will turn the physical heater back on.

Re: Heating finally automated using HomeEasy HE105

Posted: Wednesday 13 January 2016 23:16
by mihadongle
Hallo i have some problem in the log

2016-01-13 23:04:56.901 Domoticz V2.4078 (c)2012-2016 GizMoCuz
2016-01-13 23:04:56.902 Build Hash: 7f07293, Date: 2016-01-10 08:33:58
2016-01-13 23:04:56.922 Sunrise: 07:50:00 SunSet:16:31:00
2016-01-13 23:04:56.922 EventSystem: reset all events...
2016-01-13 23:04:56.937 Active notification subsystems: (0/10)
2016-01-13 23:04:57.031 Webserver(HTTP) started on port: 8080
2016-01-13 23:04:57.047 Incoming connection from: 127.0.0.1
2016-01-13 23:04:57.047 Webserver(SSL) started on port: 443
2016-01-13 23:04:57.047 Proxymanager started.
2016-01-13 23:04:57.047 Starting shared server on: :::6144
2016-01-13 23:04:57.047 TCPServer: shared server started...
2016-01-13 23:04:57.047 RxQueue: queue worker started...
2016-01-13 23:04:59.066 EventSystem: reset all events...
2016-01-13 23:04:59.066 EventSystem: reset all device statuses...
2016-01-13 23:04:59.067 EventSystem: Started
2016-01-13 23:05:00.165 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:213: attempt to index global 'devicechanged' (a nil value)
2016-01-13 23:06:00.081 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:213: attempt to index global 'devicechanged' (a nil value)
2016-01-13 23:07:00.485 EventSystem: Script event triggered: C:\Program Files (x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua
2016-01-13 23:07:00.769 (Wohnzimmer licht) Lighting 2 (Heating House (Boiler))
2016-01-13 23:09:34.599 User: Admin initiated a switch command
2016-01-13 23:09:34.600 (Wohnzimmer Schalter1) Lighting 2 (Heating House)
2016-01-13 23:09:35.489 User: Admin initiated a switch command
2016-01-13 23:09:35.489 (Wohnzimmer licht) Lighting 2 (Heating House (Boiler))
2016-01-13 23:09:49.706 (Wohnzimmer Schalter1) Thermostat (Thermostat House)
2016-01-13 23:09:51.810 User: Admin initiated a switch command
2016-01-13 23:09:51.810 (Wohnzimmer licht) Lighting 2 (Heating House (Boiler))
2016-01-13 23:10:00.388 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:102: bad argument #1 to 'sub' (string expected, got nil)
2016-01-13 23:10:54.785 (Wohnzimmer Schalter1) Thermostat (Thermostat House)
2016-01-13 23:11:00.260 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:102: bad argument #1 to 'sub' (string expected, got nil)
2016-01-13 23:11:29.236 (Wohnzimmer Schalter1) Thermostat (Thermostat House)
2016-01-13 23:12:00.330 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:102: bad argument #1 to 'sub' (string expected, got nil)
2016-01-13 23:13:00.085 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:102: bad argument #1 to 'sub' (string expected, got nil)
2016-01-13 23:14:00.480 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:102: bad argument #1 to 'sub' (string expected, got nil)
2016-01-13 23:15:00.371 Error: EventSystem: ...(x86)\Domoticz\scripts\lua\script_time_heating-0.4.1.lua:102: bad argument #1 to 'sub' (string expected, got nil)


Please Help me
Best regard Mike

dzVents home heating using HomeEasy HE105

Posted: Friday 08 April 2016 19:28
by commodore white
Thanks for the inspiration for deploying my HE105. I've used the code already listed in this thread as a model upon which to write my own, but this time using the dzVents add-on.

The code allows for a list of thermometers which are averaged to get the current temperature. Thermometers which have not updated recently are ignored. To prevent the boiler from cycling too frequently, you can specify a tolerance value to force some hysteresis into the workings, you can also specify a maximum rate by which the boiler can be switched.
It also allows you to list door and window sensors which are checked. If any are found open then heating is disabled.
My implementation uses a dzVents script to detect presence based on successfully pinging our android phones - if neither of the phones are present then heating is temporarily disabled. I've yet to see how well this works in practice .

Optionally, a timer runs to update the boiler setting every so often.

At present I use a simple dimmer to specify the set point, this'll change when my plumber get involved. Suggestions for improvements welcome.

Code: Select all

-- /lua/scripts/heating.lua adapted for dzVents by commodore white

local               doors = {"foo"}            -- list of doors
local             windows = {"bar"}            -- list of windows
local        thermometers = {             -- list of thermometers to average out
                            "envKitchen" }
local          thermostat = "Bedroom"     -- name of the control used to select the temperature
local              boiler = "boiler"      -- name of the switch that controls the boiler
local             heating = "heating"     -- name of the switch used to turn heating on and off

local thermometer_timeout = 60  -- minutes to prevent relying on a broken thermometer
local     max_temperature = 25  -- degrees to detect heating over-run
local     min_temperature = 15  -- degress for target if house is unoccupied 
local       frost_protect = 10  -- degrees for target to protect against a freeze (un-implemented)
local boiler_switch_delay = 10  -- seconds to prevent boiler being switched too frequently (negative to disable)
local           tolerance = 0.5 -- degrees of thermal hysteresis to avoid frequent cycling
local          keep_alive = 15  -- minutes between repeated commands (9999 to efectively disable)
 
local               debug = true

-------------------- break the seal to void the warrenty -------------------------

-- build the on= list

local onlist = {['timer'] = 'every ' .. keep_alive .. ' minutes', thermostat, heating}
          
for _,j in ipairs(thermometers) do onlist[#onlist+1] = j end
for _,j in ipairs(doors       ) do onlist[#onlist+1] = j end
for _,j in ipairs(windows     ) do onlist[#onlist+1] = j end

if false then for i,j in ipairs(onlist) do print(i..' '..j) end end

--

return {
  active = true, on=onlist,
	execute = function(domoticz,_device)
 
local printf = function(s,...) if debug then print('heating: ' .. s:format(...)) end end

local       _thermometer = domoticz.devices[thermometer]
local        _thermostat = domoticz.devices[thermostat]
local            _boiler = domoticz.devices[boiler]
local            _heating = domoticz.devices[heating]

        printf("Heating: %s ...... Boiler: %s ", _heating.state, _boiler.state)

-- re-issue most recent boiler command depending on keep_alive timer

local   demand = ""

        if     _device == nil -- scheduled script execution ?
        then
               demand = _boiler.state
               printf('Resend most recent boiler command: %s', demand)
               _boiler.setState(demand)
               return
        end

-- Calculate temperature by averaging those listed. Ignore any that have not responded recently.

local    count = 0
local    sum = 0

for _,thermometer in ipairs(thermometers)
  do
    _therm = domoticz.devices[thermometer]
    if    _therm ~= nil                               -- check the device exists
    then                                              -- if so
          age     = _therm.lastUpdate.minutesAgo
          temp    = domoticz.devices[thermometer].temperature
          printf("Thermometer %s (updated %sm ago) is %2.1f", thermometer, age, temp)
          if      age < thermometer_timeout      -- if thermometer still responding 
          then
                  count = count + 1                   -- accumulate the temperatures
                  sum = sum + temp                    -- and the number included
                  if      temp > max_temperature then -- if temperature is too high
                          boiler_switch_delay = 0     -- send command immediately
                          demand = "Off"
                          _heating.switchOff()
                          domoticz.notify("Room temperature of " .. t .. "deg is too high","Shutting down")
                  end
          else
                  printf("Thermometer device %s is unresponsive - skipping", thermometer)
          end
    else
          printf("Thermometer device %s not found - skipping", thermometer)
    end
  end

  if      count == 0
  and     _heating.state == "On"
  then
          printf("No viable thermometers found - turning heating Off")
          _boiler.switchOff()
          _heating.switchOff()
          return
  end

local   current = sum/count  -- calculate average across all thermometers

-- set the target temperature depending on house occupancy

local   is_occupied = domoticz.devices["AnyPhone"].state == "On"
local   target

        if    is_occupied
        then
              target = _thermostat.rawData[1]
        else
              print("House is unoccupied")
              target = min_temperature
        end                                                  

        printf('target temp:   %s', target)                 
        printf('Average current temp: %2.1f (average of %1d measurement(s))', current,count)

-- check if any doors or windows are open

local  is_open = false -- assume no doors or windows are open

        for _,door in ipairs(doors) do
local       ptr   = domoticz.devices[door]
            if    ptr == nil then
                  printf("No such door sensor as %s - skipping it", door)
            else
                  if    ptr.state == "Alarm" then
                        printf("Door %s is open", door)
                        is_open = true
                  end
            end
         end

        for _,window in ipairs(windows) do
local       ptr   = domoticz.devices[window]
            if    ptr == nil then
                  printf("No such window sensor as %s - skipping it", window)
            else
                  if    ptr.state == "Alarm" then
                        printf("Window %s is open", window)
                        is_open = true
                  end
            end
         end

         if        is_open
         then
                print("One or more doors or windows open - heating is disabled")
                _boiler.switchOff()
                return
         end

-- if the doors and windows are closed and the house is occupied, then
-- heat the room if it's cold, don't if it's not 

local   is_heatingScheduled = _heating.state == "On"

        if      is_heatingScheduled
        and     not is_open          -- doors/windows closed
        then
                is_toohot   = current > target + tolerance
                is_toocool  = current < target - tolerance
                        
                if      is_toohot
                and     _boiler.state == "On"
                then    demand = "Off"
                        printf('Too hot! Switching boiler Off') end

                if      is_toocool
                and     _boiler.state == "Off"
                then    demand = "On"
                        printf('Too cold! Switching boiler On') end                        
        else
                if      _boiler.state == "On"
                then
                        printf("Switching boiler Off")
                        demand = "Off" -- turn off boiler if heating is off or if doors/windows are open
                end
        end

-- send the boiler the command ensuring there's a reasonable delay since the last one

local   age     = _boiler.lastUpdate.secondsAgo printf("Boiler previously updated %ss ago", age)
local   delay   = boiler_switch_delay - age

        if      demand ~= ""
        then
                if      age >= boiler_switch_delay
                then
                        _boiler.setState(demand)
                else
                        if boiler_switch_delay >= 0 then
                              _boiler.setState(demand).after_sec(delay)
                        end
                end
        end

	end -- execute
 
}
Enjoy, Peter

Re: Heating finally automated using HomeEasy HE105

Posted: Friday 06 May 2016 20:57
by pieman
The Home Easy HE105 Central Heating Switch can now also be controlled over the internet with a free Smartphone app and a few parts costing around 4 quid / 5 bucks. Blynk has the details on their Community pages at http://community.blynk.cc/t/connect-you ... blynk/5925