sander76/aio-powerview-api

Hub v3 support?

Closed this issue · 39 comments

Is there any chance of this being updated to support the newer API that Hub v3 uses or should I start looking to implement that on my own? I know it would probably be a rather large update which is why I ask.

I don't think any of the maintainers have a v3 hub so its probably something we would need a PR to support

My Python isn't the greatest (C# is my daily language) but I'm going to be digging into this one way or the other as I want my shades working properly with HASS and the HomeKit connection is crap (keeps failing).

I don't mind submitting work back to here but it seems to me it would be a difficult implementation in the current structure as the API is entirely different. We would need a way to essentially version the API used so that existing v1 and v2 devices used the current layout and v3 ones used the new layout.

I haven’t had a chance to look at this yet but the developers from OpenHAB managed to get in touch with someone from Hunter Douglas who has been extremely helpful.

You are correct, there is a bit of work to do to make it work but I have an idea of what needs to be done with minimal impact.

As @bdraco mentioned we lack a v3 hub so if you have the capacity to spin up a Dev environment I can supply you with some updated code (not now when it is ready) so we can test it all out.

ideally we make 99% of the changes here and HA just works (translate the HA commands to their relative call in this API) - I believe I will need to make one change in the HA side but it is minimal.

If you can give me a bit of time it is in the pipeline at least

Just wanted to ping back in on this given more questions popping up in the HA forums.

What I've personally done right now is setup Node RED flows that let me simply open and close the blinds using the new API and then attached those to HA switches. Not the best long term setup but it works for now.

That said a lot of other people might not have that technical ability so if there is anything I can do to help you on this issue just ping me at any time.

I've been watching this as an interested party, fortunately the API support in PV3 is amazing. The Hub has a swagger server that documents the API and lets you poke at it to try things. I've been able to manipulate my blinds just from their swagger server.

Having the units I might be able to offer some time to help, I think the kids are starting to entertain themselves more these days, but I'd appreciate if one of the maintainers could give me a brief walk through so I can ensure my understanding is correct and briefly strategize best direction to support both versions of the API. I just spent 10 minutes going through the code, I think I see how it works but there's some assumptions I'd want to validate which are probably easier with a brief call than async messaging.

But this library looks fantastic, I don't think it'd be too difficult to extend it to the new API. Thanks.

i did start on this but then the api doco we had shared from HD went offline - i too am hoping it doesnt take too much to implement here and we would want all the changes made here (in the upstream api) where possible and only update HA where required.
HA will need some minimal changes but ideally this API continues to handle the current HA calls and manipulate for the hub as required (in order to support gen1, gen2 and gen3 hubs)

If you can provide a yaml export of the swagger that would be immensly helpful - hell i would take a pdf export with all fields open at this stage 😄
But ultimately it would be heaps easier to have access to gen3 hub for testing detection of both gen2 and gen3 at once.

If you are willing to expose the hub to the internet, either via Port forwarding or VPN you're welcome to hit me up via PM on the HA forum (same username) to keep that info personal

No idea of how to get a YAML export but if you know how let me know. But simply saving it as a local HTML file seems to be relatively complete and self contained from some quick tests (except the favicon but who cares)
Swagger UI.zip

There are a few tools to export available online but I’ve never personally used any of them

the file you provided likely looks to be working as it is all local to your network, but I cannot expand any of the endpoints

I have one other system using swagger in my network which I could try and work this out with - the only other option I’ve tested quickly (which provides some needed info) is an extension of what you did

before saving you need to open all the end points and their sub items (put post etc) then when you save as html select mhtml as the file type - this includes all the cached metadata

this could be extremely tedious so some of the key endpoints focus with would be identifying the gateway, getting and setting shade pos. Getting and calling scenes

I’ll have a look at how to export the whole thing, hopefully it has some example return there too

Think I found what I need from you.

fell free to see what you can find too (on how to export for work offline)

