Evohome Python Set script

Right, This was originally a post for Evohome binding 2.0 however I realised it was probably best for the moment in it’s own topic. This is a python script which will enable you to use the current evohome 2.0 binding in conjunction with these scripts in order to setzones as well as read. It’s designed as a temporary stop gap until we can work out the best way to set a zone within the native binding!

Here be dragons

I’ve done my best to document how this worked, it works for my setup but as usual YMMV. i MIGHT have missed a step, so if it doesn’t work then give me a shout and I’ll try to diagnose!

Requirements

Install steps

  • Install the prereqs above
  • Create the two files below somewhere on your openhab server (I currently put them somewhere in /opt)
  • Ensure you update the location of the evohome-client library on the 2nd line of setzone.py:
    sys.path.append('<path-to-evohome-git>')
  • Create the following things/items for each of your evohome zones
    • evohome-python.things:
      Thing exec:command:<zone>_evohome_python [command="/usr/bin/python3 <path-to-setzone>/setzone.py %2$s", interval=0, timeout=30, autorun=true]
    • evohome-python.items:
      String <zonename>_Evohome_Input "[%s]" (gEvohome) {channel="exec:command:Lounge_evohome_python:input"}
      Switch <zonename>_Evohome_CurrentSetPoint_Reset "Living Room Schedule Reset" (gEvohome)
      
    • evohome_python.rules
      rule "<zonename>_Evohome_CurrentSetPoint_command"
      when
      	Item <Zone CurrentSetPoint Item> received command
      then
      	<Zonename>_Evohome_Input.sendCommand("'<Zonename>' "+<Zone CurrentSetPoint Item>.state);
      end
      
      rule "<zonename>_Evohome_CurrentSetPoint_Reset_command"
      when
      	Item <zonename>_Evohome_CurrentSetPoint_Reset received command
      then
      	<Zonename>_Evohome_Input.sendCommand("'<zonename>' reset");
      	postUpdate(<Zonename>_Evohome_CurrentSetPoint_Reset, "OFF");
      end
      
      
      

setzone.cfg

[Evohome]
username=<<evohomeusername>>
password=<<evohomepassword>>

setzone.py

import sys
sys.path.append('<path-to-evohome-git>')

from sys import argv
from evohomeclient2 import EvohomeClient
from datetime import datetime
from datetime import timedelta
import configparser
import shlex

print(sys.argv)
parsed = shlex.split(' '.join(sys.argv[1:]))
if (len(parsed)+1 > len(sys.argv)):
    parsed = sys.argv[1:]
print("Parsed: ",parsed)

reset = False

if len(parsed) == 2:
    zone, temperature = parsed
    if (temperature == "reset"):
        reset = True
        temperature = 0
    time = None
elif len(parsed) == 3:
    zone, temperature, time = parsed
    time = int(time)
else:
    print("Invalid number of arguements, format: setzone.py <zonename> <temperature> [time (s)]")
    sys.exit(128)

config = configparser.RawConfigParser()
config.read('/opt/smarthome/conf/opt/python/setzone.cfg')
username = config.get('Evohome','username')
password = config.get('Evohome','password')

client = EvohomeClient(username, password)
zone = client.locations[0]._gateways[0]._control_systems[0].zones[zone];
schedules = zone.schedule()['DailySchedules'];

weekday = datetime.today().weekday()

if reset:
    print("Resetting zone to schedule")
    zone.cancel_temp_override(zone.name);
else:
    if time is None:
    
        switchofftime = None;
    
        for schedule in schedules:
            for point in schedule['Switchpoints']:
                if schedule['DayOfWeek'] < weekday:
                    daydelta = schedule['DayOfWeek'] + 7 - weekday
                else:
                    daydelta = schedule['DayOfWeek'] - weekday
                (hour, minute, second) = (int(x) for x in point['TimeOfDay'].split(":"))
                setPointTime = datetime(datetime.today().year,datetime.today().month,(datetime.today() + timedelta(days=(daydelta))).day,hour,minute,second)
                print(setPointTime);
                if (setPointTime > datetime.today()):
                    if switchofftime is None or setPointTime < switchofftime:
                        switchofftime = setPointTime
    
        if switchofftime is None:
            switchofftime = datetime.today() + timedelta(hours=1)
    else:
        switchofftime = datetime.today() + timedelta(seconds=time)
        print(switchofftime)
    
    print("Switch off time: ",switchofftime)
    zone.set_temperature(temperature, switchofftime)
