GeoffAtHome / genius-hub-home-assistant

Add support for genius hub (HeatGenius) to Home Assistant
4 stars 3 forks source link

Request: integrated folders #1

Closed zxdavb closed 5 years ago

zxdavb commented 5 years ago

Hi @GeoffAtHome !

I was just about to create a PyPi/HA pair for HG when I found your work. I would rather contribute to your repos than duplicate effort.

I have a bit of experience with HA with a similar system, so maybe I can help - you've probably discovered how strict they can be!

Custom components can 'evolve' faster, but I was wondering what plans you've got maintain this repo?

I am happy to submit a PR to reflect the new integrated folder structure, but I was wondering what other changes, if any, exist between this component and your HA PR.

GeoffAtHome commented 5 years ago

Hi @zxdavb ,

Thanks - I believe these changes will be accepted into the next build of HA: https://github.com/GeoffAtHome/home-assistant

The work is not complete as I really want to expose the time element. I.e. turn a switch on or boost the heat for a fixed period, as you can do with the HG app.

Would be great to collaborate than go it alone.

I am not great with Git so if I need to enable something for you to work on the same folk let me know.

Cheers, Geoff

zxdavb commented 5 years ago

Geoff, I'd be really keen to work of a custom_component version - I kinda gave up on official components after my water_heater fiasco (it was not the first fiasco), which is still ongoing...

What I found is: that ideas can be tested most quickly with the CC version, and those changes pushed up to HA in due course.

In addition, there are things that the CC version can do (i.e. break through HA limitations), that the the HA version can never do, but also also vice-versa.

One limitation I had was setting room temps for a set period of time...

Anyway, I have two GH installs (I don't live in either house, they're rentals), and I am personally interested mostly in monitoring more than anything else (e.g. issues, and DHW/Boiler temps), with alerting (via PushBullet in my case) when something goes wrong.

Would you accept PRs into this repo?

GeoffAtHome commented 5 years ago

@zxdavb Happy to accept PRs but you need maybe completely different to mine. The integration I have with HA is to use GH on the local network only. If you want to go over the public network you can either use the public API or use this. https://github.com/GeoffAtHome/HG-Mirror-V2

This can be tested here: https://geniusmirrorv2.firebaseapp.com

I am abandoning this project as HA is fit for my purposes.

A word of caution. Do not poll the hub to frequently as the GH app will stop functioning. Once every 5 seconds was too fast. I have settled on once every 20 seconds.

With HA the results are pushed into InfluxDB and can be view in Grafana. Automation via node-red is another possibility as are alerts in HA and Grafana - but if you are using PushBullet you probably know all this already.

zxdavb commented 5 years ago

No, each property has it's own local instance of HA, so I'll stick with this.

zxdavb commented 5 years ago

OK, submitted PR.

I can run it now, so will do some testing & let you know.

Woops - closed in error.

GeoffAtHome commented 5 years ago

Hi @zxdavb ,

Sorry for the delay in getting back to you. Quick glance looks like you have pulled out the work done to get this component in HA to a custom component.

I will need to take time to review but I have been stressed over buying a house. Will be a few days before things settle down but will keep you posted.

You mention about 'hot_water'. It should be straight forward to add more device types. I agree with you about the climate control as somewhat lacking. Either that or my understand. Still can get this to work directly from Alexa without some help for node-red.

Cheers, Geoff

zxdavb commented 5 years ago

@GeoffAtHome

If you like, let me knock up the hot_water thing - will be good practice for me - you can concentrate on your house.

However, I really wanted to raise an issue for you to consider before heaps of people start using your two geniushub repositories:

  1. geniushub-client this is the PyPi package that sits between the hub itself, and consumers such as HA (which will need an integration/component for that) - I've gotten into the habit of calling these pieces of code the 'client library'
  2. geniushub-for-ha the HA integration (used to be called a component/custom_component) that HA uses to talk to the client library

