hasscc / petkit

🐱 Petkit feeder components for HomeAssistant
Apache License 2.0
122 stars 16 forks source link

Request: Petkit Pura X integration #5

Closed fhornrudd closed 2 years ago

fhornrudd commented 2 years ago

Request: It would be nice if this could also gather the sensors of the petkit pura x smart litter box. I think it uses the same API as my installation shows online and I do not have the feeder.

al-one commented 2 years ago

Can you capture the data in APP of the device ?

fhornrudd commented 2 years ago

Can you help with how I can do this?

fhornrudd commented 2 years ago

I found user Lydian has some info on a separate GitHub for writing to a spreadsheet, does this have any of the information needed from the app?

fhornrudd commented 2 years ago

https://github.com/lydian/petkit_pura_x_exporter/blob/master/petkit_exporter/petkit.py

fhornrudd commented 2 years ago

Request URL: http://api.petkt.com/latest/t3/devicestate Response:

{
  "result": {
    "box": 0,
    "boxFull": false,
    "liquid": 100,
    "liquidEmpty": false,
    "liquidLack": false,
    "ota": 0,
    "overall": 1,
    "petInTime": 0,
    "pim": 1,
    "power": 1,
    "sandLack": false,
    "sandPercent": 88,
    "sandWeight": 5191,
    "wifi": {
      "bssid": "###########",
      "rsq": -77,
      "ssid": "############"
    }
  }
}
fhornrudd commented 2 years ago

Request: http://api.petkt.com/latest/discovery/device_roster

Response:

{
  "result": {
    "p3d": {
      "enable": 1
    },
    "t4": {
      "enable": 1
    },
    "r2": {
      "enable": 1
    },
    "p3c": {
      "enable": 1
    },
    "aqr": {
      "enable": 1
    },
    "p3": {
      "enable": 1
    },
    "w5c": {
      "enable": 1
    },
    "cozy": {
      "gearsTotal": 6.0,
      "enable": 1,
      "tempunit": 1,
      "sTempMin": 50,
      "isShowDeviceSafetyClause": 0,
      "gearsOffset": 3.0,
      "sTempMax": 108
    },
    "feeder": {
      "isShowDeviceSafetyClause": 0
    },
    "h2": {
      "enable": 0
    },
    "tools": [{
      "type": "walkpet",
      "data": {}
    }, {
      "type": "weight"
    }, {
      "type": "remind",
      "data": {}
    }],
    "d3": {
      "enable": 1
    },
    "d4": {
      "enable": 1
    },
    "w5n": {
      "enable": 1
    },
    "w5": {
      "enable": 1
    },
    "devices": [{
      "data": {
        "name": "Cat Box",
        "createdAt": "2021-09-01T############",
        "id": 100006205,
        "state": 1,
        "relation": {
          "petIds": ["100######"],
          "userId": "100######"
        },
        "status": {
          "box": 0,
          "boxFull": false,
          "liquid": 100,
          "liquidEmpty": false,
          "liquidLack": false,
          "ota": 0,
          "overall": 1,
          "petInTime": 0,
          "pim": 1,
          "power": 1,
          "sandLack": false,
          "sandPercent": 88,
          "sandWeight": 5229,
          "wifi": {
            "bssid": "#########",
            "rsq": -77,
            "ssid": "########"
          },
          "workState": {
            "stopTime": 600,
            "workMode": 0,
            "workProcess": 10,
            "workReason": 2
          }
        },
        "desc": "Cat litter remaining: 88%"
      },
      "type": "T3"
    }],
    "k2": {
      "enable": 1
    },
    "go": {
      "hasMarks": 0,
      "maxMarksPerRoute": 30,
      "markEnabled": 1
    },
    "k3": {
      "enable": 1
    },
    "aq": {
      "enable": 1
    },
    "feedermini": {
      "isShowDeviceSafetyClause": 0
    },
    "w4x": {
      "enable": 1
    },
    "appbanner": [],
    "t3": {
      "enable": 1
    },
    "aq1s": {
      "enable": 1
    }
  }
}
fhornrudd commented 2 years ago