I have been able to get the JSON from my swagger through this method - could you provide that ?
These are from chrome, others will be similar

  1. Navigate to your Swagger docs endpoint
  2. Open the browser developer console (usually F12)
  3. Refresh the page
  4. Navigate to the network tab and filter by XHR requests (In chrome this is Fetch/XHR)
  5. Right click on the XHR request that mathes the keyword openapi
  6. Select Copy Response
  7. JSON should now be on the clipboard

I had tried that actually originally but couldn't see anything being sent except the html and some js

image

This is the best I can do for now but I'll keep digging:
HDPowerView3_API_Dump.pdf

Also here is that .mhtml
Swagger UI.zip

thanks - ill take a look at the mhtml in the morning - to check if any of those responses have json return you can select them and then go to the reposnse tab - it should start with curly braces
image

Ok I got it figured out. Had to dive through the JS files. Here is the YAML. FYI if you open this in openapi it WILL throiw a bunch of errors due to inverted values. This is apparently correct in the API so just hide the error box and you should see the API
hunterdouglas-Powerview3-openapi.zip

One thing to be aware of which I haven't figured out yet is how to handle multi-hub setups. I don't if this is a problem in v2 or if you have already solved it, but it is something I am running into in my v3 home which has 2 hubs. The /home/ commands must be sent to the "primary" hub or else it will return an error.

{"errMsg":"Multi-Gateway environment - this is not the primary gateway"}

However the primary hub can seemingly change at random. Some days it has just changed on me. So for now my flows broadcast the command to BOTH hub IPs so that one will error but one will process it. Something more elegant may be possible though.

Yeah I was just coming to report the same, this is one f'ed up swagger viewer. It jams the spec in a giant variable in this javascript file. Wow. Anhow, it looks like someone has given you the details, let me know if there's anything else I can do to help. I'm still willing to collaborate if you need it, I haven't gotten too rusty with my coding. :D

Screenshot from 2022-11-13 16-15-22

I recently had gen 3 blinds installed, and I am also interested in getting them working with HA. @kingy444 were you able to make any progress with the OpenAPI spec? I am happy to help with either the coding or testing. It's been a while since I wrote any python (and I have never done any python aio before), but more than happy to work through it and collaborate on a branch if you're open to it.

Besides the API changes, what was most interesting to see in the latest spec was support for events (SSE). With this, the HA integration can be improved to also support local push.

