
Originally Posted by
victorp1612
Thanks , works like a charm :-)
I've updated my domoticz evohome patch to add support for retrieving full resolution of the hot water temperature, and also improved error handling and recovery a bit so that if it can't for some reason find a matching zone in the V1 API it will cleanly fall back to giving the V2 API temperature reading.
The new code:
Code:
#!/usr/bin/python
#
# Copyright 2015 - fullTalgoRythm
#
# Licensed under GNU General Public License 3.0 or later.
# Some rights reserved. See COPYING, AUTHORS.
#
# @license GPL-3.0+ <http://spdx.org/licenses/GPL-3.0+>
#
# see http://www.domoticz.com/wiki/Evohome
# see http://evohome-client.readthedocs.org/en/latest/index.html
#
import evoconfig
from evohomeclient2 import EvohomeClient
import evohomeclient
import requests
import json
import datetime
import base64
import os
import sys, traceback
if os.path.isfile("/var/tmp/evo-noup.tmp"):
os.remove("/var/tmp/evo-noup.tmp")
sys.exit(1)
#connect to evohome web portal @ http://www.mytotalconnect.com
client = EvohomeClient(evoconfig.usr,evoconfig.pw)
#also connect to V1 API to fetch more accurate temperature readings
client1 = evohomeclient.EvohomeClient(evoconfig.usr,evoconfig.pw)
fi=client.full_installation()
systemId=fi['gateways'][0]['temperatureControlSystems'][0]['systemId']
modelType=fi['gateways'][0]['temperatureControlSystems'][0]['modelType']
status=client.locations[0].status()
tcs=status['gateways'][0]['temperatureControlSystems'][0]
zones=tcs['zones']
currentmode=tcs['systemModeStatus']['mode']
createdev=False
updatedev=True
hwname="evohome"
if len(sys.argv)>1:
mode=sys.argv[1]
if mode=="init":
createdev=True
if len(sys.argv)>2:
hwname=sys.argv[2]
elif mode=="quick":
updatedev=False
if createdev:
#create evohome script hardware
r=requests.get("http://%s:%s/json.htm?type=command¶m=addhardware&htype=40&port=1&name=%s&enabled=true&datatimeout=0" % (evoconfig.url,evoconfig.port,hwname))
#find last added evohome script hw
r=requests.get("http://%s:%s/json.htm?type=hardware" % (evoconfig.url,evoconfig.port))
hwl=json.loads(r.text)
hwid=-1
for hw in hwl['result']:
if hw['Type']==40:
hwid=int(hw['idx'])
if hwid==-1:
print "ERROR: evohome hardware not found"
sys.exit(1)
if createdev:
#create evohome controller device
r=requests.get("http://%s:%s/json.htm?type=createevohomesensor&idx=%d&sensortype=69" % (evoconfig.url,evoconfig.port,hwid))
#create evohome dhw device
r=requests.get("http://%s:%s/json.htm?type=createevohomesensor&idx=%d&sensortype=71" % (evoconfig.url,evoconfig.port,hwid))
#create evohome zones - create all 12 as helpful if they are sequential
for i in range(12):
r=requests.get("http://%s:%s/json.htm?type=createevohomesensor&idx=%d&sensortype=70" % (evoconfig.url,evoconfig.port,hwid))
#update evohome devices with default name, id for portal access and correct location/name of script to run
r=requests.get("http://%s:%s/json.htm?type=devices&displayhidden=1&used=all" % (evoconfig.url,evoconfig.port))
devl=json.loads(r.text)
for dev in devl['result']:
if dev['HardwareID']==hwid:
if dev['SubType']=='Evohome':
if updatedev:
r=requests.get("http://%s:%s/json.htm?type=setused&idx=%s&deviceid=%s&used=true&name=%s&strparam1=%s" % (evoconfig.url,evoconfig.port,dev['idx'],systemId,modelType,base64.urlsafe_b64encode('%s/evo-setmode.sh {status}' % (evoconfig.srt))))
r=requests.get("http://%s:%s/json.htm?type=command¶m=switchmodal&idx=%s&status=%s&action=0&ooc=1" % (evoconfig.url,evoconfig.port,dev['idx'],currentmode))
elif dev['SubType']=='Hot Water' and 'dhw' in tcs:
dhw=tcs['dhw']
if updatedev:
r=requests.get("http://%s:%s/json.htm?type=setused&idx=%s&deviceid=%s&used=true&name=%s&strparam1=%s" % (evoconfig.url,evoconfig.port,dev['idx'],dhw['dhwId'],"Hot Water",base64.urlsafe_b64encode('%s/evo-setdhw.sh {deviceid} {mode} {state} {until}' % (evoconfig.srt))))
zonemode=dhw['stateStatus']['mode']
if currentmode=="HeatingOff" or currentmode=="AutoWithEco" or currentmode=="Custom":# dhw has no economy mode and does not turn off for heating off also appears custom does not support the dhw zone
currentmode="Auto"
if zonemode=="FollowSchedule":
zonemode=currentmode
# Fetch the measured temperature from the V1 API for increased resolution. Match zones between both API's via id/dhwId.
temp=dhw['temperatureStatus']['temperature']
for zonetemp in client1.temperatures():
if int(zonetemp['id'])==int(dhw['dhwId']):
temp=zonetemp['temp']
break
req="http://%s:%s/json.htm?type=command¶m=udevice&idx=%s&nvalue=0&svalue=%s;%s;%s" % (evoconfig.url,evoconfig.port,dev['idx'],temp,dhw['stateStatus']['state'],zonemode)
if zonemode=="TemporaryOverride":
req+=";%s" % (dhw['stateStatus']['until'])
r=requests.get(req)
elif dev['SubType']=='Zone' and dev['Unit']<=len(zones):
zone=zones[dev['Unit']-1]
if updatedev:
r=requests.get("http://%s:%s/json.htm?type=setused&idx=%s&deviceid=%s&used=true&name=%s&strparam1=%s" % (evoconfig.url,evoconfig.port,dev['idx'],zone['zoneId'],zone['name'],base64.urlsafe_b64encode('%s/evo-settemp.sh {deviceid} {mode} {setpoint} {until}' % (evoconfig.srt))))
if not zone['temperatureStatus']['isAvailable']:
continue
zonemode=zone['heatSetpointStatus']['setpointMode']
#for custom mode the rooms are assignable so ideally we need to check the schedule and see if the room is assigned or not
if zonemode=="FollowSchedule" or currentmode=="HeatingOff": #heating off doesn't support override i.e. heating is permanently switched off
zonemode=currentmode
# Fetch the measured temperature from the V1 API for increased resolution. Match zones between both API's via id/zoneId.
temp=zone['temperatureStatus']['temperature']
for zonetemp in client1.temperatures():
if int(zonetemp['id'])==int(zone['zoneId']):
temp=zonetemp['temp']
break
req="http://%s:%s/json.htm?type=command¶m=udevice&idx=%s&nvalue=0&svalue=%s;%s;%s" % (evoconfig.url,evoconfig.port,dev['idx'],temp,zone['heatSetpointStatus']['targetTemperature'],zonemode)
if zonemode=="TemporaryOverride":
req+=";%s" % (zone['heatSetpointStatus']['until'])
r=requests.get(req)
if createdev:
print "Your evohome zones should now be available in the Domoticz"
The new diff, mainly to make it easy to see the changes:
Code:
--- evo-update.bak 2016-08-04 20:46:45.063303828 +0100
+++ evo-update.sh 2016-10-30 20:00:01.996775185 +0000
@@ -13,6 +13,7 @@
import evoconfig
from evohomeclient2 import EvohomeClient
+import evohomeclient
import requests
import json
import datetime
@@ -26,6 +27,8 @@
#connect to evohome web portal @ http://www.mytotalconnect.com
client = EvohomeClient(evoconfig.usr,evoconfig.pw)
+#also connect to V1 API to fetch more accurate temperature readings
+client1 = evohomeclient.EvohomeClient(evoconfig.usr,evoconfig.pw)
fi=client.full_installation()
systemId=fi['gateways'][0]['temperatureControlSystems'][0]['systemId']
modelType=fi['gateways'][0]['temperatureControlSystems'][0]['modelType']
@@ -89,7 +92,13 @@
currentmode="Auto"
if zonemode=="FollowSchedule":
zonemode=currentmode
- req="http://%s:%s/json.htm?type=command¶m=udevice&idx=%s&nvalue=0&svalue=%s;%s;%s" % (evoconfig.url,evoconfig.port,dev['idx'],dhw['temperatureStatus']['temperature'],dhw['stateStatus']['state'],zonemode)
+ # Fetch the measured temperature from the V1 API for increased resolution. Match zones between both API's via id/dhwId.
+ temp=dhw['temperatureStatus']['temperature']
+ for zonetemp in client1.temperatures():
+ if int(zonetemp['id'])==int(dhw['dhwId']):
+ temp=zonetemp['temp']
+ break
+ req="http://%s:%s/json.htm?type=command¶m=udevice&idx=%s&nvalue=0&svalue=%s;%s;%s" % (evoconfig.url,evoconfig.port,dev['idx'],temp,dhw['stateStatus']['state'],zonemode)
if zonemode=="TemporaryOverride":
req+=";%s" % (dhw['stateStatus']['until'])
r=requests.get(req)
@@ -103,7 +112,13 @@
#for custom mode the rooms are assignable so ideally we need to check the schedule and see if the room is assigned or not
if zonemode=="FollowSchedule" or currentmode=="HeatingOff": #heating off doesn't support override i.e. heating is permanently switched off
zonemode=currentmode
- req="http://%s:%s/json.htm?type=command¶m=udevice&idx=%s&nvalue=0&svalue=%s;%s;%s" % (evoconfig.url,evoconfig.port,dev['idx'],zone['temperatureStatus']['temperature'],zone['heatSetpointStatus']['targetTemperature'],zonemode)
+ # Fetch the measured temperature from the V1 API for increased resolution. Match zones between both API's via id/zoneId.
+ temp=zone['temperatureStatus']['temperature']
+ for zonetemp in client1.temperatures():
+ if int(zonetemp['id'])==int(zone['zoneId']):
+ temp=zonetemp['temp']
+ break
+ req="http://%s:%s/json.htm?type=command¶m=udevice&idx=%s&nvalue=0&svalue=%s;%s;%s" % (evoconfig.url,evoconfig.port,dev['idx'],temp,zone['heatSetpointStatus']['targetTemperature'],zonemode)
if zonemode=="TemporaryOverride":
req+=";%s" % (zone['heatSetpointStatus']['until'])
r=requests.get(req)
I've passed a copy of the code on to DanD so the above new version will hopefully show up on the Domoticz wiki page soon as well.