There were also device_detail and getDeviceRecord requests if those would be useful

fhornrudd commented 2 years ago

Request: http://api.petkt.com/latest/t3/getDeviceRecord

Response:

{
  "result": [{
    "content": {
      "autoClear": 1,
      "interval": 6,
      "petWeight": 4837,
      "timeIn": 1640244149,
      "timeOut": 1640244210
    },
    "eventType": 10,
    "timestamp": 1640244210
  }, {
    "content": {
      "box": 0,
      "boxFull": false,
      "litterPercent": 91,
      "result": 0,
      "sandLack": false,
      "startReason": 0,
      "startTime": 1640244572
    },
    "eventType": 5,
    "timestamp": 1640244659
  }, {
    "content": {
      "autoClear": 1,
      "interval": 6,
      "petWeight": 4883,
      "timeIn": 1640256238,
      "timeOut": 1640256321
    },
    "eventType": 10,
    "timestamp": 1640256321
  }, {
    "content": {
      "box": 0,
      "boxFull": false,
      "litterPercent": 91,
      "result": 0,
      "sandLack": false,
      "startReason": 0,
      "startTime": 1640256683
    },
    "eventType": 5,
    "timestamp": 1640256770
  }, {
    "content": {
      "liquid": 100,
      "liquidLack": false,
      "result": 0,
      "startReason": 1,
      "startTime": 1640269802
    },
    "eventType": 8,
    "timestamp": 1640269832
  }, {
    "content": {
      "autoClear": 1,
      "interval": 6,
      "petWeight": 4763,
      "timeIn": 1640281500,
      "timeOut": 1640281607
    },
    "eventType": 10,
    "timestamp": 1640281607
  }, {
    "content": {
      "box": 0,
      "boxFull": false,
      "litterPercent": 91,
      "result": 0,
      "sandLack": false,
      "startReason": 0,
      "startTime": 1640281969
    },
    "eventType": 5,
    "timestamp": 1640282056
  }, {
    "content": {
      "autoClear": 1,
      "interval": 6,
      "petWeight": 4773,
      "timeIn": 1640282470,
      "timeOut": 1640282530
    },
    "eventType": 10,
    "timestamp": 1640282530
  }, {
    "content": {
      "box": 100,
      "boxFull": true,
      "litterPercent": 91,
      "result": 0,
      "sandLack": false,
      "startReason": 0,
      "startTime": 1640282892
    },
    "eventType": 5,
    "timestamp": 1640283030
  }, {
    "content": {
      "liquid": 100,
      "liquidLack": false,
      "result": 0,
      "startReason": 1,
      "startTime": 1640287801
    },
    "eventType": 8,
    "timestamp": 1640287831
  }, {
    "content": {
      "autoClear": 1,
      "interval": 6,
      "petWeight": 4692,
      "timeIn": 1640306238,
      "timeOut": 1640306306
    },
    "eventType": 10,
    "timestamp": 1640306306
  }, {
    "content": {
      "box": 100,
      "boxFull": true,
      "litterPercent": 88,
      "result": 0,
      "sandLack": false,
      "startReason": 0,
      "startTime": 1640306667
    },
    "eventType": 5,
    "timestamp": 1640306742
  }, {
    "content": {
      "liquid": 100,
      "liquidLack": false,
      "result": 0,
      "startReason": 1,
      "startTime": 1640309401
    },
    "eventType": 8,
    "timestamp": 1640309431
  }, {
    "content": {
      "box": 0,
      "boxFull": false,
      "litterPercent": 88,
      "result": 0,
      "sandLack": false,
      "startReason": 2,
      "startTime": 1640318362
    },
    "eventType": 5,
    "timestamp": 1640318448
  }, {
    "content": {
      "liquid": 100,
      "liquidLack": false,
      "result": 0,
      "startReason": 2,
      "startTime": 1640318703
    },
    "eventType": 8,
    "timestamp": 1640318733
  }, {
    "content": {
      "liquid": 100,
      "liquidLack": false,
      "result": 0,
      "startReason": 1,
      "startTime": 1640323802
    },
    "eventType": 8,
    "timestamp": 1640323832
  }]
}
fhornrudd commented 2 years ago