Additional info from my side:

  • I have 2 blinds - one supports up/down and tilt, other is only up/down.
  • I have a powerview pro hub (supports PoE)
  • Both blinds are on opposite ends of the house, and the hub only reaches the tilting blind (even though the api lists both). Most likely, I will need to get a second hub :(

What I ended up doing in the interim is setting it all up as custom template devices in HA using the rest API. I can share those configs if desired, but it works well and shows state etc.

@jwvanderbeck yea if you don’t mind sharing. It will be a good stop gap.

jlk commented

Hey folks - recent convert to HA (from openhab), got some gen3 gear last year that I'd love to get in the system.

Would love to see your templates, @jwvanderbeck if you're still game to share!

I was following the OH gen3 discussion, and understand supporting gen2/gen3 might be a bit of work.

I'm happily unemployed for the next month or two - I got the Python chops, a gen3 hub, an OpenVPN setup, years of swagger experience...I don't want to step on people but love to help however I can!

Hey folks - recent convert to HA (from openhab), got some gen3 gear last year that I'd love to get in the system.

Would love to see your templates, @jwvanderbeck if you're still game to share!

I was following the OH gen3 discussion, and understand supporting gen2/gen3 might be a bit of work.

I'm happily unemployed for the next month or two - I got the Python chops, a gen3 hub, an OpenVPN setup, years of swagger experience...I don't want to step on people but love to help however I can!

Thought initially this was going to be simple but looks like the api needs a rewrite - which will also translate to a fair amount of change on the HA side too so need to make sure not to go breaking gen2 in the process

I have started the work but had a pretty busy Christmas and New year period and this suffered as a result - will get stuck back in soon and definitely reach out for some testing at the very least but I’m sure there will be some parts that having the Gen3 hub will be useful (I only have gen2) 😉

jlk commented

Cool - I saw how to enable swagger on the hub yesterday and poked around. The API itself isn't complex, but I get the issue is backwards compatibility.

For others following along - I was able to quickly add a few curl commands as HA rest_commands so there's a usable workaround for now. If it's helpful I can write up a howto in a gist or maybe a video walkthrough...

Sorry for now posting sooner. I didn't want to just dump my HA config without any context or explanation, so I kept holding off until I could write up some sort of accompanying text. Truth is I'm not sure when that will happen so I figure dumping my configs is still better than nothing.

The tl;dr is you can set up HA to use a REST API as input for sensors, and can send commands to a REST API. This is all you need to get it working with the one big caveat that "covers" as HA treats blinds natively only have one major movement axis and a second "tilt" axis. This means you need to sort of shoehorn in your HD blinds if they are liked mine where they have secondary axis movement such as a light blocking second layer or can be opened closed both up top down and bottom up. So in my configs below there are a couple of special scripts which I use to directly control these secondary axes for specific situations like my bedroom shades where I have a privacy mode that opens the top 30% or my office where I have a command to open or close the second room darkening layer.

You will of course need to modify these accordingly for your own use case.

FHere is the main configuration.yaml and then after that I will include a couple of the example scripts I mentioned above which are in my scripts.yaml

sensor:
  - platform: template
    sensors:
      office_blinds_position_primary:
        friendly_name: "Office Blinds Primary Position"
        value_template: >
          {{ states('sensor.office_blinds_position')|float(0) * 100 }}
  - platform: rest
    resource: http://192.168.0.147/home/shades/36
    name: Powerview Office Primary Position
    value_template: "{{value_json.positions.primary}}"
    unique_id: powerview.office.primary.position
  - platform: rest
    resource: http://192.168.0.147/home/shades/36
    name: Powerview Office Secondary Position
    value_template: "{{value_json.positions.secondary}}"
    unique_id: powerview.office.secondary.position
  - platform: rest
    resource: http://192.168.0.147/home/shades/56
    name: Powerview Bedroom Primary Position
    value_template: "{{value_json.positions.primary}}"
    unique_id: powerview.bedroom.primary.position
  - platform: rest
    resource: http://192.168.0.147/home/shades/56
    name: Powerview Bedroom Secondary Position
    value_template: "{{value_json.positions.secondary}}"
    unique_id: powerview.bedroom.secondary.position

cover:
  - platform: template
    covers:
      office_blinds:
        friendly_name: "Powerview Office Shade"
        unique_id: powerview.office.blinds
        device_class: shade
        position_template: >
          {{ states('sensor.powerview_office_primary_position')|float * 100 }}
        tilt_template: >
          {{ states('sensor.powerview_office_secondary_position')|float * 100 }}
        open_cover:
          service: rest_command.powerview_office_set_position
          data:
            primary: 1
            secondary: 1
        close_cover:
          service: rest_command.powerview_office_set_position
          data:
            primary: 0
            secondary: 1
        set_cover_position:
          service: rest_command.powerview_office_set_position
          data:
            primary: "{{ (position / 100)|float }}"
            secondary: "{{ states('sensor.powerview_office_secondary_position')|float }}"
        set_cover_tilt_position:
          service: rest_command.powerview_office_set_position
          data:
            primary: "{{ states('sensor.powerview_office_primary_position')|float }}"
            secondary: "{{ (tilt / 100)|float }}"
      bedroom_blinds:
        friendly_name: "Powerview Bedroom Shade"
        unique_id: powerview.bedroom.blinds
        device_class: shade
        position_template: >
          {{ states('sensor.powerview_bedroom_primary_position')|float * 100 }}
        tilt_template: >
          {{ states('sensor.powerview_bedroom_secondary_position')|float * 100 }}
        open_cover:
          service: rest_command.powerview_bedroom_set_position
          data:
            primary: 1
            secondary: 0
        close_cover:
          service: rest_command.powerview_bedroom_set_position
          data:
            primary: 0
            secondary: 0
        set_cover_position:
          service: rest_command.powerview_bedroom_set_position
          data:
            primary: "{{ (position / 100)|float }}"
            secondary: "{{ states('sensor.powerview_bedroom_secondary_position')|float }}"
        set_cover_tilt_position:
          service: rest_command.powerview_bedroom_set_position
          data:
            primary: "{{ states('sensor.powerview_bedroom_primary_position')|float }}"
            secondary: "{{ (tilt / 100)|float }}"

rest_command:
  powerview_office_primary_open:
    url: http://192.168.0.147:80/home/shades/positions?ids=36
    method: PUT
    headers:
      accept: "application/json, text/html"
      user-agent: "Mozilla/5.0 {{ useragent }}"
    content_type: "application/json; charset=utf-8"
    payload: '{"positions":{"primary":1,"secondary":1}}'
  powerview_office_primary_close:
    url: http://192.168.0.147:80/home/shades/positions?ids=36
    method: PUT
    headers:
      accept: "application/json, text/html"
      user-agent: "Mozilla/5.0 {{ useragent }}"
    content_type: "application/json; charset=utf-8"
    payload: '{"positions":{"primary":0,"secondary":1}}'
  powerview_office_set_position:
    url: http://192.168.0.147:80/home/shades/positions?ids=36
    method: PUT
    headers:
      accept: "application/json, text/html"
      user-agent: "Mozilla/5.0 {{ useragent }}"
    content_type: "application/json; charset=utf-8"
    payload: '{"positions":{"primary":{{ primary }},"secondary":{{ secondary }}}}'
  powerview_bedroom_set_position:
    url: http://192.168.0.147:80/home/shades/positions?ids=56
    method: PUT
    headers:
      accept: "application/json, text/html"
      user-agent: "Mozilla/5.0 {{ useragent }}"
    content_type: "application/json; charset=utf-8"
    payload: '{"positions":{"primary":{{ primary }},"secondary":{{ secondary }}}}'

Scripts

office_shades_darkening_on:
  alias: Office Shades Darkening On
  sequence:
    - service: rest_command.powerview_office_set_position
      data:
        primary: 0
        secondary: 0
  mode: single
  icon: mdi:roller-shade-closed
office_shades_darkening_off:
  alias: Office Shades Darkening Off
  sequence:
    - service: rest_command.powerview_office_set_position
      data:
        primary: 0
        secondary: 1
  mode: single
  icon: mdi:roller-shade
bedroom_shade_privacy_mode:
  alias: Bedroom Shade Privacy Mode On
  sequence:
    - service: rest_command.powerview_bedroom_set_position
      data:
        primary: 0
        secondary: 0.3
  mode: single
  icon: mdi:roller-shade-closed
bedroom_shade_privacy_mode_off:
  alias: Bedroom Shade Privacy Mode Off
  sequence:
    - service: rest_command.powerview_bedroom_set_position
      data:
        primary: 0
        secondary: 0
  mode: single
  icon: mdi:roller-shade-closed

Thought initially this was going to be simple but looks like the api needs a rewrite - which will also translate to a fair amount of change on the HA side too so need to make sure not to go breaking gen2 in the process

Yeah that was pretty much what I was saying at the start :) Didn't really see a clean way to do things without also breaking v2, which is why I was hesitant to start mucking with other peoples code :)