1 Like

@jvanzuijlen The most useful thing here for you / the binding is probably the logic in the sethome.py script.

  • If reset
    • remove the override
  • else
    • Loop through the list of switchpoints
    • Find the Next setpoint
    • If you didn’t find a sensible setpoint, schedule it for today+1 hour
    • Set the temperature for the current zone until the designated time setpoint

I’m not really a java dev or i’d look at doing a pull request, but hopefully the logic is useful to finally getting a sensible method to set temperatures within the evohome system. (this could also be done via a seperate command channel instead of via the current setpoint channel as per the script)

1 Like

A small addendum to the setzone.py script. It doesn’t correctly take into account timezones, so add the bottom of the script replace:

zone.set_temperature(temperature, switchofftime)

with:

UTC_OFFSET_TIMEDELTA = datetime.utcnow() - datetime.now()
zone.set_temperature(temperature, switchofftime + UTC_OFFSET_TIMEDELTA)

This will make sure the timezone is corrected to whatever the zone is on your machine.

1 Like

HI @VibroAxe

First off all thanks for the amazing script. Just what i need. Im new to openhab (and python and linux). Iv bene having a play around this week and got to grips with setting up my things/items for lighting and the eco home. All configured and working in the sitemap / ui.

Im struggling a bit though setting up the rules file for this ( i think i have the other files setup correctly but could be wrong). Not sure what to put where and what to change. Could you advise me? Here are the files i have configured

evohome-python.things

Thing exec:command:evohome:heatingzone:HOME:Office_evohome_python [command="/usr/bin/python3 etc/openhab2/setzone.py %2$s", interval=0, timeout=30, autorun=true]

evohome-python.items

String evohome_heatingzone_HOME_Office_Evohome_Input "[%s]" (gEvohome) {channel="exec:command:Office_evohome_python:input"}
Switch evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset "Office Schedule Reset" (gEvohome)

But not sure what i need to set in the rules. What ever i am trying in VScode just seems to give me more red underlines

Any help would greatly be appreciated.

Thought i had got abit further but still cant get it to work unless what i have done is wrong.

Rules:

rule "evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_command"
when
	Item evohome_py_office_CurrentSetPoint received command
then
	evohome_heatingzone_HOME_Office_Evohome_Input.sendCommand("'evohome_heatingzone_HOME_Office' "+evohome_py_office_CurrentSetPoint.state);
end

rule "evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset_command"
when
	Item evohome_py_office_CurrentSetPoint_Reset received command
then
	evohome_heatingzone_HOME_Office_Evohome_Input.sendCommand("'evohome_py_office_CurrentSetPoint_reset' reset");
	postUpdate(evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset, "OFF");
end

Home.Items *Are these needed? Am i going about this the wrong way?

Number evohome_py_office_CurrentSetPoint "Set Temp"
Switch evohome_py_office_CurrentSetPoint_Reset "Reset"

SiteMap: Again i could have this all wrong:

Setpoint item=evohome_py_office_CurrentSetPoint label="Set Temp [%.1f °C]" minValue=5 maxValue=30 step=0.5 icon="temperature"
                Switch item=evohome_py_office_CurrentSetPoint_Reset  label="Reset Heating" icon="heating"

Logs

Summary

2018-02-09 14:26:04.104 [ome.event.ItemCommandEvent] - Item ‘evohome_py_office_CurrentSetPoint’ received command 11