Request: http://api.petkt.com/latest/t3/device_detail

Response:

{
  "result": {
    "btMac": "##############",
    "createdAt": "2021-09-01T###########",
    "firmware": "1.389",
    "firmwareDetails": [{
      "module": "userbin",
      "version": 2131001
    }],
    "hardware": 1,
    "id": 100006205,
    "inTimes": 4,
    "lastOutTime": 998,
    "locale": "###time zone###",
    "mac": "##########%#",
    "name": "Cat Box",
    "petOutRecords": [
      [163, 165],
      [585, 586],
      [601, 602],
      [997, 998]
    ],
    "relation": {
      "petIds": ["100######"],
      "userId": "100######"
    },
    "secret": "################",
    "settings": {
      "autoIntervalMin": 0,
      "autoWork": 1,
      "fixedTimeClear": 0,
      "fixedTimeRefresh": 1,
      "lackLiquidNotify": 1,
      "lackSandNotify": 1,
      "language": "en_US",
      "languageFollow": 0,
      "languages": ["zh_CN", "en_US"],
      "lightMode": 1,
      "lightRange": [0, 1440],
      "litterFullNotify": 1,
      "manualLock": 1,
      "petInNotify": 0,
      "sandType": 1,
      "stillTime": 300,
      "stopTime": 600,
      "unit": 1,
      "workNotify": 0
    },
    "shareOpen": 0,
    "signupAt": "2021-12-07T###########",
    "sn": "#############",
    "specialLitterAd": {
      "adDetailUrl": "http:\/\/m.petkit.com\/app\/cat_litter.html",
      "adSwitch": 0,
      "adLinkUrl": "petkit.com"
    },
    "state": {
      "box": 0,
      "boxFull": false,
      "liquid": 100,
      "liquidEmpty": false,
      "liquidLack": false,
      "ota": 0,
      "overall": 1,
      "petInTime": 0,
      "pim": 1,
      "power": 1,
      "sandLack": false,
      "sandPercent": 88,
      "sandWeight": 5191,
      "wifi": {
        "bssid": "##############",
        "rsq": -77,
        "ssid": "###############"
      }
    },
    "timezone": -7.0,
    "totalTime": 318,
    "user": {
      "avatar": "http:\/\/img5-us.petkit.cn\/uavatar\/2021\/9\/1\/612ece4e98953a6fa400a91duqb775R7I",
      "gender": 2,
      "id": "100######",
      "nick": "user nickname",
      "point": {
        "endGrowth": 50,
        "growth": 15,
        "honour": "LV0",
        "icon": "http:\/\/img5-us.petkit.cn\/misc\/point\/s0",
        "icon2": "http:\/\/img5-us.petkit.cn\/misc\/point\/l0",
        "rank": 0,
        "startGrowth": 0
      }
    }
  }
}
al-one commented 2 years ago

Thank you, I will add support for this device when I have time.

fhornrudd commented 2 years ago

Thanks!

al-one commented 2 years ago

Please upgrade to main branch and try.

DevilsAdjutant commented 2 years ago

Thanks for the update, installed and tested it.

Got the following error:

Logger: homeassistant
Source: custom_components/petkit/__init__.py:541
Integration: Petkit (documentation, issues)
First occurred: 10:08:12 (3 occurrences)
Last logged: 10:12:12

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 134, in _handle_refresh_interval
    await self._async_refresh(log_failures=True, scheduled=True)
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 265, in _async_refresh
    update_callback()
  File "/config/custom_components/petkit/__init__.py", line 685, in _handle_coordinator_update
    self.update()
  File "/config/custom_components/petkit/__init__.py", line 689, in update
    if hasattr(self._device, self._name):
  File "/config/custom_components/petkit/__init__.py", line 526, in last_record
    evt = self.last_record_attrs().get('eventType') or 0
  File "/config/custom_components/petkit/__init__.py", line 541, in last_record_attrs
    ctx = lst.pop('content') or {}
