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
- Python 3
- Evohome client python library (https://github.com/watchforstock/evohome-client)
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
- evohome-python.things:
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)