Closed TooUnCool closed 8 years ago
Hi Marc
If you looked at my code (or my disclaimer!) you'd know I'm not a python programmer either :)
I am resting on the shoulders of giants here, using https://github.com/watchforstock/evohome-client to handle all the communications to EvoHome, and it is that which is politely telling you there is more than one location :)
It looks like I could access some lower level, essentially internal, methods to be able to deal with multiple locations - though it is generally bad practice to access the internals of a component as in theory they could change at any time....but hey ho, this is all unofficial stuff anyway...
I don't have multiple locations so I'm not entirely sure what the result looks like coming back from EvoHome - would you be able to provide me with the result of the call to the EvoHome service so I can see what it's like?
In your local copy of the evohome client (which you had to install for my stuff to work, in here: https://github.com/watchforstock/evohome-client/blob/master/evohomeclient2/__init__.py
just after line 86:
r = requests.get('https://tccna.honeywell.com/WebAPI/emea/api/v1/location/installationInfo?userId=%s&includeTemperatureControlSystems=True' % self.account_info['userId'], headers=self.headers)
could you send me the output of r.text? If you can't step into the code (I have no idea how!) then you could write it to the console or raise an error to get the text displayed and then paste it in here so I can fake it and see if I can write something to deal with it.
I'm thinking that my software could have an additional parameter to specify which location you are interested in - so it is still only supporting one EvoHome (for now anyway) but at least it would work in your scenario - multiple locations with the software running separately at each location.
Obviously ideally you would be able to have all locations running from the same instance but that's much further away....if I'd written this in C# (which means I would have to have engineered my own EvoClient too) then it would be trivial for me to mock up and test each scenario, but I have limited bandwidth for this sort of thing unfortunately :/
Meanwhile, I will raise an issue with the evo client guy to see if he will support multiple locations without the need to access internal/private methods....
I can do that using Postman, which is how I taught myself the use of the API.....pasted below. I am thinking that maybe passing the locationId as a parameter might be the path of least resistance? I don't think it's beyond the wit of man to create a list in Python to the effect of (I am not a programmer, full stop....you are Woz compared to me!) :
for i in range (len(r.json())): location.append(r.json()[i]['locationInfo']['locationId'])
....but clearly there is a lot more to it. It looks like watchforstock "goes there" on lines 32-35 but says, effectively "can't be a$$ed with an array" and kicks you out! I am more than happy to chew through this myself, I wasn't asking you to start cutting code, but you are a lot more experienced than I with the Evohome api.
Best Marc
[
{
"locationInfo": {
"locationId": "1631734",
"name": "London",
"streetAddress": "street",
"city": "London",
"country": "UnitedKingdom",
"postcode": "123456",
"locationType": "Residential",
"useDaylightSaveSwitching": true,
"timeZone": {
"timeZoneId": "GMTStandardTime",
"displayName": "(UTC) Dublin, Edinburgh, Lisbon, London",
"offsetMinutes": 0,
"currentOffsetMinutes": 60,
"supportsDaylightSaving": true
},
"locationOwner": {
"userId": "1372761",
"username": "email address",
"firstname": "My",
"lastname": "Name"
}
},
"gateways": [
{
"gatewayInfo": {
"gatewayId": "1501298",
"mac": "00D02D93E003",
"crc": "ECA7",
"isWiFi": false
},
"temperatureControlSystems": [
{
"systemId": "1808089",
"modelType": "EvoTouch",
"zones": [
{
"zoneId": "1808088",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 25,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Living Room",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1809610",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Spare Bed",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1809611",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Kitchen",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1809612",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Master Bed",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1809613",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Office",
"zoneType": "ZoneTemperatureControl"
}
],
"dhw": {
"dhwId": "1809741",
"dhwStateCapabilitiesResponse": {
"allowedStates": [
"On",
"Off"
],
"allowedModes": [
"FollowSchedule",
"PermanentOverride",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilitiesResponse": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00"
}
},
"allowedSystemModes": [
{
"systemMode": "Auto",
"canBePermanent": true,
"canBeTemporary": false
},
{
"systemMode": "AutoWithEco",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "1.00:00:00",
"timingResolution": "01:00:00",
"timingMode": "Duration"
},
{
"systemMode": "AutoWithReset",
"canBePermanent": true,
"canBeTemporary": false
},
{
"systemMode": "Away",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "99.00:00:00",
"timingResolution": "1.00:00:00",
"timingMode": "Period"
},
{
"systemMode": "DayOff",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "99.00:00:00",
"timingResolution": "1.00:00:00",
"timingMode": "Period"
},
{
"systemMode": "HeatingOff",
"canBePermanent": true,
"canBeTemporary": false
},
{
"systemMode": "Custom",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "99.00:00:00",
"timingResolution": "1.00:00:00",
"timingMode": "Period"
}
]
}
]
}
]
},
{
"locationInfo": {
"locationId": "1789953",
"name": "Ling",
"streetAddress": "another street",
"city": "another town",
"country": "UnitedKingdom",
"postcode": "a different postcode",
"locationType": "Residential",
"useDaylightSaveSwitching": true,
"timeZone": {
"timeZoneId": "GMTStandardTime",
"displayName": "(UTC) Dublin, Edinburgh, Lisbon, London",
"offsetMinutes": 0,
"currentOffsetMinutes": 60,
"supportsDaylightSaving": true
},
"locationOwner": {
"userId": "1372761",
"username": "email address",
"firstname": "My",
"lastname": "Name"
}
},
"gateways": [
{
"gatewayInfo": {
"gatewayId": "1658207",
"mac": "00D02D93DF09",
"crc": "FE23",
"isWiFi": false
},
"temperatureControlSystems": [
{
"systemId": "1990311",
"modelType": "EvoTouch",
"zones": [
{
"zoneId": "1990303",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Living Room Ling",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1990304",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Music Room",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1990305",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Kitchen Ling",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1990306",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Master Bed Ling",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1990307",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Sewing room",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1990308",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Utility",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1990309",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Spare Bed Ling",
"zoneType": "ZoneTemperatureControl"
},
{
"zoneId": "1990310",
"modelType": "HeatingZone",
"heatSetpointCapabilities": {
"maxHeatSetpoint": 35,
"minHeatSetpoint": 5,
"valueResolution": 0.5,
"allowedSetpointModes": [
"PermanentOverride",
"FollowSchedule",
"TemporaryOverride"
],
"maxDuration": "1.00:00:00",
"timingResolution": "00:10:00"
},
"scheduleCapabilities": {
"maxSwitchpointsPerDay": 6,
"minSwitchpointsPerDay": 1,
"timingResolution": "00:10:00",
"setpointValueResolution": 0.5
},
"name": "Hall",
"zoneType": "ZoneTemperatureControl"
}
],
"allowedSystemModes": [
{
"systemMode": "Auto",
"canBePermanent": true,
"canBeTemporary": false
},
{
"systemMode": "AutoWithEco",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "1.00:00:00",
"timingResolution": "01:00:00",
"timingMode": "Duration"
},
{
"systemMode": "AutoWithReset",
"canBePermanent": true,
"canBeTemporary": false
},
{
"systemMode": "Away",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "99.00:00:00",
"timingResolution": "1.00:00:00",
"timingMode": "Period"
},
{
"systemMode": "DayOff",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "99.00:00:00",
"timingResolution": "1.00:00:00",
"timingMode": "Period"
},
{
"systemMode": "HeatingOff",
"canBePermanent": true,
"canBeTemporary": false
},
{
"systemMode": "Custom",
"canBePermanent": true,
"canBeTemporary": true,
"maxDuration": "99.00:00:00",
"timingResolution": "1.00:00:00",
"timingMode": "Period"
}
]
}
]
}
]
}
]
Great, thanks - just edited it to make the code more readable :)
Yes the watchforstocks code is certainly aware of multiple locations (I don't know where multiple gateways etc come into it or multiple control systems within each gateway - maybe these aren't really relevant for EvoHome and maybe just for their other smart home offering (can't remember the name) or when you add in the security system etc...
I have raised an issue with watchforstocks to see if he will support multiple zones natively but I will still explore this further and see if I can maybe extend the client myself (or at least abstract away somewhere the nastiness of calling private methods).
I presume location name has to be unique, so using that rather than locationId would be a bit more "user friendly" in terms of configuring the app for the location you are interested in monitoring - if nothing else, it eliminates the problem of having to figure out what the location id actually is!
I'm a bit swamped at the moment so no promises but ping me back if I haven't done something in the next week or two...
I agree with you that passing the location name would be more user friendly, but I actually don't think the name does need to be unique. A quick test reveals that it doesn't stop me making them both the same and Postman still throws out the json, although I am not brave enough to test further with my wife up at the second location needing heating!
As I said, I have no expectation that you go to the trouble of changing code and I might continue to tinker myself over the weekend. All I am really interested in at this stage is being able to automate the setting of the Away and Auto modes, triggered by setting or disarming the security system in one or the other location, I am fine with the controller or apps (or my new Echo!) for setting/changing temperatures.
I started looking at your code as I wanted to see how you called the various functions in watchforstock's code to avoid me having to rebuild it all in the language of my home automation environment. Interestingly, said environment only supports https via C# and the newer controllers, I have an older controller so was looking at your code along with watchforstock's, trying to work out how to grab the token - https is only necessary for the authorisation step.
Anyhow...thank you for even looking at it, it's very much appreciated.
Marc
C# is my language of choice, but I would have had to re-implement watchforstock's code in that too, hence it seemed "simpler" to learn a bit of python than to go that route :) A long, long term goal is to actually control it but I can't see me finding the time for that any time soon - hence this is evologger, not evocontroller :)
Your comment - "said environment only supports https via C#" seems a bit odd to me as the language you use shouldn't matter when making these calls - http/https is language-agnostic after all.
That's annoying that the name doesn't have to be unique :/ I'd still prefer to use it so maybe the logic is:
Possibly with warnings where more than one location is found with the same name (but it still works) If necessary could go with the same sort of logic for control systems/gateways though wary of adding code for a situation that may not arise (ie multiple of either of these). I do wish Honeywell would make the API spec public :/
re: Echo - missed out on the Amazon Prime £99 deal for it and don't know yet how much I will use it - £149 is a bit much for an impulse buy for me :} So have ordered the dot to see how I get on with that. Mrs freeranger seems unable to set the temp at the moment so being able to say "turn the heating up in the lounge by 3 degrees" would seem ideal. I understand the evohome stuff for it is very basic at the moment but hopefully they will expand it over time....
I can't currently see why I will use echo/dot beyond that at the moment but it may surprise me :)
Re my comments around C# and https, I wasn't at all clear.
I say 'only supports C#"; what the language actually is is this "https://www.crestron.com/products/model/SW-SIMPL-SHARP/-PRO", a modified version of C# that integrates with Crestron's proprietary development tools via their custom libraries. It is used when someone needs to build custom integration beyond the capabilities of those tools or when it is just easier. The trouble is, the above language doesn't run on the 2-series Crestron processors and it's the firmware on those processors that doesn't support https. Rather than attempt to persuade Mrs Uncool that shelling out the silly money for a 3-series processor is money well spent, I am trying to integrate Evohome via 'middleware'...and here I am. My choices are either, use an external programme to return all the data I need (say, location name and status) and send changes back to that utility and allow to do the heavy lifting, or return the token from the utility and develop the rest using the Crestron language the 2-series supports. I can send and receive commands between a TCP server running on the processor and a Python shell set to "listen" and can get the token back after working out how to build a little Python programme (cut paste from watchforstock's init.py basically) so it's probably easier to roll my own from here, but piggybacking on all the great work you and others are doing also has a lot of appeal......clear as mud I know.
The Echo is cool, check out Home Assistant and haaska - https://github.com/auchter/haaska), the latter being a custom Lambda utility that let's you build custom skills. Or ha-bridge https://github.com/bwssystems/ha-bridge, which is pure Alexa middleware. I strongly suspect you will find plenty of ways of entertaining yourself and making Lady freeranger's life simpler!
Ah got you now - Visual Studio® 2008 - I see they are staying current :)
If you prefer to go the C# route then I have just found these: https://github.com/paul-777/Evohome.Net https://github.com/leonmeijer/EvoHome.NET
hmm...might have to consider converting evologger to .NET after all..
Thanks for the Echo links!
Hey Marc,
So this was preying on my mind and I have pushed a commit now which should support multiple locations - by default the first location will be selected, or you can add a location=
Let me know if it works for you and I will close this issue.
Hi and apologies for the delay in replying, I was mercifully away from "devices" for a few days!
This works perfectly, very many thanks. I kind of suspected it might niggle at you, i know that sort of thing would do so at me!
Marc
No problem m8, glad it all works for you now - closing this issue.
Hi As I start to play around with the (rather excellent) software and at the risk of seriously pushing my luck, something occurs to me. My specific use case is due to the fact that my wife and I wander between two houses, one in central London, the other in nowheresville. What I am trying to achieve is the option of setting the Away mode whilst leaving one location and optionally (depending on where we are headed) setting the other location to Auto. I will do this as part of a general "leaving home" set of actions (arm security, turn stuff off that I forgot to turn off etc) on a touch panel. The above, of course, means that data from both locations needs to be "active" at the same time, not something I can achieve when I specify a single location in the config.ini. Now, for the avoidance of doubt this is categorically not an enhancement request, I can work around this without too much hassle. Simply that, were you to have the software open for surgery at any time in the future, making it truly multi-location might be a cool thing to add to the list? Thank you once again for for software and for the enhancement, it is really appreciated. Best regardsMarc
On Tue, Oct 18, 2016 at 12:58 PM +0100, "freeranger" notifications@github.com wrote:
No problem m8, glad it all works for you now - closing this issue.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
Hi,
I don't really see how it would work well for two locations - what do you do about name conflicts for zone? How do you differentiate between the configuration for one zone vs another? What if you want to log each location to a different file or different database or different [anything else]?
I'm not sure there is a sensible solution to that which doesn't detract from the simple, common use case?
The simplest solution for you is to run the app from two different locations, with slightly different config files. You can choose to have them logging to the same influxes or emoncms or plotly just by using the same configuration info in both files. I can't imagine that the setup changes very often that doing this would be onerous....
I have Evohome in two locations, so per expected behaviour your very cool piece of software politely tells me there is more than one location and stops!
Do you have any recommendations how I can handle this? I don't really need data for both locations and if i use the software it will be installed on separate Pis in each location. I am happy to let it think there is only one location if that is possible. Attempting to modify a local version of your code is clearly an option (although I am a novice Python programmer), but I thought I would ask you first if you had given any thought to it.
Marc