KeyError: 'content'

and

Logger: custom_components.petkit
Source: custom_components/petkit/__init__.py:541
Integration: Petkit (documentation, issues)
First occurred: 10:08:12 (3 occurrences)
Last logged: 10:12:12

Unexpected error fetching petkit-<MAILADDRESS>@gmail.com-devices data: 'content'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 187, in _async_refresh
    self.data = await self._async_update_data()
  File "/config/custom_components/petkit/__init__.py", line 248, in _async_update_data
    dvc.update_data(dat)
  File "/config/custom_components/petkit/__init__.py", line 299, in update_data
    self._handle_listeners()
  File "/config/custom_components/petkit/__init__.py", line 304, in _handle_listeners
    fun()
  File "/config/custom_components/petkit/__init__.py", line 685, in _handle_coordinator_update
    self.update()
  File "/config/custom_components/petkit/__init__.py", line 689, in update
    if hasattr(self._device, self._name):
  File "/config/custom_components/petkit/__init__.py", line 526, in last_record
    evt = self.last_record_attrs().get('eventType') or 0
  File "/config/custom_components/petkit/__init__.py", line 541, in last_record_attrs
    ctx = lst.pop('content') or {}
KeyError: 'content'

Initial al the sensors come up just fine, after a minute or so some become unavailable or with error.

Is it possible to also add option to manual clean the litterbox?

al-one commented 2 years ago

Upgrade and try again.

DevilsAdjutant commented 2 years ago

Now working without any problem.

Only the action option is giving an error.

Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/petkit/select.py:51
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 10:34:30 (3 occurrences)
Last logged: 10:34:39

[281473048455344] select_action() got an unexpected keyword argument 'entity'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 185, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1495, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1530, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 209, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 663, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 896, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 700, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/select/__init__.py", line 54, in async_select_option
    await entity.async_select_option(option)
  File "/config/custom_components/petkit/select.py", line 51, in async_select_option
    ret = await fun(option, **kws)
TypeError: select_action() got an unexpected keyword argument 'entity'
al-one commented 2 years ago

Try again.

DevilsAdjutant commented 2 years ago

Gives no error now, but does nothing on the Pura X..

fhornrudd commented 2 years ago

7B0D7DB4-C7BA-4E3A-900A-7518A19B372D

fhornrudd commented 2 years ago

Thanks, it’s showing quite a few of the Pura x sensors now! If it could also get deodorizing/purifying liquid level/state and last animal weight that would be amazing! Again, thank you for this!

fhornrudd commented 2 years ago

The ‘action’ entity does not seem to do anything and the power toggle returns: Failed to call service switch/turn_on. turn_on() got an unexpected keyword argument ’entity’

fhornrudd commented 2 years ago

The main actions of use would be ‘clean now’ and ‘odor removal now’

fhornrudd commented 2 years ago

2F71A9EC-4E9A-4F6E-8BFA-39C8E86721C9 I see the liquid level and status showing up under attributes of state. Is it possible to get that as a separate entity/entities?

fhornrudd commented 2 years ago

I found I can probably extract the liquid info by template creation (I still need to learn how to do this but it looks to be within my trial and error capabilities), so I think the main items for me that would be useful to me that are remaining: •The ability to manually clean (switch/button/select) •The ability to manually deodorize (switch/button/select) •A reading in the cat’s last weight

I tested that box_full, in_times, last_record, and sand_percent entities all work well. Thanks!

fhornrudd commented 2 years ago

Cat weight and liquid look like they are working with that latest

fhornrudd commented 2 years ago