A lot of my thinking is coloured by my experience with the evohome client library (which I've contributed to extensively), and the HA integration for evohome (which I wrote).

To avoid confusion, I would rename the repo for the client library (1) as above. "geniushub-client" is pretty descriptive, and will avoid confusion going forward. In PyPi, the convention would be geniushubclient.

Another issue: Looking at the client library, it seems to have been 'tailored' for HA. I think this is a real mistake, as it will be used (we hope) by other home automation platforms. Simply, the client API should be completely platform-agnostic.

Instead, it is the job of the HA component (2) to abstract the client to HA.

I think the 'distance' between the client library schema and actual geniushub schema should be absolutely minimal. That is:

hub --> zones --> devices | channels (maybe channels can be left until later)
hub --> devices --> channels

An example in your client library of not being agnostic is where fPV becomes current_temperature rather than temperature. This will confuse those who may use the HeatGenius APIs (via, say, curl) to check/debug the client library.

The approach I was taking was to use the v3 API to return JSON that looked (where possible) exactly the same as the v1 API. So I changed keys as follows:

MAPPING= {
    "id": "iID",
    "name": "strName",
    "type": "iType",
    "mode": "iMode",
    "temperature": "fPV",
    "setpoint": "fSP"
}

I was intending to provide an option to return raw (unmapped) JSON if requested.

Regarding getClimateList, I think it's OK: it is slightly non-agnostic (Climate is a HA construct), but represents a useful subset of Zones; although strictly, it should be getRadiatorList().

Going down this route will require a re-write of the HA component too...

What do you think?

GeoffAtHome commented 5 years ago

The library has been tailored specifically for undocumented V3 GH calls and HA. It is part of creating a MVP that works. I could spend time writing services that may or may not be consumed. If there is a use case for additional service, then happy for someone to extend what is there.

The repository geniushub could be refactored. A component could be made that does the pure communication with GH and simply gets and posts JSON to the GH and maintains the current state of the hub.

A second component could broker the JSON and make it fit for purpose for HA to consume. That said, for the various things I have written for GH I have always wanted a list of zones and devices and from these lists identify switches, TRVs and sensors.

To get the unfettered raw JSON is would be a useful API for those that want to do their own thing. This is essential how I started and what getAllZones does. Unless you are thinking there is a need to get the full raw JSON and not just the ['data'] node?

Maybe provide getRawJSON(). getAllZones() could be renamed getJSONData() or getDataJSON() which makes a call to GetRawJSON()? May getRaw() and getData() is better as we should know that it is JSON.

Maybe that should be all the geniushub should do. I.e. Create the connection with to the GH and set up a polling loop. At time getjson and postjson can be called.

Enough ramblings. Do you want to adopt this projects? I am happy to make you the owner or join owner if that is possible.

I need to sort out council tax, energy supplier, ISP........ the joys of buying a new house.

zxdavb commented 5 years ago

I need to sort out council tax, energy supplier, ISP........ the joys of buying a new house.

About 2 years ago I moved house six times in less than 12 months (I have two small kids/two cats) - it was hell, so you have my sympathies,

The library has been tailored specifically for undocumented V3 GH calls and HA.

I would like to see a geniushub-client library that is HA agnostic, for the benefit of the wider community. I don't want to split our efforts, though.

I would be pleased to 'adopt' the repo if you're willing, but I'd want it to become 'stable' before progressing to an official HA integration. However, there'd be the existing MVP/custom component (which is working well for me, at least) to use In the meantime (and, TBH, it'd nearly be Summer by then).

BTW, do you know you can do the following:

REQUIREMENTS = ['https://github.com/USER/REPO/archive/BRANCH.zip#geniushubclient==0.1']

If I took over the repo, what would you expect from me? I wouldn't want to take it on, and then go off in a direction you're not happy with.

My plans were for a CLI wrapper with an agnostic client library, returning JSON as close as possible to v1 api, extending to a sympathetic superset of that, but with the ultimate option of raw JSON (all of it).

It should work with either a) hub tokens (i.e. use the v1 api, but return only v1 JSON), or b) speak directly with the hub itself. I expect b) to work over a reverse proxy or through a firewall (I have two investment properties using HG, I think this is a common use-case).

A second component could broker the JSON and make it fit for purpose for HA to consume.

I think the HA component could handle just about anything (even the raw JSON, although the client library should reasonably be expected to do some of this heavy lifting, as discussed previously).