2018-02-09 14:26:04.111 [vent.ItemStateChangedEvent] - evohome_py_office_CurrentSetPoint changed from 10.5 to 11

2018-02-09 14:26:04.145 [ome.event.ItemCommandEvent] - Item ‘evohome_heatingzone_HOME_Office_Evohome_Input’ received command ‘evohome_heatingzone_HOME_Office’ 11

2018-02-09 14:26:04.152 [vent.ItemStateChangedEvent] - evohome_heatingzone_HOME_Office_Evohome_Input changed from ‘evohome_heatingzone_HOME_Office’ 10 to ‘evohome_heatingzone_HOME_Office’ 11

2018-02-09 14:26:04.841 [ome.event.ItemCommandEvent] - Item ‘evohome_py_office_CurrentSetPoint_Reset’ received command ON

2018-02-09 14:26:04.845 [vent.ItemStateChangedEvent] - evohome_py_office_CurrentSetPoint_Reset changed from OFF to ON

2018-02-09 14:26:04.850 [ome.event.ItemCommandEvent] - Item ‘evohome_heatingzone_HOME_Office_Evohome_Input’ received command ‘evohome_py_office_CurrentSetPoint_reset’ reset

2018-02-09 14:26:04.855 [vent.ItemStateChangedEvent] - evohome_heatingzone_HOME_Office_Evohome_Input changed from ‘evohome_heatingzone_HOME_Office’ 11 to ‘evohome_py_office_CurrentSetPoint_reset’ reset

2018-02-09 14:26:05.493 [ome.event.ItemCommandEvent] - Item ‘evohome_py_office_CurrentSetPoint_Reset’ received command OFF

2018-02-09 14:26:05.500 [vent.ItemStateChangedEvent] - evohome_py_office_CurrentSetPoint_Reset changed from ON to OFF

2018-02-09 14:26:05.513 [ome.event.ItemCommandEvent] - Item ‘evohome_heatingzone_HOME_Office_Evohome_Input’ received command ‘evohome_py_office_CurrentSetPoint_reset’ reset

2018-02-09 14:26:54.149 [vent.ItemStateChangedEvent] - evohome_heatingzone_HOME_Livingroom_Temperature changed from 20.5 to 21.0

Hi Curtis

First up, i’ve noticed an error in your evohome-python.items file, the _Input item is not linked to the correct channel:

String evohome_heatingzone_HOME_Office_Evohome_Input "[%s]" (gEvohome) {channel="exec:command:evohome:heatingzone:HOME:Office_evohome_python:input"}

I’m also 90% sure than your .thing is invalid and should read more like this:

Thing exec:command:evohome_heatingzone_HOME_Office_python [command="/usr/bin/python3 etc/openhab2/setzone.py %2$s", interval=0, timeout=30, autorun=true]

(notice the lack of : in the thing name) which would then require your items file to be

String evohome_heatingzone_HOME_Office_Evohome_Input "[%s]" (gEvohome) {channel="exec:command:exec:command:evohome_heatingzone_HOME_Office_python:input"}

Assuming you are using the evohome binding as well then you should create the CurrentSetPoint item within paperui and link it to the relevant binding channel.

Your rules are nearly correct :stuck_out_tongue:

rule "evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_command"
when
	Item evohome_py_office_CurrentSetPoint received command //this should be your item from paper ui
then
	evohome_heatingzone_HOME_Office_Evohome_Input.sendCommand("'Office' "+evohome_py_office_CurrentSetPoint.state); //the 'Office' within this send command is the name of the zone on the evohome controller
end

rule "evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset_command"
when
	Item evohome_py_office_CurrentSetPoint_Reset received command
then
	evohome_heatingzone_HOME_Office_Evohome_Input.sendCommand("'Office' reset"); //Again the 'Office' is the name of the zone on the evohome controller
	postUpdate(evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset, "OFF");
end

Hope that helps you get up and running?

HI @VibroAxe

