pypetkitapi 1.7.9__tar.gz → 1.7.10__tar.gz
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-1.7.9 → pypetkitapi-1.7.10}/PKG-INFO +2 -2
- pypetkitapi-1.7.10/pypetkitapi/__init__.py +56 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/const.py +18 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/containers.py +17 -14
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/feeder_container.py +31 -29
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/litter_container.py +3 -3
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pyproject.toml +6 -3
- pypetkitapi-1.7.9/pypetkitapi/__init__.py +0 -1
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/LICENSE +0 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/README.md +0 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/client.py +0 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/command.py +0 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/exceptions.py +0 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/medias.py +0 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/py.typed +0 -0
- {pypetkitapi-1.7.9 → pypetkitapi-1.7.10}/pypetkitapi/water_fountain_container.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pypetkitapi
|
3
|
-
Version: 1.7.
|
3
|
+
Version: 1.7.10
|
4
4
|
Summary: Python client for PetKit API
|
5
5
|
Home-page: https://github.com/Jezza34000/pypetkit
|
6
6
|
License: MIT
|
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Requires-Dist: aiofiles (>=24.1.0,<25.0.0)
|
16
16
|
Requires-Dist: aiohttp (>=3.10.10,<4.0.0)
|
17
17
|
Requires-Dist: pycryptodome (>=3.19.1,<4.0.0)
|
18
|
-
Requires-Dist: pydantic (>=1.10.18,<
|
18
|
+
Requires-Dist: pydantic (>=1.10.18,<3.0.0)
|
19
19
|
Description-Content-Type: text/markdown
|
20
20
|
|
21
21
|
# Petkit API Client
|
@@ -0,0 +1,56 @@
|
|
1
|
+
"""Pypetkit: A Python library for interfacing with PetKit"""
|
2
|
+
|
3
|
+
from .client import PetKitClient
|
4
|
+
from .command import FeederCommand, LBAction, LBCommand, LitterCommand, PetCommand
|
5
|
+
from .const import (
|
6
|
+
CTW3,
|
7
|
+
D3,
|
8
|
+
D4,
|
9
|
+
D4H,
|
10
|
+
D4S,
|
11
|
+
DEVICES_FEEDER,
|
12
|
+
DEVICES_LITTER_BOX,
|
13
|
+
DEVICES_WATER_FOUNTAIN,
|
14
|
+
FEEDER,
|
15
|
+
FEEDER_MINI,
|
16
|
+
K2,
|
17
|
+
K3,
|
18
|
+
T3,
|
19
|
+
T4,
|
20
|
+
T5,
|
21
|
+
T6,
|
22
|
+
W5,
|
23
|
+
RecordType,
|
24
|
+
)
|
25
|
+
from .medias import MediaHandler, MediasFiles
|
26
|
+
|
27
|
+
__version__ = "1.7.10"
|
28
|
+
|
29
|
+
__all__ = [
|
30
|
+
"MediasFiles",
|
31
|
+
"MediaHandler",
|
32
|
+
"D3",
|
33
|
+
"D4",
|
34
|
+
"D4H",
|
35
|
+
"D4S",
|
36
|
+
"FEEDER",
|
37
|
+
"FEEDER_MINI",
|
38
|
+
"T3",
|
39
|
+
"T4",
|
40
|
+
"T5",
|
41
|
+
"T6",
|
42
|
+
"W5",
|
43
|
+
"CTW3",
|
44
|
+
"K2",
|
45
|
+
"K3",
|
46
|
+
"DEVICES_FEEDER",
|
47
|
+
"DEVICES_LITTER_BOX",
|
48
|
+
"DEVICES_WATER_FOUNTAIN",
|
49
|
+
"RecordType",
|
50
|
+
"PetKitClient",
|
51
|
+
"FeederCommand",
|
52
|
+
"LitterCommand",
|
53
|
+
"PetCommand",
|
54
|
+
"LBCommand",
|
55
|
+
"LBAction",
|
56
|
+
]
|
@@ -29,6 +29,7 @@ T6 = "t6"
|
|
29
29
|
W5 = "w5"
|
30
30
|
CTW3 = "ctw3"
|
31
31
|
K2 = "k2"
|
32
|
+
K3 = "k3"
|
32
33
|
|
33
34
|
DEVICES_LITTER_BOX = [T3, T4, T5, T6]
|
34
35
|
DEVICES_FEEDER = [FEEDER, FEEDER_MINI, D3, D4, D4S, D4H, D4SH]
|
@@ -86,6 +87,18 @@ LOGIN_DATA = {
|
|
86
87
|
}
|
87
88
|
|
88
89
|
|
90
|
+
class RecordType(StrEnum):
|
91
|
+
"""Record Type constants"""
|
92
|
+
|
93
|
+
EAT = "eat"
|
94
|
+
FEED = "feed"
|
95
|
+
MOVE = "move"
|
96
|
+
PET = "pet"
|
97
|
+
|
98
|
+
|
99
|
+
RecordTypeLST = [RecordType.EAT, RecordType.FEED, RecordType.MOVE, RecordType.PET]
|
100
|
+
|
101
|
+
|
89
102
|
class PetkitEndpoint(StrEnum):
|
90
103
|
"""Petkit Endpoint constants"""
|
91
104
|
|
@@ -119,6 +132,11 @@ class PetkitEndpoint(StrEnum):
|
|
119
132
|
STATISTIC_RELEASE = "statisticRelease"
|
120
133
|
GET_PET_OUT_GRAPH = "getPetOutGraph"
|
121
134
|
|
135
|
+
# Video features
|
136
|
+
CLOUD_VIDEO = "cloud/video"
|
137
|
+
GET_DOWNLOAD_M3U8 = "getDownloadM3u8"
|
138
|
+
GET_M3U8 = "getM3u8"
|
139
|
+
|
122
140
|
# Feeders
|
123
141
|
REPLENISHED_FOOD = "added"
|
124
142
|
FRESH_ELEMENT_CALIBRATION = "food_reset"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Dataclasses container for petkit API."""
|
2
2
|
|
3
|
-
from pydantic import BaseModel, Field
|
3
|
+
from pydantic import BaseModel, Field
|
4
4
|
|
5
5
|
|
6
6
|
class RegionInfo(BaseModel):
|
@@ -69,25 +69,28 @@ class Pet(BaseModel):
|
|
69
69
|
created_at: int = Field(alias="createdAt")
|
70
70
|
pet_id: int = Field(alias="petId")
|
71
71
|
pet_name: str | None = Field(None, alias="petName")
|
72
|
-
id: int | None = None # Fictive field (for HA compatibility)
|
73
|
-
sn: str # Fictive field (for HA compatibility)
|
74
|
-
name: str | None = None # Fictive field (for HA compatibility)
|
75
|
-
device_type: str = "pet" # Fictive field (for HA compatibility)
|
76
|
-
firmware: str | None = None # Fictive field (for HA compatibility)
|
72
|
+
id: int | None = None # Fictive field copied from id (for HA compatibility)
|
73
|
+
sn: str | None = None # Fictive field copied from id (for HA compatibility)
|
74
|
+
name: str | None = None # Fictive field copied from pet_name (for HA compatibility)
|
75
|
+
device_type: str = "pet" # Fictive fixed field (for HA compatibility)
|
76
|
+
firmware: str | None = None # Fictive fixed field (for HA compatibility)
|
77
77
|
|
78
|
-
#
|
78
|
+
# Litter stats
|
79
79
|
last_litter_usage: int = 0
|
80
80
|
last_device_used: str | None = None
|
81
81
|
last_duration_usage: int = 0
|
82
82
|
last_measured_weight: int = 0
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
def __init__(self, **data):
|
85
|
+
"""Initialize the Pet dataclass.
|
86
|
+
This method is used to fill the fictive fields after the standard initialization.
|
87
|
+
"""
|
88
|
+
# Appeler l'initialisation standard de Pydantic
|
89
|
+
super().__init__(**data)
|
90
|
+
# Remplir les champs fictifs après l'initialisation
|
91
|
+
self.id = self.id or self.pet_id
|
92
|
+
self.sn = self.sn or str(self.id)
|
93
|
+
self.name = self.name or self.pet_name
|
91
94
|
|
92
95
|
|
93
96
|
class User(BaseModel):
|
@@ -12,12 +12,12 @@ from pypetkitapi.containers import CloudProduct, Device, FirmwareDetail, Wifi
|
|
12
12
|
class FeedItem(BaseModel):
|
13
13
|
"""Dataclass for feed item data."""
|
14
14
|
|
15
|
-
id: str | None = None
|
16
|
-
name: str | None = None
|
17
|
-
time: int | None = None
|
18
15
|
amount: int | None = None
|
19
16
|
amount1: int | None = Field(None, alias="amount1")
|
20
17
|
amount2: int | None = Field(None, alias="amount2")
|
18
|
+
id: str | None = None
|
19
|
+
name: str | None = None
|
20
|
+
time: int | None = None
|
21
21
|
|
22
22
|
|
23
23
|
class FeedDailyList(BaseModel):
|
@@ -50,9 +50,14 @@ class SettingsFeeder(BaseModel):
|
|
50
50
|
attire_id: int | None = Field(None, alias="attireId")
|
51
51
|
attire_switch: int | None = Field(None, alias="attireSwitch")
|
52
52
|
auto_product: int | None = Field(None, alias="autoProduct")
|
53
|
+
bucket_name1: str | None = Field(None, alias="bucketName1")
|
54
|
+
bucket_name2: str | None = Field(None, alias="bucketName2")
|
53
55
|
camera: int | None = None
|
54
56
|
camera_config: int | None = Field(None, alias="cameraConfig")
|
57
|
+
camera_multi_new: list[CameraMultiNew] | None = Field(None, alias="cameraMultiNew")
|
55
58
|
camera_multi_range: list | None = Field(None, alias="cameraMultiRange")
|
59
|
+
color_setting: int | None = None
|
60
|
+
conservation: int | None = None
|
56
61
|
control_settings: int | None = Field(None, alias="controlSettings")
|
57
62
|
desiccant_notify: int | None = Field(None, alias="desiccantNotify")
|
58
63
|
detect_config: int | None = Field(None, alias="detectConfig")
|
@@ -62,8 +67,10 @@ class SettingsFeeder(BaseModel):
|
|
62
67
|
eat_notify: int | None = Field(None, alias="eatNotify")
|
63
68
|
eat_sensitivity: int | None = Field(None, alias="eatSensitivity")
|
64
69
|
eat_video: int | None = Field(None, alias="eatVideo")
|
70
|
+
factor: int | None = None
|
65
71
|
feed_notify: int | None = Field(None, alias="feedNotify")
|
66
72
|
feed_picture: int | None = Field(None, alias="feedPicture")
|
73
|
+
feed_sound: int | None = Field(None, alias="feedSound")
|
67
74
|
food_notify: int | None = Field(None, alias="foodNotify")
|
68
75
|
food_warn: int | None = Field(None, alias="foodWarn")
|
69
76
|
food_warn_range: list[int] | None = Field(None, alias="foodWarnRange")
|
@@ -87,6 +94,7 @@ class SettingsFeeder(BaseModel):
|
|
87
94
|
pet_sensitivity: int | None = Field(None, alias="petSensitivity")
|
88
95
|
pre_live: int | None = Field(None, alias="preLive")
|
89
96
|
selected_sound: int | None = Field(None, alias="selectedSound")
|
97
|
+
shortest: int | None = None # D4S
|
90
98
|
smart_frame: int | None = Field(None, alias="smartFrame")
|
91
99
|
sound_enable: int | None = Field(None, alias="soundEnable")
|
92
100
|
surplus: int | None = None # D3
|
@@ -99,35 +107,29 @@ class SettingsFeeder(BaseModel):
|
|
99
107
|
tone_multi_range: list[tuple[int, int]] | None = Field(None, alias="toneMultiRange")
|
100
108
|
upload: int | None = None
|
101
109
|
volume: int | None = None
|
102
|
-
feed_sound: int | None = Field(None, alias="feedSound")
|
103
|
-
factor: int | None = None
|
104
|
-
color_setting: int | None = Field(None, alias="colorSetting")
|
105
|
-
conservation: int | None = None
|
106
|
-
bucket_name1: str | None = Field(None, alias="bucketName1")
|
107
|
-
bucket_name2: str | None = Field(None, alias="bucketName2")
|
108
|
-
camera_multi_new: list[CameraMultiNew] | None = Field(None, alias="cameraMultiNew")
|
109
110
|
|
110
111
|
|
111
112
|
class FeedState(BaseModel):
|
112
113
|
"""Dataclass for feed state data."""
|
113
114
|
|
115
|
+
add_amount_total: int | None = Field(None, alias="addAmountTotal")
|
116
|
+
add_amount_total1: int | None = Field(None, alias="addAmountTotal1")
|
117
|
+
add_amount_total2: int | None = Field(None, alias="addAmountTotal2")
|
118
|
+
eat_amount_total: int | None = Field(None, alias="eatAmountTotal") # D3
|
114
119
|
eat_avg: int | None = Field(None, alias="eatAvg")
|
115
120
|
eat_count: int | None = Field(None, alias="eatCount")
|
116
121
|
eat_times: list[int] | None = Field(None, alias="eatTimes")
|
117
122
|
feed_times: dict | list | None = Field(None, alias="feedTimes")
|
118
|
-
times: int | None = None
|
119
|
-
add_amount_total: int | None = Field(None, alias="addAmountTotal")
|
120
123
|
plan_amount_total: int | None = Field(None, alias="planAmountTotal")
|
121
|
-
plan_real_amount_total: int | None = Field(None, alias="planRealAmountTotal")
|
122
|
-
real_amount_total: int | None = Field(None, alias="realAmountTotal")
|
123
|
-
add_amount_total1: int | None = Field(None, alias="addAmountTotal1")
|
124
|
-
add_amount_total2: int | None = Field(None, alias="addAmountTotal2")
|
125
124
|
plan_amount_total1: int | None = Field(None, alias="planAmountTotal1")
|
126
125
|
plan_amount_total2: int | None = Field(None, alias="planAmountTotal2")
|
126
|
+
plan_real_amount_total: int | None = Field(None, alias="planRealAmountTotal")
|
127
127
|
plan_real_amount_total1: int | None = Field(None, alias="planRealAmountTotal1")
|
128
128
|
plan_real_amount_total2: int | None = Field(None, alias="planRealAmountTotal2")
|
129
|
+
real_amount_total: int | None = Field(None, alias="realAmountTotal")
|
129
130
|
real_amount_total1: int | None = Field(None, alias="realAmountTotal1")
|
130
131
|
real_amount_total2: int | None = Field(None, alias="realAmountTotal2")
|
132
|
+
times: int | None = None
|
131
133
|
|
132
134
|
|
133
135
|
class StateFeeder(BaseModel):
|
@@ -135,31 +137,31 @@ class StateFeeder(BaseModel):
|
|
135
137
|
|
136
138
|
battery_power: int | None = Field(None, alias="batteryPower")
|
137
139
|
battery_status: int | None = Field(None, alias="batteryStatus")
|
138
|
-
bowl: int | None = None
|
139
140
|
block: int | None = None
|
141
|
+
bowl: int | None = None
|
140
142
|
broadcast: dict | None = None
|
141
143
|
camera_status: int | None = Field(None, alias="cameraStatus")
|
142
144
|
charge: int | None = None
|
145
|
+
conservation_status: int | None = Field(None, alias="conservationStatus")
|
143
146
|
desiccant_left_days: int | None = Field(None, alias="desiccantLeftDays")
|
144
147
|
desiccant_time: int | None = Field(None, alias="desiccantTime")
|
145
148
|
door: int | None = None
|
146
|
-
|
147
|
-
feeding: int | None = None
|
149
|
+
eating: int | None = None
|
148
150
|
error_code: str | None = Field(None, alias="errorCode")
|
149
151
|
error_detail: str | None = Field(None, alias="errorDetail")
|
150
152
|
error_level: int | None = Field(None, alias="errorLevel")
|
151
153
|
error_msg: str | None = Field(None, alias="errorMsg")
|
154
|
+
feed_state: FeedState | None = Field(None, alias="feedState")
|
155
|
+
feeding: int | None = None
|
156
|
+
food: int | None = None
|
157
|
+
food1: int | None = Field(None, alias="food1")
|
158
|
+
food2: int | None = Field(None, alias="food2")
|
152
159
|
ota: int | None = None
|
153
160
|
overall: int | None = None
|
154
161
|
pim: int | None = None
|
155
162
|
runtime: int | None = None
|
156
163
|
weight: int | None = None
|
157
164
|
wifi: Wifi | None = None
|
158
|
-
eating: int | None = None
|
159
|
-
food: int | None = None
|
160
|
-
food1: int | None = Field(None, alias="food1")
|
161
|
-
food2: int | None = Field(None, alias="food2")
|
162
|
-
conservation_status: int | None = Field(None, alias="conservationStatus")
|
163
165
|
|
164
166
|
|
165
167
|
class ManualFeed(BaseModel):
|
@@ -302,15 +304,20 @@ class Feeder(BaseModel):
|
|
302
304
|
bt_mac: str | None = Field(None, alias="btMac")
|
303
305
|
cloud_product: CloudProduct | None = Field(None, alias="cloudProduct")
|
304
306
|
created_at: str | None = Field(None, alias="createdAt")
|
307
|
+
device_records: FeederRecord | None = None
|
308
|
+
device_type: str | None = Field(None, alias="deviceType")
|
305
309
|
firmware: float
|
306
310
|
firmware_details: list[FirmwareDetail] | None = Field(None, alias="firmwareDetails")
|
307
311
|
hardware: int
|
308
312
|
id: int
|
309
313
|
locale: str | None = None
|
310
314
|
mac: str | None = None
|
315
|
+
manual_feed: ManualFeed | None = None
|
311
316
|
model_code: int | None = Field(None, alias="modelCode")
|
317
|
+
multi_config: bool | None = Field(None, alias="multiConfig")
|
312
318
|
multi_feed_item: MultiFeedItem | None = Field(None, alias="multiFeedItem")
|
313
319
|
name: str | None = None
|
320
|
+
p2p_type: int | None = Field(None, alias="p2pType")
|
314
321
|
secret: str | None = None
|
315
322
|
service_status: int | None = Field(None, alias="serviceStatus")
|
316
323
|
settings: SettingsFeeder | None = None
|
@@ -319,11 +326,6 @@ class Feeder(BaseModel):
|
|
319
326
|
sn: str
|
320
327
|
state: StateFeeder | None = None
|
321
328
|
timezone: float | None = None
|
322
|
-
p2p_type: int | None = Field(None, alias="p2pType")
|
323
|
-
multi_config: bool | None = Field(None, alias="multiConfig")
|
324
|
-
device_type: str | None = Field(None, alias="deviceType")
|
325
|
-
manual_feed: ManualFeed | None = None
|
326
|
-
device_records: FeederRecord | None = None
|
327
329
|
|
328
330
|
@classmethod
|
329
331
|
def get_endpoint(cls, device_type: str) -> str:
|
@@ -10,6 +10,7 @@ from pypetkitapi.const import (
|
|
10
10
|
DEVICE_RECORDS,
|
11
11
|
DEVICE_STATS,
|
12
12
|
T4,
|
13
|
+
T5,
|
13
14
|
T6,
|
14
15
|
PetkitEndpoint,
|
15
16
|
)
|
@@ -77,7 +78,6 @@ class SettingsLitter(BaseModel):
|
|
77
78
|
pet_detection: int | None = Field(None, alias="petDetection")
|
78
79
|
pet_notify: int | None = Field(None, alias="petNotify")
|
79
80
|
pre_live: int | None = Field(None, alias="preLive")
|
80
|
-
shortest: int | None = None
|
81
81
|
system_sound_enable: int | None = Field(None, alias="systemSoundEnable")
|
82
82
|
time_display: int | None = Field(None, alias="timeDisplay")
|
83
83
|
toilet_detection: int | None = Field(None, alias="toiletDetection")
|
@@ -242,7 +242,7 @@ class LitterRecord(BaseModel):
|
|
242
242
|
"""Get the endpoint URL for the given device type."""
|
243
243
|
if device_type == T4:
|
244
244
|
return PetkitEndpoint.GET_DEVICE_RECORD
|
245
|
-
if device_type
|
245
|
+
if device_type in [T5, T6]:
|
246
246
|
return PetkitEndpoint.GET_DEVICE_RECORD_RELEASE
|
247
247
|
raise ValueError(f"Invalid device type: {device_type}")
|
248
248
|
|
@@ -259,7 +259,7 @@ class LitterRecord(BaseModel):
|
|
259
259
|
if request_date is None:
|
260
260
|
request_date = datetime.now().strftime("%Y%m%d")
|
261
261
|
return {"date": int(request_date), "deviceId": device.device_id}
|
262
|
-
if device_type
|
262
|
+
if device_type in [T5, T6]:
|
263
263
|
return {
|
264
264
|
"timestamp": int(datetime.now().timestamp()),
|
265
265
|
"deviceId": device.device_id,
|
@@ -187,7 +187,7 @@ build-backend = "poetry.core.masonry.api"
|
|
187
187
|
|
188
188
|
[tool.poetry]
|
189
189
|
name = "pypetkitapi"
|
190
|
-
version = "1.7.
|
190
|
+
version = "1.7.10"
|
191
191
|
description = "Python client for PetKit API"
|
192
192
|
authors = ["Jezza34000 <info@mail.com>"]
|
193
193
|
readme = "README.md"
|
@@ -199,7 +199,7 @@ python = ">=3.11"
|
|
199
199
|
aiohttp = "^3.10.10"
|
200
200
|
aiofiles = "^24.1.0"
|
201
201
|
pycryptodome = "^3.19.1"
|
202
|
-
pydantic = "
|
202
|
+
pydantic = ">=1.10.18,<3.0.0"
|
203
203
|
|
204
204
|
[tool.poetry.dev-dependencies]
|
205
205
|
pre-commit = "^4.0.1"
|
@@ -208,7 +208,7 @@ ruff = "^0.8.1"
|
|
208
208
|
types-aiofiles = "^24.1.0.20240626"
|
209
209
|
|
210
210
|
[tool.bumpver]
|
211
|
-
current_version = "1.7.
|
211
|
+
current_version = "1.7.10"
|
212
212
|
version_pattern = "MAJOR.MINOR.PATCH"
|
213
213
|
commit_message = "bump version {old_version} -> {new_version}"
|
214
214
|
tag_message = "{new_version}"
|
@@ -224,6 +224,9 @@ push = true
|
|
224
224
|
'^version = "{version}"',
|
225
225
|
'^current_version = "{version}"',
|
226
226
|
]
|
227
|
+
"pypetkitapi/__init__.py" = [
|
228
|
+
'^__version__ = "{version}"',
|
229
|
+
]
|
227
230
|
|
228
231
|
[tool.tox]
|
229
232
|
envlist = ["pre-commit"]
|
@@ -1 +0,0 @@
|
|
1
|
-
"""Pypetkit: A Python library for interfacing with PetKit"""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|