For example, my Honeywell evohome component pulls all zone data (the equivalent of the superset of ['data']) as one large JSON object (i.e. only the 'hub' is doing I/O), and it then sends the zones a message when that updated data is available (via hass.data[GENIUS_HUB).

Maybe provide getRawJSON()...

I think getRawJSON() & getAllZones(), and also getAllDevices() & getHub() and I like your idea of filtering for the Zones/Devices.

zxdavb commented 5 years ago

I think it really all boils down to providing the best PyPi package we can. The goal would be to have only the one package (I vote geniushub-client) with a few changes ASAP, and the rest can comes in time...

In that sense, your client library is 90% there.

So let's put a hold on the HA component - people can use the custom component for now (with the existing library downloaded from github, as above), I can add custom_updater to the custom component to ease the way for any users.

Let me know your thoughts.

GeoffAtHome commented 5 years ago

The component is getting integrated into HA. Once this is done I will abandon this pre-cursor to getting it built into HA.

I will refactor geniushub to become geniushub-client which will be lighter weight and geniushub_ha which will contain all the HA specific code. The API signatures will not change to avoid breaking functionality.

I need GH to work on local network. Using the public API provide by HG, while straightforward, is not my intention. At the moment, I cannot see a good path forward to encompass both, but do not see why this is not possible.

zxdavb commented 5 years ago

Hey Geoff, that's great.

I am looking forward to sending off some PRs for you to consider.

I thought giving the option of calling the v1 API offered a few useful advantages, one being it is guaranteed to not change (a guarantee that doesn't exist for v3), but also to provide a counterpoint to my goal of having v3 calls return JSON that is identical - as much as practical - to v1.

That is, I could just execute the same command, but use v1 instead of v3 and then compare the two outputs - it was very useful. I did this by providing a CLI wrapper for my library:

python ghclient.py ${HUB_ADDRESS} -u ${USERNAME} -p ${PASSWORD} zones -vvv
python ghclient.py ${HUB_TOKEN} zones -vvv

The whole idea was to emulate the v1 api, but by using v3 calls.

The API signatures will not change to avoid breaking functionality.

Sensible. evohome-client crossed this bridge (although there was a little more to it than that) by having a v1 and a v2 of the library.

Any client using geniushub would have to be refactored in any case to use geniushub-client, so is there no chance you can do that before HA rolls over? - it is only a change to the REQUIREMENTS statement.

-Dave

GeoffAtHome commented 5 years ago

@zxdavb Just started to look at doing the refactoring. Do you know if packages can be renamed on pypi.org? Looks to me a new package may need to be created - not ideal but open to suggestions.

zxdavb commented 5 years ago

I don't think you can - I was about to create geniushub-client when I noticed your package! :)

GeoffAtHome commented 5 years ago

That's the conclusion I can too. I guess we can abandon this and point people at the new one.

I was going to refactor the work as follow: geniushub-client: init creates the connection to the hub and starts the polling and includes all the utility functions to make that work. It will also expose getData() which returns the current status as read from the hub and setData() - functionality the same as fetch().

geniushub_utilities: imports geniushub_client and provides non-HA utility functions such as getSensorList(), getTRVList() etc.

geniushub_homeassistant: imports geniushub_utilites and provide the HA specific functionality. I.e. getClimate, getSwitch, getSensor, getTRV

Comments?

zxdavb commented 5 years ago

I am putting the kids to bed now, but the main must-have would be a 'copy' of the v1 API.

Do you wanna have a look at https://github.com/zxdavb/geniushub-myclient and we can chat about it later?

GeoffAtHome commented 5 years ago

Chatting sounds good but not this evening. Tomorrow will work for me but the rest of the week I am busy. Skype, Hangouts, WhatsApp, Messenger or good old phone?

zxdavb commented 5 years ago

WhatsApp!

I think there is no need to go beyond emulating the v1 API

As I said before, I put a CLI wrapper in the library, which adds flexibility, and allows v1 to be compared with v3 (the output is identical):

(venv) dbonnes@vm-builder:~/client_apis/geniushub-myclient$ python ghclient.py ${HUB_ADDRESS} -u ${USERNAME} -p ${PASSWORD} zones
[{'id': 0, 'name': '32 Clift road'}, {'id': 1, 'name': 'Room 1.1'}, {'id': 2, 'name': 'Room 1.2'}, {'id': 3, 'name': 'Room 2.3'}, {'id': 4, 'name': 'Room 2.1'}, {'id': 5, 'name': 'Room 2.2'}, {'id': 6, 'name': 'Boiler H/W'}, {'id': 7, 'name': 'Immersion H/W'}, {'id': 8, 'name': 'Upstairs hall'}, {'id': 10, 'name': 'Bathrooms'}, {'id': 11, 'name': 'WiFi Repeater'}, {'id': 12, 'name': 'Kitchen'}]

(venv) dbonnes@vm-builder:~/client_apis/geniushub-myclient$ python ghclient.py ${HUB_TOKEN} zones
[{'id': 0, 'name': '32 Clift road'}, {'id': 1, 'name': 'Room 1.1'}, {'id': 2, 'name': 'Room 1.2'}, {'id': 3, 'name': 'Room 2.3'}, {'id': 4, 'name': 'Room 2.1'}, {'id': 5, 'name': 'Room 2.2'}, {'id': 6, 'name': 'Boiler H/W'}, {'id': 7, 'name': 'Immersion H/W'}, {'id': 8, 'name': 'Upstairs hall'}, {'id': 10, 'name': 'Bathrooms'}, {'id': 11, 'name': 'WiFi Repeater'}, {'id': 12, 'name': 'Kitchen'}]

(venv) dbonnes@vm-builder:~/client_apis/geniushub-myclient$ curl -X GET https://my.geniushub.co.uk/v1/zones/summary -H "authorization: Bearer ${HUB_TOKEN}"
[{"id":0,"name":"32 Clift road"},{"id":1,"name":"Room 1.1"},{"id":2,"name":"Room 1.2"},{"id":3,"name":"Room 2.3"},{"id":4,"name":"Room 2.1"},{"id":5,"name":"Room 2.2"},{"id":6,"name":"Boiler H/W"},{"id":7,"name":"Immersion H/W"},{"id":8,"name":"Upstairs hall"},{"id":10,"name":"Bathrooms"},{"id":11,"name":"WiFi Repeater"},{"id":12,"name":"Kitchen"}]