Pyhiveapi icon indicating copy to clipboard operation
Pyhiveapi copied to clipboard

[FEATURE] Work with guest access to secondary homes

Open martintoreilly opened this issue 3 years ago • 13 comments

Is your feature request related to a problem? Please describe.

It is possible to add additional accounts with guest access to a Hive Home (at either "Partner" or "Family" levels of access). However, this library currently only supports the primary Hive Home for a Hive account. Therefore I cannot currently use an account with guest access to my Hive Home to control my Hive devices via this library or the Hive Home Assistant integration that uses it.

Describe the solution you'd like

I would like to be able to query for homes an account has access to and control the devices in these guest homes. I think the pieces are in place to do this and I'm happy to make the changes and submit a PR, but I'd like your thoughts on my proposed approach @KJonline.

Pieces in place

  • getAll() currently returns a list of homes the account has access to in addition to the devices, products and actions in the default/primary home for the account, via a call to the https://beekeeper.hivehome.com/1.0/nodes/all Hive API endpoint.
  • Most Hive API endpoints take an optional homeId query parameter that allows selection of a secondary Hive Home for users with guest permissions. So far I've verified this works for the following endpoints for a user with "Partner" access to my Hive Home and no devices/products in their primary Hive Home:
    • https://beekeeper.hivehome.com/1.0/nodes/all
    • https://beekeeper.hivehome.com/1.0/devices
    • https://beekeeper.hivehome.com/1.0/products

Complication

  • The homeId parameter does not appear to work for the https://beekeeper.hivehome.com/1.0/actions endpoint. I can see two actions when using my Owner account and none using my Partner account, whether or not I add the homeId parameter.

Proposed approach

  • Add a hive_api.getHomes() function that calls hive_api.getAll() and extracts just the list of homes.
  • Add a hive_api.setHome(homeId) function that updates the value of self.config.homeID.
  • Augment the hive_api.getAll() function to take an additional optional homeId parameter and pass it on to the call to the underlying https://beekeeper.hivehome.com/1.0/nodes/all Hive API endpoint, using the passed homeId if provided and self.config.homeID if not.
  • Augment the hive_api.getActions() function to take an additional optional homeId parameter and change it to call hive_api.getAll()with the homeId parameter and filter for just the actions list to work around the fact that the homeId parameter does not work with the https://beekeeper.hivehome.com/1.0/actions endpoint.
  • Augment the hive_api.getDevices() and hive_api.getProducts() functions to take an additional optional homeId parameter and pass this on to their underlying calls to their respective Hive API endpoints, using the passed homeId if provided and self.config.homeID if not. For consistency, I'd be inclined to switch these functions from calling their own Hive API endpoints to calling hive_api.getAll() with the homeId parameter and filtering the results to just the devices and products lists respectively. However, I'll take your steer on whether this is a good idea @KJonline.
  • The hive_api.getAlarms() function already calls its underlying https://beekeeper.hivehome.com/1.0/security-lite Hive API endpoint with the homeId parameter, passing self.config.homeID as the value of this parameter. Augment this function to take an additional optional homeId parameter and use this if provided, defaulting to self.config.homeID if not (as currently).

Additional context

I would like this features to provide more restricted access to the Hive Home Assistant integration, by creating a new Hive account for home assistant and adding it to my Hive Home with either "Family" or "Partner" access (whichever gives the minimum access required to control my Hive devices).

Originally raised in the discussion in (closed) issue #18 (see this comment). Moving to its own issue to take forward.

Thoughts @KJonline ?

martintoreilly avatar Dec 29 '21 20:12 martintoreilly

Edit: Oops. Hit submit too soon

As part of this change, I think we should also update the exception raised at the end of startSession() if there are no devices or products found. At the moment this raises a HiveReauthRequired error, but I think this condition would result in a 403 response to the query (at least that is what I see when using an expired token to query a beekeeper endpoint manually using Postman). I think seeing no devices or products just means that there are none for the specified Hive Home and any error raised should reflect this. My instinct would be not to raise an error at all here.

martintoreilly avatar Dec 29 '21 20:12 martintoreilly

If the Hive API beekeeper endpoints are called with an invalid homeId (even one that doesn't match the GUID format), a 200 OK response is received with a JSON payload that is the same as when there are no devices in a home (rather than defaulting to the "primary" home). This response contains the following elements:

  • user
  • status
  • alerts
  • media
  • products (empty array)
  • devices (empty array)
  • actions (empty array)
  • homes (includes homes and entitlements elements)

martintoreilly avatar Dec 29 '21 21:12 martintoreilly

I'm also happy to extend the Hive Home Assistant Integration to expose this new functionality, though I'll need some time to get my head into the codebase.

martintoreilly avatar Dec 30 '21 06:12 martintoreilly

@martintoreilly I agree with the overall approach I would probably look at the nodes/all endpoint and reversing the parameters and setting products/devices/actions to false. If that brings a short response back with the users and homes information that could be used to get how many homes there are.

KJonline avatar Dec 30 '21 16:12 KJonline

Thanks @KJonline. I can confirm that calling https://beekeeper.hivehome.com/1.0/nodes/all?devices=false&products=false&actions=false does return a short response back with users and homes and no devices, products or actions. I'll use this as the underlying call for the getHomes() function.

martintoreilly avatar Dec 31 '21 01:12 martintoreilly

Glad it’s helps what we need if you create a PR I’ll look at merging it in. I have merged your other PR for the .gitignore change

KJonline avatar Dec 31 '21 15:12 KJonline

@martintoreilly did you have any luck with this?

AWare avatar May 03 '22 17:05 AWare

@KJonline there seem to be two implementations of the API, are they both in use?

AWare avatar May 14 '22 17:05 AWare

@AWare ye there is a async and a sync one. Home assistant and the session based code use the async version. The sync version offers another use case in the library for people who don’t use home assistant but may still want a hive integration of their own.

KJonline avatar May 14 '22 19:05 KJonline

@AWare ye there is a async and a sync one. Home assistant and the session based code use the async version. The sync version offers another use case in the library for people who don’t use home assistant but may still want a hive integration of their own.

KJonline avatar May 14 '22 19:05 KJonline

@martintoreilly did you have any luck with this?

Hi @AWare. I haven't managed to spend any more time on this. I did some work on setting the schedule (#19) then got a bit bogged down trying to add testing to ensure I wasn't breaking anything. I'd be happy to jump back in on this if it would help?

martintoreilly avatar May 14 '22 23:05 martintoreilly

I had a decent go at it yesterday, I'll see if I can't raise a draft PR today.

AWare avatar May 15 '22 11:05 AWare

getAll also doesn't support homeId

AWare avatar May 15 '22 14:05 AWare