pypetkitapi 1.12.6__py3-none-any.whl → 1.15.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pypetkitapi/__init__.py +1 -1
- pypetkitapi/client.py +27 -1
- pypetkitapi/command.py +3 -3
- pypetkitapi/const.py +3 -3
- pypetkitapi/containers.py +38 -1
- pypetkitapi/litter_container.py +2 -26
- pypetkitapi/purifier_container.py +16 -2
- {pypetkitapi-1.12.6.dist-info → pypetkitapi-1.15.0.dist-info}/METADATA +2 -2
- pypetkitapi-1.15.0.dist-info/RECORD +19 -0
- pypetkitapi-1.12.6.dist-info/RECORD +0 -19
- {pypetkitapi-1.12.6.dist-info → pypetkitapi-1.15.0.dist-info}/LICENSE +0 -0
- {pypetkitapi-1.12.6.dist-info → pypetkitapi-1.15.0.dist-info}/WHEEL +0 -0
pypetkitapi/__init__.py
CHANGED
pypetkitapi/client.py
CHANGED
@@ -38,7 +38,14 @@ from pypetkitapi.const import (
|
|
38
38
|
PetkitDomain,
|
39
39
|
PetkitEndpoint,
|
40
40
|
)
|
41
|
-
from pypetkitapi.containers import
|
41
|
+
from pypetkitapi.containers import (
|
42
|
+
AccountData,
|
43
|
+
Device,
|
44
|
+
Pet,
|
45
|
+
PetDetails,
|
46
|
+
RegionInfo,
|
47
|
+
SessionInfo,
|
48
|
+
)
|
42
49
|
from pypetkitapi.exceptions import (
|
43
50
|
PetkitAuthenticationError,
|
44
51
|
PetkitAuthenticationUnregisteredEmailError,
|
@@ -227,6 +234,18 @@ class PetKitClient:
|
|
227
234
|
raise PetkitSessionError("No session ID available")
|
228
235
|
return {"F-Session": self._session.id, "X-Session": self._session.id}
|
229
236
|
|
237
|
+
async def _get_pet_details(self) -> list[PetDetails]:
|
238
|
+
"""Fetch pet details from the PetKit API."""
|
239
|
+
_LOGGER.debug("Fetching user details")
|
240
|
+
response = await self.req.request(
|
241
|
+
method=HTTPMethod.GET,
|
242
|
+
url=PetkitEndpoint.DETAILS,
|
243
|
+
headers=await self.get_session_id(),
|
244
|
+
)
|
245
|
+
user_details = response.get("user", {})
|
246
|
+
dogs = user_details.get("dogs", [])
|
247
|
+
return [PetDetails(**dog) for dog in dogs]
|
248
|
+
|
230
249
|
async def _get_account_data(self) -> None:
|
231
250
|
"""Get the account data from the PetKit service."""
|
232
251
|
_LOGGER.debug("Fetching account data")
|
@@ -253,6 +272,13 @@ class PetKitClient:
|
|
253
272
|
uniqueId=str(pet.sn),
|
254
273
|
)
|
255
274
|
|
275
|
+
# Fetch pet details and update pet information
|
276
|
+
pet_details_list = await self._get_pet_details()
|
277
|
+
for pet_details in pet_details_list:
|
278
|
+
pet_id = pet_details.id
|
279
|
+
if pet_id in self.petkit_entities:
|
280
|
+
self.petkit_entities[pet_id].pet_details = pet_details
|
281
|
+
|
256
282
|
async def get_devices_data(self) -> None:
|
257
283
|
"""Get the devices data from the PetKit servers."""
|
258
284
|
start_time = datetime.now()
|
pypetkitapi/command.py
CHANGED
@@ -98,7 +98,7 @@ class DeviceAction(StrEnum):
|
|
98
98
|
END = "end_action"
|
99
99
|
START = "start_action"
|
100
100
|
STOP = "stop_action"
|
101
|
-
# Purifier only
|
101
|
+
# Purifier K2 only
|
102
102
|
MODE = "mode_action"
|
103
103
|
# All devices
|
104
104
|
POWER = "power_action"
|
@@ -159,8 +159,8 @@ def get_endpoint_reset_desiccant(device):
|
|
159
159
|
|
160
160
|
def get_endpoint_update_setting(device):
|
161
161
|
"""Get the endpoint for the device"""
|
162
|
-
if device.device_nfo.device_type
|
163
|
-
return PetkitEndpoint.
|
162
|
+
if device.device_nfo.device_type in [FEEDER_MINI, K3]:
|
163
|
+
return PetkitEndpoint.UPDATE_SETTING_OLD
|
164
164
|
return PetkitEndpoint.UPDATE_SETTING
|
165
165
|
|
166
166
|
|
pypetkitapi/const.py
CHANGED
@@ -46,7 +46,7 @@ DEVICES_FEEDER = [FEEDER, FEEDER_MINI, D3, D4, D4S, D4H, D4SH]
|
|
46
46
|
# Water Fountain
|
47
47
|
DEVICES_WATER_FOUNTAIN = [W4, W5, CTW2, CTW3]
|
48
48
|
# Purifier
|
49
|
-
DEVICES_PURIFIER = [K2]
|
49
|
+
DEVICES_PURIFIER = [K2, K3]
|
50
50
|
# All devices
|
51
51
|
ALL_DEVICES = [
|
52
52
|
*DEVICES_LITTER_BOX,
|
@@ -78,7 +78,7 @@ class Header(StrEnum):
|
|
78
78
|
ACCEPT = "*/*"
|
79
79
|
ACCEPT_LANG = "en-US;q=1, it-US;q=0.9"
|
80
80
|
ENCODING = "gzip, deflate"
|
81
|
-
API_VERSION = "12.0
|
81
|
+
API_VERSION = "12.1.0"
|
82
82
|
CONTENT_TYPE = "application/x-www-form-urlencoded"
|
83
83
|
AGENT = "okhttp/3.12.11"
|
84
84
|
CLIENT = f"{Client.PLATFORM_TYPE}({Client.OS_VERSION};{Client.MODEL_NAME})"
|
@@ -152,7 +152,7 @@ class PetkitEndpoint(StrEnum):
|
|
152
152
|
GET_DEVICE_RECORD = "getDeviceRecord"
|
153
153
|
GET_DEVICE_RECORD_RELEASE = "getDeviceRecordRelease"
|
154
154
|
UPDATE_SETTING = "updateSettings"
|
155
|
-
|
155
|
+
UPDATE_SETTING_OLD = "update"
|
156
156
|
|
157
157
|
# Bluetooth
|
158
158
|
BLE_AS_RELAY = "ble/ownSupportBleDevices"
|
pypetkitapi/containers.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
"""Dataclasses container for petkit API."""
|
2
2
|
|
3
|
+
from typing import Any
|
4
|
+
|
3
5
|
from pydantic import BaseModel, Field, field_validator
|
4
6
|
|
5
7
|
|
@@ -68,6 +70,40 @@ class Device(BaseModel):
|
|
68
70
|
return value
|
69
71
|
|
70
72
|
|
73
|
+
class PetDetails(BaseModel):
|
74
|
+
"""Dataclass for pet details.
|
75
|
+
Subclass of Pet.
|
76
|
+
"""
|
77
|
+
|
78
|
+
active_degree: int | None = Field(None, alias="activeDegree")
|
79
|
+
avatar: str | None = None
|
80
|
+
birth: str | None = None
|
81
|
+
block_time: int | None = Field(None, alias="blockTime")
|
82
|
+
blocke: int | None = None
|
83
|
+
body_info: dict[str, Any] | None = Field(None, alias="bodyInfo")
|
84
|
+
category: dict[str, Any]
|
85
|
+
created_at: str | None = Field(None, alias="createdAt")
|
86
|
+
device_count: int | None = Field(None, alias="deviceCount")
|
87
|
+
emotion: int | None = None
|
88
|
+
family_id: int | None = Field(None, alias="familyId")
|
89
|
+
female_state: int | None = Field(None, alias="femaleState")
|
90
|
+
gender: int | None = None
|
91
|
+
id: int | None = None
|
92
|
+
is_royal_canin_pet: int | None = Field(None, alias="isRoyalCaninPet")
|
93
|
+
male_state: int | None = Field(None, alias="maleState")
|
94
|
+
name: str | None = None
|
95
|
+
oms_discern_pic: dict[str, Any] | None = Field(None, alias="omsDiscernPic")
|
96
|
+
owner: dict[str, Any] | None = None
|
97
|
+
size: dict[str, Any] | None = None
|
98
|
+
states: list[Any] | None = None
|
99
|
+
type: dict[str, Any] | None = None
|
100
|
+
updated_at: str | None = Field(None, alias="updatedAt")
|
101
|
+
weight: float | None = None
|
102
|
+
weight_control: int | None = Field(None, alias="weightControl")
|
103
|
+
weight_control_tips: dict[str, Any] | None = Field(None, alias="weightControlTips")
|
104
|
+
weight_label: str | None = Field(None, alias="weightLabel")
|
105
|
+
|
106
|
+
|
71
107
|
class Pet(BaseModel):
|
72
108
|
"""Dataclass for pet data.
|
73
109
|
Subclass of AccountData.
|
@@ -81,7 +117,8 @@ class Pet(BaseModel):
|
|
81
117
|
sn: str | None = None # Fictive field copied from id (for HA compatibility)
|
82
118
|
name: str | None = None # Fictive field copied from pet_name (for HA compatibility)
|
83
119
|
firmware: str | None = None # Fictive fixed field (for HA compatibility)
|
84
|
-
device_nfo: Device | None = None
|
120
|
+
device_nfo: Device | None = None
|
121
|
+
pet_details: PetDetails | None = None
|
85
122
|
|
86
123
|
# Litter stats
|
87
124
|
last_litter_usage: int | None = None
|
pypetkitapi/litter_container.py
CHANGED
@@ -21,6 +21,7 @@ from pypetkitapi.containers import (
|
|
21
21
|
UserDevice,
|
22
22
|
Wifi,
|
23
23
|
)
|
24
|
+
from pypetkitapi.purifier_container import Purifier
|
24
25
|
|
25
26
|
|
26
27
|
class SettingsLitter(BaseModel):
|
@@ -386,31 +387,6 @@ class PetOutGraph(BaseModel):
|
|
386
387
|
}
|
387
388
|
|
388
389
|
|
389
|
-
class K3Device(BaseModel):
|
390
|
-
"""Dataclass for K3 device data."""
|
391
|
-
|
392
|
-
battery: int | None = None
|
393
|
-
created_at: datetime | None = Field(None, alias="createdAt")
|
394
|
-
firmware: int | None = None
|
395
|
-
hardware: int | None = None
|
396
|
-
id: int | None = None
|
397
|
-
lighting: int | None = None
|
398
|
-
liquid: int | None = None
|
399
|
-
liquid_lack: int | None = Field(None, alias="liquidLack")
|
400
|
-
mac: str | None = None
|
401
|
-
name: str | None = None
|
402
|
-
refreshing: int | None = None
|
403
|
-
relate_t4: int | None = Field(None, alias="relateT4")
|
404
|
-
relation: dict | None = None
|
405
|
-
secret: str | None = None
|
406
|
-
settings: dict | None = None
|
407
|
-
sn: str | None = None
|
408
|
-
timezone: float | None = None
|
409
|
-
update_at: datetime | None = Field(None, alias="updateAt")
|
410
|
-
user_id: str | None = Field(None, alias="userId")
|
411
|
-
voltage: int | None = None
|
412
|
-
|
413
|
-
|
414
390
|
class Litter(BaseModel):
|
415
391
|
"""Dataclass for Litter Data.
|
416
392
|
Supported devices = T3, T4, T5, T6
|
@@ -425,7 +401,7 @@ class Litter(BaseModel):
|
|
425
401
|
firmware_details: list[FirmwareDetail] = Field(alias="firmwareDetails")
|
426
402
|
hardware: int
|
427
403
|
id: int
|
428
|
-
k3_device:
|
404
|
+
k3_device: Purifier | None = Field(None, alias="k3Device")
|
429
405
|
is_pet_out_tips: int | None = Field(None, alias="isPetOutTips")
|
430
406
|
locale: str | None = None
|
431
407
|
mac: str | None = None
|
@@ -4,7 +4,7 @@ from typing import Any, ClassVar
|
|
4
4
|
|
5
5
|
from pydantic import BaseModel, Field
|
6
6
|
|
7
|
-
from pypetkitapi.const import DEVICE_DATA, PetkitEndpoint
|
7
|
+
from pypetkitapi.const import DEVICE_DATA, K3, PetkitEndpoint
|
8
8
|
from pypetkitapi.containers import Device, FirmwareDetail, Wifi
|
9
9
|
|
10
10
|
|
@@ -12,9 +12,11 @@ class Settings(BaseModel):
|
|
12
12
|
"""Dataclass for settings data."""
|
13
13
|
|
14
14
|
auto_work: int | None = Field(None, alias="autoWork")
|
15
|
+
fixed_time_refresh: int | None = Field(None, alias="fixedTimeRefresh")
|
15
16
|
lack_notify: int | None = Field(None, alias="lackNotify")
|
16
17
|
light_mode: int | None = Field(None, alias="lightMode")
|
17
18
|
light_range: list[int] | None = Field(None, alias="lightRange")
|
19
|
+
liquid_lack_switch: int | None = Field(None, alias="liquidLackSwitch")
|
18
20
|
log_notify: int | None = Field(None, alias="logNotify")
|
19
21
|
manual_lock: int | None = Field(None, alias="manualLock")
|
20
22
|
sound: int | None = None
|
@@ -42,29 +44,41 @@ class Purifier(BaseModel):
|
|
42
44
|
|
43
45
|
data_type: ClassVar[str] = DEVICE_DATA
|
44
46
|
|
47
|
+
battery: int | None = None
|
45
48
|
bt_mac: str | None = Field(None, alias="btMac")
|
46
49
|
created_at: str | None = Field(None, alias="createdAt")
|
47
|
-
firmware: str | None = None
|
50
|
+
firmware: str | int | None = None
|
48
51
|
firmware_details: list[FirmwareDetail] | None = Field(None, alias="firmwareDetails")
|
49
52
|
hardware: int | None = None
|
50
53
|
id: int | None = None
|
54
|
+
lighting: int | None = None
|
55
|
+
liquid: int | None = None
|
56
|
+
liquid_lack: int | None = Field(None, alias="liquidLack")
|
51
57
|
locale: str | None = None
|
52
58
|
mac: str | None = None
|
53
59
|
name: str | None = None
|
60
|
+
refreshing: int | None = None
|
61
|
+
relate_t4: int | None = Field(None, alias="relateT4")
|
54
62
|
relation: dict[str, str]
|
55
63
|
secret: str | None = None
|
56
64
|
settings: Settings | None = None
|
57
65
|
share_open: int | None = Field(None, alias="shareOpen")
|
58
66
|
signup_at: str | None = Field(None, alias="signupAt")
|
59
67
|
sn: str | None = None
|
68
|
+
spray_times: int | None = Field(None, alias="sprayTimes")
|
60
69
|
state: State | None = None
|
61
70
|
timezone: float | None = None
|
71
|
+
update_at: str | None = Field(None, alias="updateAt")
|
72
|
+
user_id: str | None = Field(None, alias="userId")
|
73
|
+
voltage: int | None = None
|
62
74
|
work_time: list[tuple[int, int]] | None = Field(None, alias="workTime")
|
63
75
|
device_nfo: Device | None = None
|
64
76
|
|
65
77
|
@classmethod
|
66
78
|
def get_endpoint(cls, device_type: str) -> str:
|
67
79
|
"""Get the endpoint URL for the given device type."""
|
80
|
+
if device_type == K3:
|
81
|
+
return PetkitEndpoint.DEVICE_DATA
|
68
82
|
return PetkitEndpoint.DEVICE_DETAIL
|
69
83
|
|
70
84
|
@classmethod
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: pypetkitapi
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.15.0
|
4
4
|
Summary: Python client for PetKit API
|
5
5
|
License: MIT
|
6
6
|
Author: Jezza34000
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
23
23
|
|
24
24
|
---
|
25
25
|
|
26
|
-
[](https://github.com/Jezza34000/py-petkit-api/)
|
27
27
|
[][python version] [](https://github.com/Jezza34000/py-petkit-api/actions)
|
28
28
|
|
29
29
|
[][pypi_] [](https://pepy.tech/projects/pypetkitapi)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
pypetkitapi/__init__.py,sha256=sEgLSfzU-CM7h7-yfbyp_wr7WhyOl7Txz03Vh0VrDOE,2107
|
2
|
+
pypetkitapi/bluetooth.py,sha256=1zEZIrKNTttrZpqBiQ-6V37Uphft5_T8CH9OBfYjwxE,9915
|
3
|
+
pypetkitapi/client.py,sha256=cn3JIh-3AU5Rzka2rX7FgkSfWeQCG9Vw82-moK_rOPY,30889
|
4
|
+
pypetkitapi/command.py,sha256=sRLgV7bkG_kZAWf7Un_UNHL-OkJMH1GLD_RGgg9z8Mw,7515
|
5
|
+
pypetkitapi/const.py,sha256=aAUPBZC56MwbAiDRsSHRvDI5zTy-lZP8uLk-gHPeT7g,4763
|
6
|
+
pypetkitapi/containers.py,sha256=7wYKmaoBpMKrqIVMsoD4Iv2in7Kh5nNxrl4vC4eF2fg,6305
|
7
|
+
pypetkitapi/exceptions.py,sha256=4BXUyYXLfZjNxdnOGJPjyE9ASIl7JmQphjws87jvHtE,1631
|
8
|
+
pypetkitapi/feeder_container.py,sha256=PhidWd5WpsZqtdKZy60PzE67YXgQfApjm8CqvMCHK3U,14743
|
9
|
+
pypetkitapi/litter_container.py,sha256=R79wHFKy6pTsHIPf7bJko1PGFsdI-JCAPK4zPyliBmQ,18559
|
10
|
+
pypetkitapi/media.py,sha256=LNY3khU5eZN4i1MGHxJaPHcf3LA1fFaPVkn-wdn0YLI,27168
|
11
|
+
pypetkitapi/purifier_container.py,sha256=mAnvPF8Mm6YI43fitdxXEWScshM6sPg0KK6GXbylU1I,3179
|
12
|
+
pypetkitapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
+
pypetkitapi/schedule_container.py,sha256=ycIHeQHkVILDp7ZBjaVdGI_9rhHrgqeKBfvQAX3JMGE,2071
|
14
|
+
pypetkitapi/utils.py,sha256=z7325kcJQUburnF28HSXrJMvY_gY9007K73Zwxp-4DQ,743
|
15
|
+
pypetkitapi/water_fountain_container.py,sha256=5J0b-fDZYcFLNX2El7fifv8H6JMhBCt-ttxSow1ozRQ,6787
|
16
|
+
pypetkitapi-1.15.0.dist-info/LICENSE,sha256=u5jNkZEn6YMrtN4Kr5rU3TcBJ5-eAt0qMx4JDsbsnzM,1074
|
17
|
+
pypetkitapi-1.15.0.dist-info/METADATA,sha256=q3okbsikRZd38LsZQKABic_7teS3tVcB5rheUJH3oqI,6944
|
18
|
+
pypetkitapi-1.15.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
19
|
+
pypetkitapi-1.15.0.dist-info/RECORD,,
|
@@ -1,19 +0,0 @@
|
|
1
|
-
pypetkitapi/__init__.py,sha256=9aYDp2exciCKqaGEwL9K23dY3sH05gih03womG0NnII,2107
|
2
|
-
pypetkitapi/bluetooth.py,sha256=1zEZIrKNTttrZpqBiQ-6V37Uphft5_T8CH9OBfYjwxE,9915
|
3
|
-
pypetkitapi/client.py,sha256=62QzLypzCa6nEfR-Ihams6uQuYyKpu6yrFfnjfFu1Cc,30057
|
4
|
-
pypetkitapi/command.py,sha256=k04iC0ONiFx7pkr-LJI7qT3RprQ3ojT0jP6KWQk8eTQ,7514
|
5
|
-
pypetkitapi/const.py,sha256=tDCbvDbJHKZEy6L5Api59O1NE3mi9X61YTYTBv_6E9E,4767
|
6
|
-
pypetkitapi/containers.py,sha256=QshQ3PaN858jy0nSjeIZyyLijK_AfpzrIZeq2SDoqXQ,4816
|
7
|
-
pypetkitapi/exceptions.py,sha256=4BXUyYXLfZjNxdnOGJPjyE9ASIl7JmQphjws87jvHtE,1631
|
8
|
-
pypetkitapi/feeder_container.py,sha256=PhidWd5WpsZqtdKZy60PzE67YXgQfApjm8CqvMCHK3U,14743
|
9
|
-
pypetkitapi/litter_container.py,sha256=VIQZyZwmsxgMsV80Bc1lnYMqJyTZSaiqwE4Y_CNTD9Q,19338
|
10
|
-
pypetkitapi/media.py,sha256=LNY3khU5eZN4i1MGHxJaPHcf3LA1fFaPVkn-wdn0YLI,27168
|
11
|
-
pypetkitapi/purifier_container.py,sha256=ssyIxhNben5XJ4KlQTXTrtULg2ji6DqHqjzOq08d1-I,2491
|
12
|
-
pypetkitapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
-
pypetkitapi/schedule_container.py,sha256=ycIHeQHkVILDp7ZBjaVdGI_9rhHrgqeKBfvQAX3JMGE,2071
|
14
|
-
pypetkitapi/utils.py,sha256=z7325kcJQUburnF28HSXrJMvY_gY9007K73Zwxp-4DQ,743
|
15
|
-
pypetkitapi/water_fountain_container.py,sha256=5J0b-fDZYcFLNX2El7fifv8H6JMhBCt-ttxSow1ozRQ,6787
|
16
|
-
pypetkitapi-1.12.6.dist-info/LICENSE,sha256=u5jNkZEn6YMrtN4Kr5rU3TcBJ5-eAt0qMx4JDsbsnzM,1074
|
17
|
-
pypetkitapi-1.12.6.dist-info/METADATA,sha256=QaAgcHSi7rs1mRuz_LKb7zFPD3QHlqhnwd680OBC0bs,6946
|
18
|
-
pypetkitapi-1.12.6.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
19
|
-
pypetkitapi-1.12.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|