Page 31 of 47 FirstFirst ... 21262728293031323334353641 ... LastLast
Results 301 to 310 of 470

Thread: Decoded - EvoHome API access to control remotely.

  1. #301
    Automated Home Legend
    Join Date
    Sep 2014
    Location
    Scotland
    Posts
    1,886

    Default

    Quote Originally Posted by victorp1612 View Post
    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&param=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&param=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&param=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&param=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&param=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&param=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&param=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&param=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.

  2. #302
    Automated Home Jr Member
    Join Date
    Feb 2016
    Posts
    23

    Default

    My Domoticz install hasn't been able to connect to my Evohome setup for a couple of days, has something changed in the API which the above code fixes? When I try and run evo-update.sh, the following is returned;

    Traceback (most recent call last):
    File "./evo-update.sh", line 59, in <module>
    hwl=json.loads(r.text)
    File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
    File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
    raise ValueError("No JSON object could be decoded")
    ValueError: No JSON object could be decoded
    EDIT: Nope - same error with the updated evo-update.sh in place

    EDIT2: User error - I'd enabled website protection and it seems you need to allow access to localhost (127.0.0.1) to allow the script to run successfully
    Last edited by DJBenson; 1st November 2016 at 03:41 PM.

  3. #303
    Automated Home Legend
    Join Date
    Sep 2014
    Location
    Scotland
    Posts
    1,886

    Default

    Quote Originally Posted by DJBenson View Post
    EDIT2: User error - I'd enabled website protection and it seems you need to allow access to localhost (127.0.0.1) to allow the script to run successfully
    Yes, connecting on localhost (127.0.0.1) must be possible for the script to work.

    All evo-update.sh is, is a scheduled cron job which queries the data from the Honeywell servers, then sends an HTTP JSON request to Domoticz's own web server (running on localhost relative to where the script is running) to submit the retrieved data to Domoticz. Blocking localhost connections would indeed cause it to fail.
    Last edited by DBMandrake; 1st November 2016 at 04:28 PM.

  4. #304
    Automated Home Lurker
    Join Date
    Nov 2016
    Posts
    1

    Default

    Hi freeranger,

    Thanks for your work, I just installed a Evohome system and wanted to replace the temperature updates I had from my MAX system into my Vera home automation box. I have knocked up a plugin to update virtual temperature sensors and it is working well. The one thing I am missing is a notification if the boiler is currently on or off. I haven't delved into your code yet but wondered it that was in the information that comes back from Honeywell?

  5. #305
    Automated Home Legend
    Join Date
    Jul 2014
    Posts
    1,054

    Default

    No it isnt

  6. #306
    Automated Home Jr Member
    Join Date
    Jan 2016
    Location
    The Netherlands
    Posts
    17

    Default

    Tonight I received an e-mail informing me about sceduled maintenance to the Total Connect Comfort server. In Dutch, but you'll get the point:
    "Onderhoud - Server Total Connect Comfort - op 29/11/16
    Start: 29/11/16 8:00 AM
    Einde: 29/11/16 12:00 PM"

    Could that be an update to extend the V2 API with the more detailed temperature info we recently noticed in the V1 API?
    Does anybody know where to find the 'release notes' of maintenance like this?
    Evohomeclient temperatures on ThingSpeak: https://thingspeak.com/channels/79213

  7. #307
    Automated Home Lurker
    Join Date
    Dec 2016
    Posts
    6

    Default

    Hello guys,

    im new to this forum so please be patient
    What i try to do is to connect my evohome system to domoticz server.
    I installed as advised in the tutorials from domoticz wiki for connecting via RFG100

    My problem is that the python script for connection doesnt work. every time i try to connect I get the following error:

    TypeError: list indices must be integers, not str
    This error raises with the scripts from DBMandrake as well as with other "test"-scripts

    tryed the following to simplify:

    #!/usr/bin/python
    import sys
    import requests
    from evohomeclient2 import EvohomeClient

    client = EvohomeClient('username', 'password')

    #for device in client.temperatures():
    # print(device['temp'])
    # print(device['setpoint'])
    Result:

    Traceback (most recent call last):
    File "test.py", line 6, in <module>
    client = EvohomeClient('username', 'password')
    File "/usr/local/lib/python2.7/dist-packages/evohomeclient2/__init__.py", line 18, in __init__
    self._login()
    File "/usr/local/lib/python2.7/dist-packages/evohomeclient2/__init__.py", line 76, in _login
    self.installation()
    File "/usr/local/lib/python2.7/dist-packages/evohomeclient2/__init__.py", line 86, in installation
    r = requests.get('https://tccna.honeywell.com/WebAPI/emea/api/v1/location/installationInfo?userId=%s&includeTemperatureContr olSystems=True' % self.account_info['userId'], headers=self.headers)
    TypeError: list indices must be integers, not str
    Hope somebody can help me out...

    Thanks in advance

  8. #308
    Automated Home Legend
    Join Date
    Sep 2014
    Location
    Scotland
    Posts
    1,886

    Default

    Are you trying to use the V1 or V2 API ? The code you pasted at the top (which is incomplete, as you have commented out everything except the initial client connection) you are querying the V2 API, however the traceback result appears to show you getting a response from the V1 API ?

    Have you double checked your username and password are correct and work when you log into the Honeywell website ?

    By the way if I query the V1 API with a deliberate wrong password I get very similar results to you:

    Code:
    pi@pi1monitor:~ $ ./evohome_V1
    Traceback (most recent call last):
      File "./evohome_V1", line 8, in <module>
        for device in client.temperatures():
      File "/usr/local/lib/python2.7/dist-packages/evohomeclient/__init__.py", line 73, in temperatures
        self._populate_full_data(force_refresh)
      File "/usr/local/lib/python2.7/dist-packages/evohomeclient/__init__.py", line 33, in _populate_full_data
        userId = self.user_data['userInfo']['userID']
    TypeError: list indices must be integers, not str
    The simplest python script you can write to access the V1 API and print out temperatures looks like this:

    Code:
    #!/usr/bin/python
    
    from evohomeclient import EvohomeClient
    
    client = EvohomeClient('username', 'password')
    
    for device in client.temperatures():
        print device
    This is what I used in my test above with a deliberately wrong password.
    Last edited by DBMandrake; 10th December 2016 at 08:49 PM.

  9. #309
    Automated Home Lurker
    Join Date
    Dec 2016
    Posts
    6

    Default

    Thanks for your reply.

    I tested your code and it works, the temperatures are read out!
    So the error seems to be raised by the v2 API?

    As I understood does your script use V1 and V2 API

    Not sure if its important to mention: When I log in to the Web-Frontend from evohome, it connects to "international.totalconnect.com"

    How can I use your script with domoticz?

    And by the way: Thank you for your great work!

  10. #310
    Automated Home Legend
    Join Date
    Sep 2014
    Location
    Scotland
    Posts
    1,886

    Default

    Quote Originally Posted by thtools View Post
    Thanks for your reply.

    I tested your code and it works, the temperatures are read out!
    So the error seems to be raised by the v2 API?
    In the small test script I just provided if you change the line

    Code:
    from evohomeclient import EvohomeClient
    to

    Code:
    from evohomeclient2 import EvohomeClient
    It will query the same data from the V2 API - you'll notice that temperature readings are rounded to 0.5 degrees from this API. If this also works OK it means the python libraries are installed and querying the servers properly and you have the correct username and password.

    If the V1 API works but the V2 API returns errors it probably means your evohome-client python libraries are outdated and should be updated from here:

    https://github.com/watchforstock/evohome-client

    There was a change to the server hostname for the V2 API some time back and the python client libraries were updated to include this change but if your evohome-client library is out of date it will be querying the old server hostname which may no longer exist.
    As I understood does your script use V1 and V2 API
    If by "my script" you're referring to evo-update.sh, then I am not the original author of the script, I just submitted a patch to the script to provide greater temperature resolution by querying measured temperature using the V1 API. All other data still comes from the V2 API.

    My changes are now in the official Domoticz evohome scripts over on this page:

    https://www.domoticz.com/wiki/Evohom...ller_or_RFG100

    Perhaps it would be an idea to just copy these versions of the script and try again. Also are you sure you have the correct username and password in evoconfig.py ?

    To test the script is connecting to the server and the username and password are correct you can just cd to the directory the script is in and run evo-update.sh manually.
    Last edited by DBMandrake; 11th December 2016 at 12:47 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •