Decoded - EvoHome API access to control remotely.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • DBMandrake
    Automated Home Legend
    • Sep 2014
    • 2361

    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.

    Comment

    • DJBenson
      Automated Home Jr Member
      • Feb 2016
      • 24

      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; 1 November 2016, 03:41 PM.

      Comment

      • DBMandrake
        Automated Home Legend
        • Sep 2014
        • 2361

        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; 1 November 2016, 04:28 PM.

        Comment

        • stephenmhall
          Automated Home Lurker
          • Nov 2016
          • 1

          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?

          Comment

          • bruce_miranda
            Automated Home Legend
            • Jul 2014
            • 2307

            No it isnt

            Comment

            • Krejt
              Automated Home Jr Member
              • Jan 2016
              • 21

              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

              Comment

              • thtools
                Automated Home Lurker
                • Dec 2016
                • 6

                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

                Comment

                • DBMandrake
                  Automated Home Legend
                  • Sep 2014
                  • 2361

                  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; 10 December 2016, 08:49 PM.

                  Comment

                  • thtools
                    Automated Home Lurker
                    • Dec 2016
                    • 6

                    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!

                    Comment

                    • DBMandrake
                      Automated Home Legend
                      • Sep 2014
                      • 2361

                      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:

                      Python client to access the Evohome web service. Contribute to watchforstock/evohome-client development by creating an account on GitHub.


                      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:



                      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; 11 December 2016, 12:47 PM.

                      Comment

                      • thtools
                        Automated Home Lurker
                        • Dec 2016
                        • 6

                        Originally posted by DBMandrake View Post

                        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:

                        Python client to access the Evohome web service. Contribute to watchforstock/evohome-client development by creating an account on GitHub.


                        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.
                        I tried to query V2 API and it returned the error.
                        I proved that the version I used is the actual version from git-repository

                        This one is linked in the domoticz wiki as well.

                        Frustrating...

                        Tried to debug:

                        Code:
                        DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): tccna.honeywell.com
                        send: 'POST /Auth/OAuth/Token HTTP/1.1\r\nHost: tccna.honeywell.com\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml\r\nUser-Agent: python-requests/2.12.3\r\nAuthorization: Basic YjAxM2FhMjYtOTcyNC00ZGJkLTg4OTctMDQ4YjlhYWRhMjQ5OnRlc3Q=\r\nContent-Length: 306\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\nUsername=secret&Host=rs.alarmnet.com%2F&Password=verysecret&Pragma=no-cache&Cache-Control=no-store+no-cache&scope=EMEA-V1-Basic+EMEA-V1-Anonymous+EMEA-V1-Get-Current-User-Account&grant_type=password&Content-Type=application%2Fx-www-form-urlencoded%3B+charset%3Dutf-8&Connection=Keep-Alive'
                        reply: 'HTTP/1.1 200 OK\r\n'
                        header: Set-Cookie: tccna=R3709470637; path=/; expires=Mon, 12-Dec-2016 14:04:12 GMT
                        header: Cache-Control: no-cache
                        header: Pragma: no-cache
                        header: Content-Length: 1433
                        header: Content-Type: application/json;charset=UTF-8
                        header: Expires: -1
                        header: Server: Microsoft-IIS/8.5
                        header: X-Powered-By: ASP.NET
                        header: Server: Web1
                        header: Date: Sun, 11 Dec 2016 13:59:48 GMT
                        DEBUG:requests.packages.urllib3.connectionpool:https://tccna.honeywell.com:443 "POST /Auth/OAuth/Token HTTP/1.1" 200 1433
                        DEBUG:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): tccna.honeywell.com
                        send: 'GET /WebAPI/emea/api/v1/userAccount HTTP/1.1\r\nHost: tccna.honeywell.com\r\nConnection: keep-alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml\r\nUser-Agent: python-requests/2.12.3\r\napplicationId: b013aa26-9724-4dbd-8897-048b9aada249\r\nAuthorization: bearer AZqFqY0t8dVUzXN2QY13AxwWTuhB8VDEuyN3sz-41jeLSHGWw-HCNgPVH0ZfXOSvWOf2_uqKWMHYBn41F9TNQO8ld_intfBM7QsugBs1C0tDNOsz8oQHre2jJP6Bs1FVIlWlrLiUI2Bf5WvSlZ_MPAPb_znvVujEgtF3f3dWolMaVtb23eu3VAqRkNXgH7mdkaxuwrCYE7wvW1nmgMetkl3rkd3bCTfHYSufyC6DqnOFiN3xzWcq0McifxNpPvm8v8HJUIoJZyb1JNMznA0kouu8TaqVMeouc6bOrtL5OrPf4vmcJH8fWzAGnHlDHnL0F1CCxgFVm8ywgLglBRrUTHNhlxqfqtTsxkvlW-zaFNlJfdzljEjR2UTti4lBBRt8FVJEppuT2EQFn_oajO3onFKKJR1EmtzgdNPbQEdixJ0CtpBTufnQ4J264KG-WD1zLzVbCZ25uOg-jSUteq19jHh1rjuFmXlDlAGXfBkjd3qr_QazTafCtRsEauFugsRT7Ok2dqNfupMniRLpFm4HKJmVMJqYwrHI3vx-YnoxEfc3wNOpfYjvgWNaR7JsMdM8X9jxXkZS_JFugzjMo5BcUE5_qfsACt7LxK-X9QYC8odBeKdd0_rTcLvNUPZ_7yhrR4YA9g\r\n\r\n'
                        reply: 'HTTP/1.1 400 Bad Request\r\n'
                        header: Set-Cookie: tccna=R3709470637; path=/; expires=Mon, 12-Dec-2016 14:04:12 GMT
                        header: Cache-Control: no-cache
                        header: Pragma: no-cache
                        header: Content-Type: application/json; charset=utf-8
                        header: Expires: -1
                        header: Server: Microsoft-IIS/8.5
                        header: X-AspNet-Version: 4.0.30319
                        header: X-Powered-By: ASP.NET
                        header: Server: Web1
                        header: Date: Sun, 11 Dec 2016 13:59:48 GMT
                        header: Content-Length: 167
                        DEBUG:requests.packages.urllib3.connectionpool:https://tccna.honeywell.com:443 "GET /WebAPI/emea/api/v1/userAccount HTTP/1.1" 400 167
                        Traceback (most recent call last):
                          File "test.py", line 5, in <module>
                            client = EvohomeClient('secret', 'verysecret', debug=True)
                          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&includeTemperatureControlSystems=True' % self.account_info['userId'], headers=self.headers)
                        TypeError: list indices must be integers, not str
                        so there ist an error 400 (bad request)

                        any ideas?
                        Last edited by thtools; 11 December 2016, 03:06 PM.

                        Comment

                        • jzwack-honeywell
                          Automated Home Jr Member
                          • Jan 2016
                          • 36

                          I just tried the evohomeclient2 locally and it worked no problem.

                          Based on your logfile, it looks like the client couldn't get the "userId" number from GET /WebAPI/emea/api/v1/userAccount
                          developer.honeywell.com | I work for Honeywell. API Evangelist. Views are my own.

                          Comment

                          • DBMandrake
                            Automated Home Legend
                            • Sep 2014
                            • 2361

                            What version does 'python -V' report ? What operating system and platform are you running on ?

                            Also does your password have any unusual punctuation in it ? I wonder if the evohomeclient library doesn't correctly escape certain punctuation in passwords.

                            I notice that you have a different version of python-requests than me but other than that and the order of some of the HTTP headers I can't see any difference, so it might be worth temporarily changing to a more plain password (just letters and numbers) and seeing if it works then, as different usernames and passwords would be the main difference between your setup and my working one.
                            Last edited by DBMandrake; 12 December 2016, 10:47 PM.

                            Comment

                            • gordonb3
                              Automated Home Ninja
                              • Dec 2016
                              • 273

                              Hi all,

                              I like to start with a big thank you to all those that managed to figure out the protocol. I've been running the Domoticz scripts with the python evohome-client for quite some time but it became more and more of an annoyance that python is so heavy on resources. So I started out creating a C++ library for the methods. It's still a bit rough around the edges, but I did manage to create a first working application with it that combines all the functions of the Domoticz scripts.

                              I'm a bit puzzled at the moment however about what is version 2 API and what is version 1 API. The one I currently access uses URIs that start with /WebAPI/emea/api/v1/. Posts in this thread seem to indicate that this is the version 2 API. Is that correct? In my implementation I calculate the next scheduled switch point - I already did that in the python scripts - and on the Honeywell developer site I found an example output that already includes that information. I was hoping the other API which I figured to be the version 2 API but apparently is version 1(?) would supply me that output, but I can't seem to get any schedule information using that API.

                              Hope you guys can enlighten me. In the meantime if you're interested in checking out my project, it is here on GitHub

                              Comment

                              • DBMandrake
                                Automated Home Legend
                                • Sep 2014
                                • 2361

                                Originally posted by gordonb3 View Post
                                I'm a bit puzzled at the moment however about what is version 2 API and what is version 1 API. The one I currently access uses URIs that start with /WebAPI/emea/api/v1/. Posts in this thread seem to indicate that this is the version 2 API. Is that correct?
                                Yes that's correct. Looking at watchforstock's evohome-client python library this is the URL accessed for the "V2" API:



                                The older "V1" API uses:



                                So a bit confusing on the naming side - it is those of us here who have coined the API's as V1 and V2, or old and new API's - apparently honeywell considers the new version to be V1 which is confusing.

                                Basically the old API didn't support scheduling while the current newer API does support scheduling. Both API's are still available and have different but overlapping feature sets. In general the newer API is the best one to use - it supports reading and writing schedules and reading hotwater status, neither of which the old API does. The only advantage the old API has is that it provides measured temperatures to two decimal places whereas the V2 API rounds measured temperatures to the nearest half a degree then biases it towards the set point (same as the evotouch interface) so if you want accurate unmodified temperature readings you'll want to pull that from the older API. (The latest versions of the Domoticz evo-update.sh do that)
                                In my implementation I calculate the next scheduled switch point - I already did that in the python scripts - and on the Honeywell developer site I found an example output that already includes that information. I was hoping the other API which I figured to be the version 2 API but apparently is version 1(?) would supply me that output, but I can't seem to get any schedule information using that API.
                                Correct - the older API does not support scheduling information at all, only reading temperatures and performing manual overrides.

                                Comment

                                Working...
                                X