benleb / surepy

🐾 Library & CLI to monitor and control the Pet Door & Cat Flap Connect 🚪 the Pet Feeder Connect 🍽 and the Felaqua 💦 sold by Sure Petcare
https://pypi.org/project/surepy/
MIT License
76 stars 36 forks source link

Update API Url #200

Closed chrisdrackett closed 8 months ago

chrisdrackett commented 8 months ago

closes #199

cs12ag commented 8 months ago

I've tested your changes in my local installation and I'm struggling to get it operational. I too noticed yesterday that the API looks like it might have moved address, but after applying these changes I can't get an authorization token generated from within Home Assistant. I've also attempted to generate one from the CLI using surepy token -u ... -p ... but also without success. When attempting this I get a bunch of errors out:

  File "/usr/local/bin/surepy", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context(), *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/surepy/surecli/__init__.py", line 39, in wrapper
    return asyncio.run(f(*args, **kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/surepy/surecli/__init__.py", line 141, in token
    if surepy_token := await sp.sac.get_token():
                       ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/surepy/client.py", line 188, in get_token
    raise SurePetcareError()
surepy.exceptions.SurePetcareError

Oddly, there seems to be another API used too: https://app-api.production.surehub.io/api/start I don't know why there are two, and I haven't looked into which is used when and / or why.

However, I've tested out using this URI instead i.e. removing '.blue' from the URI in const.py and client.py. I'm actually then able to create a token from the CLI.

I was also then presented with a final issue that took me an annoyingly long time to work out - the auth token also exists in the hidden file /config/.storage/.core.config_entries . Once I'd copied over the new token from /root/.surepy.token into the 'token' parameter in the 'sureha' json and restarted HA, I was able to authenticate and get the the Sure HA integration up and running again. I wonder if there is an issue with some part of SureHA that either isn't checking for a new token in /root/.surepy.token or isn't replacing the contents of the /config/.storage/.core.config_entries json when it's supposed to.

chrisdrackett commented 8 months ago

@cs12ag are you sending a device id along with the user and password? With this I was able to get a token via the CLI and in postman, but I never went as far as you did to get it going in HASS as I'm not up on how that all works.

cs12ag commented 8 months ago

Yep. The device ID is automatically handled by the surepy library, It looks rather basic, in so much as a random UUID is being passed each time: https://github.com/benleb/surepy/blob/dev/surepy/client.py#L113 I guess there's no stringent server-side checking that a given auth token belongs to a specific device ID when using the API.

Apologies for presuming you were also working with a Home Assistant system; I should have figured that the separation of surepy and SureHA was so that anyone could use the underlying API to SurePetcare without being forced to host it within a Home Assistant system.

chrisdrackett commented 8 months ago

I am using home assistant, I just don't know how to modify its components, but I do know how to install and modify stuff in python :P

cs12ag commented 8 months ago

Ah! I have quite a specific, non-standard HA set-up. I can tell you how I modified the surepy component on mine for testing, but that may not the same for you - my testing was done on a system where I've explicitly set each part of HA up in its own container in docker. This was so that I didn't have to hand over my entire Raspberry PI to HASS OS.

ivo-toby commented 8 months ago

I manually modified the lib with the changes in this PR on my HA instance and that did not do the trick unfortunately. But I don't know that much about how the HA architecture works so I might have missed a step.

cs12ag commented 8 months ago

@ivo-toby Did you use app-api.blue.production.surehub.io or app-api.production.surehub.io ?

There might also be some shenanigans going on around using a token generated by app.api.surehub.io (the old API) with whichever new API you've added to your installation. This is in reference to the last paragraph on my comment above.

dieriver commented 8 months ago

I'm afraid that changing the URL will not solve the issue. It seems that the specs of the messages were also changed. For example, to set the lock state of a cat flap, v0.8.0 of surepy sends a "PUT" request to the URL "https://app-api.production.surehub.io/api/device/{deviceId}/control" with the map "locking: " in the payload. According to https://app-api.production.surehub.io/index.html, the URL endpoint is still valid, however, the expected format of the message is totally different (see the definition of "DeviceControl", under the "PUT" request for the URL /api/device/{deviceId}/control). This change on the expected format would explain the HTTP 422 return codes we get from surepy. Moreover, in the expected message spec, the "status" is an enum in the set "[ 0, 1, 2, 3, 4, 5 ]". Those values do not map with the hard-coded Flap statuses in the LockState enum in the surepy/enums.py file, which even has some negative values. Imho, the library needs to be re-reversed engineered :/

cs12ag commented 8 months ago

@dieriver I'm surprised and somewhat elated to see that API definition. I didn't think that information would be made public. That's cool.

However, the documentation you've found for the Enum set isn't related to the request actually sent to the API. Those Enums are the outcome of the transaction itself, and they appear in the 'results' section of the response json. The actual business bit of the request is within the 'data' section of the request json, which is entirely undefined according to the documentation. I've tested this out using F12 on Chrome and then locked my cat-flap (keep pets in), the content of the 'data' json element is as follows:

{
  "curfew": {
    "enabled": false,
    "lock_time": "23:30",
    "unlock_time": "06:30"
  },
  "locking": 1,
  "fast_polling": true
}

The value of locking matches up with what's in enums.py to lock my cat-flap such that pets inside are stuck inside but pets outside are allowed in. :) I totally concede that I haven't tested anything else, so I'm absolutely not ruling out any changes within the new API - but this stuff looks like it should still work to me at least.

dieriver commented 8 months ago

@cs12ag interesting... if I find some time this weekend, I will try to play a bit more with the "manual" HTTP requests from any browser. As you say, maybe a full re-implementation is not required, but just some adjustments to match the new structures

jmvedrine commented 8 months ago

Hello, there is at least one thing that seems to have changed in the new API: my old command to add a pet to a feeder doesn't work anymore but surprisingly the command to remove a pet is still working ???

chrisdrackett commented 8 months ago

I'm going to close this PR for now as it seems insufficient :(

blair287 commented 8 months ago

I'm going to close this PR for now as it seems insufficient :(

Oh does it not fix the issue? Sad all my pet automations now are not working. Wish there was a local option for products that do what theirs do their approach to smart home is God awful.

jmvedrine commented 8 months ago

Hello I am the author of the sure petcare products integration in the Jeedom french home automation software (not using the surepy library but "largely inspired" by its code). As the authentification is still working with the new base url in jeedom (but other part of the plugin are broken for instance curfew and profile requests) I guess you are just missing to add Content-Type: application/json and Content-Length in the headers of the requests to make authentification working again. For the blue/green thing I and totaly unfamiliar with that but I was beleiving that blue is the old API and green the new one. As long as blue is not deprecated we can use blue. Correct ?

jmvedrine commented 8 months ago

I find some aspects of the API quite surprising: request to get pet's position: GET /api/pet/position/{deviceId} and GET /api/pet/{petId}/position/{deviceId} seem to be related to a flap (and optionnaly to a pet) but the request to update pet position is only related to a pet: PUT /api/pet/{petId}/position If I undersatnd well they are trying to manage the case of users with several flaps but currently the API is not consistent.

cs12ag commented 8 months ago

@jmvedrine the swagger documentation for all the following APIs all look the same: https://app.api.surehub.io/index.html (old API) https://app-api.production.surehub.io/index.html (new API) https://app-api.blue.production.surehub.io/index.html (new API - blue)

The new API green is giving me 403 response currently (https://app-api.green.production.surehub.io/index.html). I'm not sure what documentation is accurate. I've also found a call to a report/household/{householdID} transaction which I would have expected to appear under the ReportHouseholdPet functionality in the documentation on the old API at least, but it's not in any of the documentation. It seems to return information when I execute surepy pets from the CLI, against the new API. Perhaps this transaction is deprecated but still available? Most odd.

Kiphouder commented 8 months ago

Hope you guys can fix it, would be super grateful!

chrisdrackett commented 8 months ago

I find some aspects of the API quite surprising: request to get pet's position: GET /api/pet/position/{deviceId} and GET /api/pet/{petId}/position/{deviceId} seem to be related to a flap (and optionnaly to a pet) but the request to update pet position is only related to a pet: PUT /api/pet/{petId}/position If I undersatnd well they are trying to manage the case of users with several flaps but currently the API is not consistent.

I think this is used if you let a can in another door. There is a way in the app to mark a cat as in or out. We use it from time to time :)

chrisdrackett commented 8 months ago

@cs12ag might need to switch back over to blue, that works for me at the moment (https://app-api.blue.production.surehub.io/index.html)

jmvedrine commented 8 months ago

I think this is used if you let a can in another door. There is a way in the app to mark a cat as in or out. We use it from time to time :)

Yes I use that feature in my Jeedom plugin too. And I just found that a call to /api/v2/report/household/{householdId}/pet/{petId} gives results for pet movements with entry_device_id and exit_device_id so they are certainly trying to fix the case of several flaps but I was expecting consistency between GET and PUT calls.

DarkPhyber-hg commented 7 months ago

Following up to see if there are any updates on this? Specifically as it relates to the feeders not working in Home Assistant with sureha integration..