It looks like any actions (power, manual cleaning, deodorizing) still are not working/doing anything. Thanks!

al-one commented 2 years ago

Show me the logs after control the device.

fhornrudd commented 2 years ago

Maybe this is it? Turn Off Request URL: http://api.petkt.com/latest/t3/controlDevice Params: id=100006205&kv=%7B%22power_action%22%3A0%7D&type=power Response: { "result": "success" }

Turn On Params: id=100006205&kv=%7B%22power_action%22%3A1%7D&type=power

fhornrudd commented 2 years ago

Manual Odor Removal Params: id=100006205&kv=%7B%22start_action%22%3A2%7D&type=start

Manual Cleaning Params: id=100006205&kv=%7B%22start_action%22%3A0%7D&type=start

fhornrudd commented 2 years ago

One more nice switch would be the child lock. http://api.petkt.com/latest/t3/updateSettings Params: id=100006205&kv=%7B%22manualLock%22%3A0%7D And: id=100006205&kv=%7B%22manualLock%22%3A1%7D

Let me know if it is a different detail you need from these posts and I’ll try to look for those details.

robertoleonardo commented 2 years ago

hi - i'll add this here since it's basically the same ask: but petkit just released the puramax. would be great for it to be supported as well. it's /t4/ instead of /t3/, and i changed that in the init file and MOST everything started working but not the action select. says there is no entity id. looks like i'm supposed to have sensor.[id]_action in addition to select.[id]_action, but i only have the latter -- so i guess it's not quite as simple as changing the t3 to t4 and, alas, i'm way out of my depth in trying to do anything more. thank you so much!

by the way, if helpful - this is the request body i captured on quantumult when i trigger a clean cycle -- id=100000496&kv=%7B%22start_action%22%3A0%7D&type=start

i see that start_action instead of just action - maybe that's what changed from t3 to t4?

i've managed to get a power shell script successfully triggering the clean cycle from my pc but i'd love to be able to do it within ha and i cannot for the life of me figure out how to format this text string to use rest api.

fhornrudd commented 2 years ago

None of the actions are working as of yet on the Pura X either, the request parameters weren’t in the original dumps I made. Hoping that the more recent request parameter dumps can help al-one when they have time to be able to add those features

tapnet88 commented 2 years ago

Just wanted say this is working with a Pura MAX I can see all the attributes

image

robertoleonardo commented 2 years ago

anyone get pura x/max actions working yet? 'actions' still wonky with today's update. but i can see the attributes and those appear to work. i wonder if it relates to the fact that it keeps recognizing my pura x as a feeder. i've gotten aroun that by manually tweaking the py script to redirect all device types to the t4 function, but that's obviously not ideal since i have to re-tweak every time there's an update to the component.

fhornrudd commented 2 years ago

Nothing yet and I don’t have the dev skills needed. I think I captured the info above that is needed for the development but it hasn’t been integrated yet.

sam43434 commented 2 years ago

hopefully the dev has some time to get it working, Just got one of these machines myself

al-one commented 2 years ago

Upgrade and try.

fhornrudd commented 2 years ago

Thank you! I can confirm power on/off, clean, and deodorize are all working for me. The only other one of use to me would be a switch for lock/unlock

fhornrudd commented 2 years ago

617A2EC6-8F58-4947-A43C-D212D5850CA9 This is all working along with pause/resume

robertoleonardo commented 2 years ago

still no joy on pura max. i can still change the code to the correct device type (t4 instead of t3), and most things work, but still can't get the clean action to run. i was, however, able to trigger the deodorize and power on/off with this update, though both are spotty in terms of whether they respond.

al-one commented 2 years ago

@robertoleonardo Upgrade again.

robertoleonardo commented 2 years ago

thanks but that didn't do it. that change is what i'd tried -- it gets it to recognize the device, but most of the actions still don't work. clean cycle just doesn't do anything, pause/continue give me an error message. deodorize does work though. i think there must be different commands necessary for t4 vs t3, otherwise i would've thought the tweak you'd made, and i'd tried previously, would work.