I enabled swagger on my Gateway and (eventually) found this API spec which is version 2.1.0: https://drive.google.com/file/d/1E2CRMYLyzT-4X4q798zRe-tAgej2WjPM/view?usp=share_link
Using it through Postman I can see I have hardware version 3.0.4 and firmware 3.1.452
Python is probably my weakest language, but I am planning on working on this as I really want to get my blinds integrated with Home Assistant.

lairdm commented

I've begun making some automations and attempted to create a sensor while we figure out how to update the HA plugin, unfortunately I see a potential blocker to some functionality.

Based on poking at the scenes endpoints there's two issues. The first is there's no easy way to tell what an active scene for a blind or group of blinds are. You can ask for all the scenes, you can ask for all the active scenes, but the scenes aren't grouped by what blinds they apply to. As in, if your living room blinds have an open and close scene, the only way to know those scenes are related to the same blind grouping is by looking at all the blinds associated with them. There's no way to find the status of the living room blinds scene, only that a particular scene is active and you have to already now its the living room.

The second is for not fully open or closed scenes, for example we have zebra blinds, and we have a scene where they're in vanes open (eg all the transparent slits line up), if you activate that scene it doesn't show in the /scenes/active endpoint. I suspect this partially has to do with the position to achieve this scene being 0.2, and it's something to do with it not being at an extreme (0 or 1).