Thanks for getting back to me. I’m still having issues. IE its still not working haha :frowning: which I am really sad about - I’m normally good with things like this. I made all the changes you recommended (i think) which still didn’t work. Along with something else that i think you/I might have missed. Would you be able to take 1 more look at my files and let me know if i have missed something. Would you be able to provide me with you files so i can have a read through and see everything linking together?

evohome-Python.things:

Thing exec:command:evohome_heatingzone_HOME_Office_python [command="/usr/bin/python3 etc/openhab2/setzone.py %2$s", interval=0, timeout=30, autorun=true]

Getting this error from saving Things file. Anything to worry about?

==> /var/log/openhab2/openhab.log <==

2018-02-15 16:26:00.850 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'evohome-python.things'

2018-02-15 16:26:00.858 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'evohome-python.things' is either empty or cannot be parsed correctly!

2018-02-15 16:26:00.897 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'evohome-python.things'

2018-02-15 16:26:00.943 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'evohome-python.things'

evohome-Python.items:

String evohome_heatingzone_HOME_Office_Evohome_Input "[%s]" (gEvohome) {channel="exec:command:evohome_heatingzone_Home_Office_evohome_python:input"}
Switch evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset "Office Schedule Reset" (gEvohome)

Evohome_Python.rules:

So in here i changed the item to be what’s in the paper UI like you said (still didn’t work. I also noticed that on line 5
_Evohome_Input.sendCommand("’’ "+.state);

This also needed to be changed to the Paper UI item. When doing this i get an error

2018-02-15 14:08:25.733 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'evohome_python.rules' has errors, therefore ignoring it: [4,2]: no viable alternative at input ':'

[6,79]: mismatched input ':' expecting ')'

[6,91]: mismatched input ':' expecting 'end'

2018-02-15 14:08:25.832 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'evohome_python.rules' has errors, therefore ignoring it: [4,2]: no viable alternative at input ':'

[6,79]: mismatched input ':' expecting ')'

[6,91]: mismatched input ':' expecting 'end'

rule "evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_command"
when
	Item evohome:heatingzone:HOME:Office:CurrentSetPoint received command //this should be your item from paper ui
then
	evohome_heatingzone_HOME_Office_Evohome_Input.sendCommand("'Office' "+evohome:heatingzone:HOME:Office:CurrentSetPoint.state); // I changed the "+<Zone CurrentSetPoint Item>. too to match thepaper UI but this gives me a errors  //the 'Office' within this send command is the name of the zone on the evohome controller
end

rule "evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset_command"
when
	Item evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset received command
then
	evohome_heatingzone_HOME_Office_Evohome_Input.sendCommand("'Office' reset"); //Again the 'Office' is the name of the zone on the evohome controller
	postUpdate(evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset, "OFF");
end

Last file - Home.sitemap: I winged my way through this so it could be wrong:

                Setpoint item=evohome_heatingzone_HOME_Office_Evohome_Input label="Set Temp [%s °C]" minValue=5 maxValue=30 step=0.5 icon="temperature"
                Switch item=evohome_heatingzone_HOME_Office_Evohome_CurrentSetPoint_Reset  label="Reset Heating" icon="heating"

Am i missing any other files other than the setzone.cfg and .py ? Regarding the setzone.cfg - do you leave the username and password in the chevrons or do this need removing? Iv tried every possible scenario here.

Here is also an image of my Paper UI settings for the Office

Other things that could be wrong:

.setzone.py

I have this line set as the below. Does this look right.

import sys
sys.path.append('.\evohome-client\')

Or does it need to be

'.\evohome-client\evohomeclient\
or
'.\evohome-client\evohomeclient2

Also line:

config.read('/opt/smarthome/conf/opt/python/setzone.cfg')

Does this need changing to:

config.read('/etc/openhab2/services/setzone.cfg')

Sorry for the lengthy response but i would really like to get this up and running… i would even be whiling to give you access to my system to help me get this going. trust me to have the Lighting and Heating system that doesn’t work out of the box.

Thanks in advance… Curtis