Decoded - EvoHome API access to control remotely.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • bruce_miranda
    Automated Home Legend
    • Jul 2014
    • 2307

    Originally posted by bmccluskey View Post
    I want to add my thanks to everyone here for the really great work that has been done. If anyone is interested I have a couple of things that may be of use to others. 1. I have created a very simple python script that pulls the zone temperatures and set points and pushes them up to Emoncms.org for graphing, recording and monitoring. I use this site to also monitor my solar, electric and gas usage. The python is only a half dozen lines long and runs on a PI.

    The other thing that I have done is to translate the the backup and restore scripts to use only Windows Powershell. The only difference is that i output to a tab seperated file that can easily be opened in Excel. This lets me play with the setting in a nice easy format to copy schedules between zones etc and then re upload back into Evohome.
    Any chance we have have a look at both please. I too use emoncms.org. I have to log the temperatures and setpoints into different nodes but I use the Device Ids and the Key to tie the two up together.

    Would love to see how you do it. Also the windows scripts sound nice.

    Comment

    • bmccluskey
      Automated Home Lurker
      • May 2016
      • 5

      OK, Here is the python script I use to post up to EmonCMS.org I just use Cron on the PI to run it once every 5 mins. In this example I send all the details Temp and Setpoint to Node 3 (Change the node number in the line with the EMONCMSAPIKEY). I also remove all spaces in the zone names, but you could replace them with _ or similar if you prefer.

      Code:
      import urllib2
      from evohomeclient2 import EvohomeClient
      client = EvohomeClient('[B]EVOHOMEUSERNAME[/B]', '[B]EVOHOMEPASSWORD[/B]')
      posturl='http://emoncms.org/input/post.json?apikey=[B]EMONCMSAPIKEY[/B]&node=3&json={'
      for device in client.temperatures():
              posturl=posturl+','+device['name']+' Temp:'+str(device['temp'])
              posturl=posturl+','+device['name']+' SetPoint:'+str(device['setpoint'])
      
      posturl=posturl+ '}'
      posturl=posturl.replace("{,", "{")
      posturl=posturl.replace(" ", "")
      response = urllib2.urlopen(posturl)

      Comment

      • bruce_miranda
        Automated Home Legend
        • Jul 2014
        • 2307

        Would you please post your schedule download and upload scripts?

        Comment

        • bmccluskey
          Automated Home Lurker
          • May 2016
          • 5

          I was just doing a bt of a tidy up on them. Hopefully very simple. Save the code below into a file, im going to call it "EvoHome.ps1" for this example.

          Code:
          $UserName="[B]EVOHOMEUSERNAME[/B]"
          $Password="[B]EVOHOMEPASSWORD[/B]"
          $BaseURL="https://tccna.honeywell.com/WebAPI/emea/api/v1/"
          
          Function GetAccessToken
          {
              #Logon to the site and get the Access Token
          
              $url="https://tccna.honeywell.com/Auth/OAuth/Token"
          
              $postHeader = @{
                  "Authorization"="Basic YjAxM2FhMjYtOTcyNC00ZGJkLTg4OTctMDQ4YjlhYWRhMjQ5OnRlc3Q=";
                  "Accept"="application/json, application/xml, text/json, text/x-json, text/javascript, text/xml"
              }
          
              $postParams = @{
                  "Content-Type"="application/x-www-form-urlencoded; charset=utf-8";
                  "Host"="rs.alarmnet.com/";
                  "Cache-Control"="no-store no-cache";
                  "Pragma"="no-cache";
                  "grant_type"="password";
                  "scope"="EMEA-V1-Basic EMEA-V1-Anonymous EMEA-V1-Get-Current-User-Account";
                  "Username"=$UserName;
                  "Password"=$Password;
                  "Connection"="Keep-Alive"
              }
          
              $Result=Invoke-WebRequest -Uri $url -Method POST -Body $postParams -Headers $postHeader
              return (ConvertFrom-Json $Result.Content).access_token
          }
          
          
          Function GetRequest ($RequestURL)
          {
              $postHeader = @{
                  "Authorization"="bearer " + $AccessToken;
                  "applicationId"="b013aa26-9724-4dbd-8897-048b9aada249";
                  "Accept"="application/json, application/xml, text/json, text/x-json, text/javascript, text/xml"
              }
              $URL=$BaseURL+$RequestURL
              $Result=Invoke-WebRequest -Uri $URL -Headers $postHeader
              return ConvertFrom-Json $Result.Content
          }
          
          
          Function PutRequest ($RequestURL,$PutData)
          {
              $postHeader = @{
                  "Authorization"="bearer " + $AccessToken;
                  "applicationId"="b013aa26-9724-4dbd-8897-048b9aada249";
                  "Accept"="application/json, application/xml, text/json, text/x-json, text/javascript, text/xml"
              }
              $URL=$BaseURL+$RequestURL
              $Result=Invoke-RestMethod -Uri $URL -Method PUT -Body $PutData -Headers $postHeader -ContentType "application/json"
          }
          
          
          Function ExportSchedule ($Filename)
          {
              if ($Filename -eq $Null) {
                  $Date=Get-Date -UFormat "%Y%m%d%H%M"
                  $Filename="Schedule-$Date.csv"  
              }
              $OutputZones=@()
              foreach ($Zone in $ZonesStatus){
                  Write-Host "Exporting" $Zone.name
                  $ZoneId=$Zone.zoneId
                  $Output=$Output+$Zone.name+"`t"+$ZoneId+"`t"
          
                  $DailySchedules=GetRequest "temperatureZone/$ZoneId/schedule"
                  $Schedule=$DailySchedules.dailySchedules
          
                  $obj=new-object psobject
                  Add-Member -InputObject $obj -MemberType NoteProperty -Name ZoneName -Value $Zone.Name
                  Add-Member -InputObject $obj -MemberType NoteProperty -Name ZoneId -Value $ZoneId
                  for($i=0;$i -lt 7;$i++)
                  {
                      switch ($i) 
                      { 
                          0 {$Day="Mon"}
                          1 {$Day="Tue"} 
                          2 {$Day="Wed"} 
                          3 {$Day="Thu"} 
                          4 {$Day="Fri"} 
                          5 {$Day="Sat"} 
                          6 {$Day="Sun"} 
                      }
                      for($j=1;$j -lt 7;$j++)
                      {
                          Add-Member -InputObject $obj -MemberType NoteProperty -Name "$Day-$J-Temp" -Value $Schedule[$i].switchpoints[$j-1].temperature
                          Add-Member -InputObject $obj -MemberType NoteProperty -Name $Day-$J-Time -Value $Schedule[$i].switchpoints[$j-1].timeOfDay
                      }
                  } 
                  $OutputZones+=$obj
              }
              $OutputZones | sort-object -property zonename | export-csv -notype $Filename
          }
          
          
          Function ImportSchedule ($Filename)
          {
              if ($Filename -eq $Null) {
                  $Filename="Schedule.csv"  
              }
              $ImportZones=import-csv $Filename
              $ZoneArray=@()
              foreach ($Line in $ImportZones) {
                  $ZoneObj = New-Object System.Object
                  $ZoneObj | Add-Member -type NoteProperty -name ZoneId -Value $Line.ZoneId
                  $ZoneObj | Add-Member -type NoteProperty -name ZoneName -Value $Line.ZoneName
                  $DailySchedules=@()
                  for($i=0;$i -lt 7;$i++)
                  {
                      switch ($i) 
                      { 
                          0 {$Day="Mon"}
                          1 {$Day="Tue"} 
                          2 {$Day="Wed"} 
                          3 {$Day="Thu"} 
                          4 {$Day="Fri"} 
                          5 {$Day="Sat"} 
                          6 {$Day="Sun"} 
                      }
                      $SwitchPoints=@()
                      for($j=1;$j -lt 7;$j++)
                      {
                          if ($Line."$Day-$J-Temp" -ne "") {$SwitchPoints+=@{TargetTemperature=$Line."$Day-$J-Temp";TimeOfDay=$Line."$Day-$J-Time"}}
                      }
                      $DailySchedules+=@{DayOfWeek=$i;Switchpoints=$SwitchPoints}
                  }
                  $DailySchedules=@{DailySchedules=$DailySchedules}
                  $ZoneObj | Add-Member -type NoteProperty -name ZoneSchd -Value $DailySchedules
                  $ZoneArray+=$ZoneObj
              }
          
              foreach ($Zone in $ZoneArray){
                  $ScheduleJSON=ConvertTo-Json $Zone.ZoneSchd -Depth 10
                  $ZoneID=$Zone.ZoneId
                  write-host "Setting Schedule for" $Zone.ZoneId $Zone.ZoneName
                  PutRequest "temperatureZone/$ZoneId/schedule" $ScheduleJSON
              }
          }
          
          $AccessToken=GetAccessToken
          $UserDetails=GetRequest "userAccount"
          $UserId=$UserDetails.userId
          $Locations=GetRequest "location/installationInfo?userId=$UserId&includeTemperatureControlSystems=True"
          #assuming only 1
          $LocationInfo=$Locations[0].locationInfo
          $LocationId=$LocationInfo.locationId
          $GateWayInfo=$Locations[0].gateways.gatewayInfo
          $AllowedSystemModes=$Locations[0].gateways.temperatureControlSystems.allowedSystemModes
          $ZonesCapabilities=$Locations[0].gateways.temperatureControlSystems.zones
          $GateWays=GetRequest "location/$LocationId/status?includeTemperatureControlSystems=True"
          $HeatingSystem=$GateWays.gateways.temperatureControlSystems
          $GatewayActiveFaults=$GateWays.gateways.activeFaults
          $SystemId=$HeatingSystem.systemId
          $ZonesStatus=$HeatingSystem.zones
          $SystemActiveFaults=$HeatingSystem.activeFaults
          $SystemModeStatus=$HeatingSystem.systemModeStatus
          $SystemMode=$SystemModeStatus.mode
          There are some extra variables and stuff in there that I am still working on to extend the functionality. To use the script open a PowerShell Window then go to the folder where you saved the script.

          First of all we have to import the script. This connects to the site and gets all the details about your system.
          Code:
          import-module .\Evohome.ps1
          Then to backup the schedule simply type either ExportSchedule or ExportSchedule afilename.csv If you just run it without a filename it will call it Schedule-CurrentDateTime.csv
          Code:
          ExportSchedule
          The file is a simple CSV with headings included. It should just open in Excel. You can then make any changes you want, add more switch points, reduce switch points, change times, change set points etc. Just dont remove any of the column headings. You can have any number of zones in the file, you dont have to have them all, so you could have a a schedule file to control a couple of guest rooms without changing everything else.

          Once you want to import it simply type either ImportSchedule or ImportSchedule afilename.csv. If you dont type a filename it imports a file called Schedule.csv

          Code:
          ImportSchedule MySchedule.csv
          I havent included anything for Hotwater as I dont have the option but should be pretty easy to add.

          Let me know how you get on.

          Comment

          • bruce_miranda
            Automated Home Legend
            • Jul 2014
            • 2307

            This is great.

            I am not happy with the current ECO Quick Action. Regardless of what anyone says, I think 3C from current set-point is useless. I wanted to implement my own ECO functionality. It's very easily to do that on the current set points, but my-ECO would get messed up at the schedule changes. So what I was thinking of doing is downloading the entire schedule of set points for all zones and then reducing them by 0.5 - 2.5C and then uploading the entire schedule again.

            Comment

            • bmccluskey
              Automated Home Lurker
              • May 2016
              • 5

              That should work. My plan is to have a schedule for Summer and another for Winter.

              Another option for your scenario would be to write a a little function to change all zones by an amount so for example if we called it ChangeAllSetTemp we could do

              ChangeAllSetTemp +1.5

              or

              ChangeAllSetTemp -2.5

              If your interested in that approach let me know.

              Comment

              • bruce_miranda
                Automated Home Legend
                • Jul 2014
                • 2307

                That would be brilliant if you could alter all setpoints for all zones by -1C

                Comment

                • DBMandrake
                  Automated Home Legend
                  • Sep 2014
                  • 2361

                  Originally posted by bruce_miranda View Post
                  This is great.

                  I am not happy with the current ECO Quick Action. Regardless of what anyone says, I think 3C from current set-point is useless. I wanted to implement my own ECO functionality. It's very easily to do that on the current set points, but my-ECO would get messed up at the schedule changes. So what I was thinking of doing is downloading the entire schedule of set points for all zones and then reducing them by 0.5 - 2.5C and then uploading the entire schedule again.
                  I agree 3 degress is pretty useless - it's too great a jump in my opinion. A 1 or 2 degree setback would be more useful.

                  It also has a bug - despite not being documented anywhere, it won't set any zones back to lower than 15 degrees, worse still, in addition to that any zone that would be below 15 degrees after subtracting 3 degrees doesn't get changed at all! So a zone set to 18 will drop back to 15 degrees, but a zone set to 17 degrees stays at 17 degrees! Instead of a 17 degree zone also being reduced to 15 degrees, which is what I think they intended, even though it wasn't documented. Useless...
                  Last edited by DBMandrake; 31 May 2016, 03:51 PM.

                  Comment

                  • bmccluskey
                    Automated Home Lurker
                    • May 2016
                    • 5

                    Ok - Try this - Insert it into the evohome.ps1 file

                    Code:
                    Function ChangeZoneScheduleTemps ($Filter,$Diff)
                    {
                        if($Filter -eq "All"){
                            $ZoneList=$ZonesStatus
                        }
                        else {
                            $ZoneList=$ZonesStatus| where-object {$_.name -match $Filter}
                        }
                        foreach ($Zone in $ZoneList){
                            Write-Host "Changing" $Zone.name
                            $ZoneId=$Zone.zoneId
                            $DailySchedules=GetRequest "temperatureZone/$ZoneId/schedule"
                            $Schedule=$DailySchedules.dailySchedules
                            foreach ($Day in $Schedule){
                                foreach ($Switch in $Day.switchpoints){
                                    $Switch.temperature=$Switch.temperature+$Diff
                                }
                            }
                            $DailySchedules=@{DailySchedules=$Schedule}
                            $ScheduleJSON=ConvertTo-Json $DailySchedules -Depth 10
                            $ScheduleJSON=$ScheduleJSON -Replace "temperature","TargetTemperature"
                            PutRequest "temperatureZone/$ZoneId/schedule" $ScheduleJSON
                        }
                    }
                    To use the function there are two parameters. The first is a filter which can be something like "Bed" or "All", it is not case sensitive and it will look for the text anywhere in the zone name and you dont need quotes. So if you type Bed it will match "Bedroom 1" and "bedroom 2" and "The bedroom".
                    The second parameter is the amount you want to adjust, so to increase by 1.5 degrees just type 1.5, to decrease by 2.5 degrees type -2.5

                    Code:
                    ChangeZoneScheduleTemps All -1.5
                    ChangeZoneScheduleTemps Bed 2.5
                    Let me know how you get on.
                    Last edited by bmccluskey; 31 May 2016, 11:24 PM.

                    Comment

                    • bruce_miranda
                      Automated Home Legend
                      • Jul 2014
                      • 2307

                      That works a treat. Thank you.

                      Comment

                      • TonyAntique
                        Automated Home Lurker
                        • May 2016
                        • 2

                        More than one location.
                        This code seems great but I am getting the following error code:

                        Traceback (most recent call last):
                        File "EvohomeTemperature.py", line 48, in <module>
                        for device in client.temperatures():
                        File "C:\Program Files\Python27\lib\site-packages\evohomeclient2\__init__.py", line 124, in temperatures
                        return self._get_single_heating_system().temperatures()
                        File "C:\Program Files\Python27\lib\site-packages\evohomeclient2\__init__.py", line 35, in _get_single_heating_system
                        raise Exception("More than one location available")
                        Exception: More than one location available

                        I do have two units on my network as I have two boilers.
                        Is there a work around?

                        Comment

                        • MrB
                          Automated Home Sr Member
                          • Oct 2015
                          • 80

                          I read on a recent thread (can't find it now) about how the DHW reporting seems to be lagging. Check batteries and signal strength was mentioned.

                          Anyway - I had the same with my DWH graphing with big jumps in the reporting time frames. Been happening for a short while.

                          So I looked further and found the reported device data coming back on the API call (to get all the temps etc) was not always giving the entire device list. Sometimes only a couple of devices are returned out of 14 devices.

                          This is a new "feature" - can somebody else please check to see if they see the same.
                          Thanks.

                          Comment

                          • TonyAntique
                            Automated Home Lurker
                            • May 2016
                            • 2

                            I have managed to modify the code from watchforstock on 30th March 2014, 10:30 PM to show the measured temperatures and set point temperatures of all my zones by adding data from the code line <fullData = json.loads(response.content)[0]> and <fullData = json.loads(response.content)[1] together.

                            Unfortunately I cannot see how to do the same with the EvohomeTemperature.py code. I am only a rather basic python coder.

                            Any pointers would be appreciated.

                            Comment

                            • freeranger
                              Automated Home Jr Member
                              • Feb 2016
                              • 13

                              Evologger

                              Hey guys,

                              Standing on the shoulders of giants here, I have pulled together things I have learned in this thread and elsewhere and knocked up a python based app "evologger".
                              It is designed to be extensible and currently it supports the following:
                              - Reading actual and target radiator temps from EvoHome
                              - Reading the actual Hot Water temp from EvoHome - target temp is either a config.ini value when the HW is on or 0 when it is off
                              - Reading the outside temp from forecast.io

                              Writing to:
                              - csv - do what you like with this
                              - influxdb - which you can then hook up to grafana or similar
                              - plot.ly - though this is currently only plotting the actual temps - based on the EvohomeTemperature.py script
                              - emoncms - err... someone posted about this somewhere (here?) and I added it but I don't use it.

                              I started out with plot.ly and the script from around here but now I use influxdb + grafana so the others haven't really had any much love, but they do seem to work.

                              Anyway it's here if you want to play around with it - you may find it useful: https://github.com/freeranger/evologger

                              I am not a python programmer at all, so it is undoubtedly very rough so please take that into consideration!
                              I have tested it on a mac and a nitrous.io instance but it should be ok anywhere that supports python 2.7

                              Happy to accept any suggestions/PR's and I'll see what I can do when I have time.

                              It would be great if Honeywell made the documented API available publicly and made all features available through the API - there's so much more we could do with it!

                              Comment

                              • nieldm
                                Automated Home Jr Member
                                • Jun 2016
                                • 12

                                Possibly dumb nembie question

                                Hi all

                                This is a great resource, very many thanks to everyone who has spent so much time reverse engineering the protocol. Like so many others, I was pointed here by Honeywell, to whom I replied that this being 2016 and them having released the API for their security systems, with far more severe implications when exposed by poor programming, I can't understand why they won't release the Evohome API.

                                I am not a python programmer, but I do develop home automation systems on Crestron and have a great interest in developing a Crestron module for Evohome, initially for my own use given that my Evohome system was installed today!

                                Now to the dumb question. Do I need to register on the developer.honeywell.com website to get the required authorisations, or is it simply the "http://getconnected.honeywell.com/en/evohome" credentials? I see you pass username and password in most requests, but at the same time I see a Base64 encoded 'Authorization' parameter being passed so wondering where these came from.

                                ...and finally, I did try to find all this information here and on the github site but I might well have missed it. If so, please be kind.....it's wasn't due to lack of effort!

                                Many thanks again and kind regards
                                Marc

                                Comment

                                Working...
                                X