But the combination of these two issues means when you have zebra blinds in vanes open and you ask what scenes are active, you get no information for the group, it just vanishes for the active scenes list. It means unless you then query each blind in the group to find it's exact position you don't know their current position. What's interesting is the app seems to do all these lookups, it knows the active scene is the vanes open one.

Hopefully this helps whoever starts working on the update.

jlk commented

Looking in my powerview app, for one room it's showing three(!) scenes as selected. The scenes are variations on "blinds closed" - one is quiet close, one is just one blind closed, the other is generic "close all blinds."

My guess is the app is calculating scene state by looking at blind state.

lairdm commented

I suspect you're right. It'd definitely be nice if the gateway had an endpoint that woud do that lookup and grouping for us.

I'm not even sure what "active" means in terms of a scene? Are you considering the last scene used to be the active one?

In my mind there is only current state which really has nothing to do with scenes. Simply what are the primary and secondary positions.

You'll note in my "HA Native" implementation above that I dont' strictly use HA "cover" controls because they don't really do well with the advanced options HD blinds have.

Scenes are useful for changing state but after a scene has run I don't see its relevance anymore.

jlk commented

Scenes are useful for changing state but after a scene has run I don't see its relevance anymore.

I'd generally agree with that, I think. Blind status would be good, tho.

alindner19 has done a bunch of work and has been communicating in this thread: https://community.home-assistant.io/t/hunter-douglas-powerview-gen-3-integration/424836/74
I think maybe they're just wanting some gen 1 and 2 testing before making some pull requests?

Just submitted PR for review. Didn't see this thread until now.

Just submitted PR for review. Didn't see this thread until now.

@alindner19 - The irony that the guys posting here about your progress is what prompted me to reach out on the forum 😂

Apologies for not getting the the PR this week - have had an ongoing P1 at work eating all my time.

I’ll hopefully find some time in the next couple days to get things moving on #29 (P1 closed today 🎉)

Should I submit a PR for the Home Assistant side now as well? It depends on aiopvapi driver being available.

I wouldn’t.
There will be a few things on both sides to get it ready for HA - the driver needs to be published before the HA side could be accepted anyway.

@ChrisCrewdson - any chance you could check the api for a newer version for me - just verifying and refactoring so be best to have the latest api (dont believe HD have even finalised it yet tbh)

@kingy444 Sure. It looks like my Gateway Pro is firmware 3.1.472 and the API version is 2.3.0
Here's the doc: https://drive.google.com/open?id=19h6R_GWBX3EA0_UrZS_FPPv-y-lGfnID&usp=drive_fs

The changes from 2.1.0 are pretty minimal.

Here's what I did to get it:

  1. Enable swagger with http://<gateway IP>/gateway/swagger?enable=true
  2. Go to http://<gateway IP>:3002/
  3. F12 to dev tools and force cache refresh (shift F5) and look for swagger-ui-init.js
  4. Extract the options var that contains the swagger doc.

I see #29 was merged and there's now a v3.0.0, so that's exciting! Thank you for all the work that went into this.

V3 should hopefully be in HA within a few weeks - I'll close this one off. Open a new issue if anything pops up that isn't working as expected 😉