but the recent updates have definitely made things more work than before. here's what works and doesn't:

1) power on/off toggle -- works, but the state toggle always shows on so you kinda have to just click it fast to get it to turn on when it's off. 2) manual lock toggle - works 3) sensor values - 'in_times' and 'pet_weight' show unknown, but the rest seem to be working. 4) actions: a) cleanup - no error message, but nothing happens b) all other actions - 'failed to call service select/select_option...must contain at least one of enttiy_id, area_id...' (i'm paraphrasing because it disappears too quickly haha) . previously i 'd said that deodorizer now seems to work, it doesn't - i think mine just coincidentally started doing a deodorize cycle on its own right when i was tinkering.

so basically: it correctly recognizes the pura max now that you added the t4, and MOST of the sensors work, and the two toggle switches work somewhat, but it remains the case that none of the 'actions' work.

fhornrudd commented 2 years ago

Thank you. Everything I have requested for Pura X is working! I can close this request or leave open if it is also addressing Pura max. Regarding @robertoleonardo items:

  1. Pura X behaves same, on/off commands both work but it wants to not immediately show new state so have to quickly toggle to switch back
  2. Sensor values show ‘Unknown’ after restart until next time cat enters (on t3/Pura X), at which time it shows the sensor value

Additionally nothing on the select menu records actions taken, so I automated two call services with input buttons so I would have records of manual cleaning/deodorizing.

sam43434 commented 2 years ago

617A2EC6-8F58-4947-A43C-D212D5850CA9 This is all working along with pause/resume

what card are you using there

fhornrudd commented 2 years ago

That’s just the normal “Entities Card”. I added button helpers for the two actions instead of using the select.

sam43434 commented 2 years ago

That’s just the normal “Entities Card”. I added button helpers for the two actions instead of using the select.

Any guidance of how to add the buttons and also get the weight ect like that.

fhornrudd commented 2 years ago

Sure, Button helpers were added this year to Home Assistant, so first make sure you are updated. Go to Configuration/Automations and then navigate to helpers (wrench and driver icon, same place you would add an input Boolean). Add helper, button type, then create automation that uses that button press to select desired option. Example:

alias: Clean Litterbox
description: ''
trigger:
  - platform: state
    entity_id: input_button.clean_litterbox
condition: []
action:
  - service: select.select_option
    data:
      option: cleanup
    target:
      entity_id: select.t3_100006205_action
mode: single

Regarding getting weight in pounds instead of grams, it requires templating. Here is my code (dev’s can probably write better code but this has been working for me for a few months):

template:
  - trigger:
      - platform: state
        entity_id: sensor.t3_100006205_pet_weight
    sensor:
      - name: "Kiki's Weight"
        unit_of_measurement: "lbs"
        unique_id: "sensor.kiki_s_weight"
        state: "{{(states('sensor.t3_100006205_pet_weight') | float(trigger.from_state.state|float(0)) * 0.00220462) | round(2)}}"
bluefoxlee commented 2 years ago

It seems Petkit just add cat identification function few days ago. Wonder if its just pull the weight data and display on app or will add new attribute?

IMG_8960

bdoooh commented 2 years ago

Would it be possible to add an action to turn on the light in the Pura Max? Not sure if anyone else has this desire but I'm sure there's an automation in HA where we can hit the light service every x minutes to keep it on.

bdoooh commented 2 years ago

Would it be possible to add an action to turn on the light in the Pura Max? Not sure if anyone else has this desire but I'm sure there's an automation in HA where we can hit the light service every x minutes to keep it on.

@al-one I sniffed the data and tested in Postman.. It looks like the light is just a toggle and the state comes through the other data referenced above. The payload to toggle the light is..

id=xxxxxxxx
kv={"start_action": 7}
type="start"
al-one commented 2 years ago

@bdoooh Try service: petkit.request_api.