pypetkitapi 0.1.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/const.py ADDED
@@ -0,0 +1,112 @@
1
+ """Constants for the pypetkitapi library."""
2
+
3
+ from enum import StrEnum
4
+
5
+ MIN_FEED_AMOUNT = 0
6
+ MAX_FEED_AMOUNT = 10
7
+
8
+ RES_KEY = "result"
9
+ ERR_KEY = "error"
10
+ SUCCESS_KEY = "success"
11
+
12
+ # PetKit Models
13
+ FEEDER = "feeder"
14
+ FEEDER_MINI = "feedermini"
15
+ D3 = "d3"
16
+ D4 = "d4"
17
+ D4S = "d4s"
18
+ D4H = "d4h"
19
+ D4SH = "d4sh"
20
+ T3 = "t3"
21
+ T4 = "t4"
22
+ T5 = "t5"
23
+ T6 = "t6"
24
+ W5 = "w5"
25
+ CTW3 = "ctw3"
26
+ K2 = "k2"
27
+
28
+ DEVICES_LITTER_BOX = [T4, T5, T6]
29
+ DEVICES_FEEDER = [FEEDER, FEEDER_MINI, D4, D4S, D4H, D4SH]
30
+ DEVICES_WATER_FOUNTAIN = [W5, CTW3]
31
+ ALL_DEVICES = [*DEVICES_LITTER_BOX, *DEVICES_FEEDER, *DEVICES_WATER_FOUNTAIN]
32
+
33
+
34
+ class PetkitURL(StrEnum):
35
+ """Petkit URL constants"""
36
+
37
+ REGION_SRV = "https://passport.petkt.com/v1/regionservers"
38
+
39
+
40
+ class Client(StrEnum):
41
+ """Platform constants"""
42
+
43
+ PLATFORM_TYPE = "android"
44
+ OS_VERSION = "15.1"
45
+ MODEL_NAME = "23127PN0CG"
46
+ SOURCE = "app.petkit-android"
47
+
48
+
49
+ class Header(StrEnum):
50
+ """Header constants"""
51
+
52
+ ACCEPT = "*/*"
53
+ ACCEPT_LANG = "en-US;q=1, it-US;q=0.9"
54
+ ENCODING = "gzip, deflate"
55
+ API_VERSION = "11.3.1"
56
+ CONTENT_TYPE = "application/x-www-form-urlencoded"
57
+ AGENT = "okhttp/3.12.11"
58
+ CLIENT = f"{Client.PLATFORM_TYPE}({Client.OS_VERSION};{Client.MODEL_NAME})"
59
+ TIMEZONE = "1.0"
60
+ TIMEZONE_ID = "Europe/Paris"
61
+ LOCALE = "en-US"
62
+ IMG_VERSION = "1.0"
63
+ HOUR = "24"
64
+
65
+
66
+ CLIENT_NFO = {
67
+ "locale": Header.LOCALE.value,
68
+ "name": Client.MODEL_NAME.value,
69
+ "osVersion": Client.OS_VERSION.value,
70
+ "platform": Client.PLATFORM_TYPE.value,
71
+ "source": Client.SOURCE.value,
72
+ "timezone": Header.TIMEZONE.value,
73
+ "timezoneId": Header.TIMEZONE_ID.value,
74
+ "version": Header.API_VERSION.value,
75
+ }
76
+
77
+ LOGIN_DATA = {
78
+ "client": str(CLIENT_NFO),
79
+ "oldVersion": Header.API_VERSION,
80
+ }
81
+
82
+
83
+ class PetkitEndpoint(StrEnum):
84
+ """Petkit Endpoint constants"""
85
+
86
+ LOGIN = "user/login"
87
+ GET_LOGIN_CODE = "user/sendcodeforquicklogin"
88
+ REFRESH_SESSION = "user/refreshsession"
89
+ FAMILY_LIST = "group/family/list"
90
+ REFRESH_HOME_V2 = "refreshHomeV2"
91
+ DEVICE_DETAIL = "device_detail"
92
+ DEVICE_DATA = "deviceData"
93
+ GET_DEVICE_RECORD = "getDeviceRecord"
94
+ GET_DEVICE_RECORD_RELEASE = "getDeviceRecordRelease"
95
+ UPDATE_SETTING = "updateSettings"
96
+
97
+ # Litter Box
98
+ DEODORANT_RESET = "deodorantReset"
99
+ CONTROL_DEVICE = "controlDevice"
100
+
101
+ # Feeders
102
+ REPLENISHED_FOOD = "added"
103
+ FRESH_ELEMENT_CALIBRATION = "food_reset"
104
+ FRESH_ELEMENT_CANCEL_FEED = "cancel_realtime_feed"
105
+ DESICCANT_RESET = "desiccantReset"
106
+ MINI_DESICCANT_RESET = "feedermini/desiccant_reset"
107
+ FRESH_ELEMENT_DESICCANT_RESET = "feeder/desiccant_reset"
108
+ CALL_PET = "callPet"
109
+ CANCEL_FEED = "cancelRealtimeFeed"
110
+ MINI_MANUAL_FEED = "feedermini/save_dailyfeed"
111
+ FRESH_ELEMENT_MANUAL_FEED = "feeder/save_dailyfeed"
112
+ MANUAL_FEED = "saveDailyFeed"
@@ -0,0 +1,116 @@
1
+ """Dataclasses container for petkit API."""
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class RegionInfo(BaseModel):
7
+ """Dataclass for region data.
8
+ Fetched from the API endpoint :
9
+ - /v1/regionservers.
10
+ """
11
+
12
+ account_type: str = Field(alias="accountType")
13
+ gateway: str
14
+ id: str
15
+ name: str
16
+
17
+
18
+ class SessionInfo(BaseModel):
19
+ """Dataclass for session data.
20
+ Fetched from the API endpoint :
21
+ - user/login
22
+ - user/sendcodeforquicklogin
23
+ - user/refreshsession
24
+ """
25
+
26
+ id: str
27
+ user_id: str = Field(alias="userId")
28
+ expires_in: int = Field(alias="expiresIn")
29
+ region: str
30
+ created_at: str = Field(alias="createdAt")
31
+
32
+
33
+ class Device(BaseModel):
34
+ """Dataclass for device data.
35
+ Subclass of AccountData.
36
+ """
37
+
38
+ created_at: int = Field(alias="createdAt")
39
+ device_id: int = Field(alias="deviceId")
40
+ device_name: str = Field(alias="deviceName")
41
+ device_type: str = Field(alias="deviceType")
42
+ group_id: int = Field(alias="groupId")
43
+ type: int
44
+ type_code: int = Field(alias="typeCode")
45
+ unique_id: str = Field(alias="uniqueId")
46
+
47
+
48
+ class Pet(BaseModel):
49
+ """Dataclass for pet data.
50
+ Subclass of AccountData.
51
+ """
52
+
53
+ avatar: str | None = None
54
+ created_at: int | None = Field(None, alias="createdAt")
55
+ pet_id: int | None = Field(None, alias="petId")
56
+ pet_name: str | None = Field(None, alias="petName")
57
+
58
+
59
+ class User(BaseModel):
60
+ """Dataclass for user data.
61
+ Subclass of AccountData.
62
+ """
63
+
64
+ avatar: str | None = None
65
+ created_at: int | None = Field(None, alias="createdAt")
66
+ is_owner: int | None = Field(None, alias="isOwner")
67
+ user_id: int | None = Field(None, alias="userId")
68
+ user_name: str | None = Field(None, alias="userName")
69
+
70
+
71
+ class AccountData(BaseModel):
72
+ """Dataclass for account data.
73
+ Fetch from the API endpoint
74
+ - /group/family/list.
75
+ """
76
+
77
+ device_list: list[Device] | None = Field(None, alias="deviceList")
78
+ expired: bool | None = None
79
+ group_id: int | None = Field(None, alias="groupId")
80
+ name: str | None = None
81
+ owner: int | None = None
82
+ pet_list: list[Pet] | None = Field(None, alias="petList")
83
+ user_list: list[User] | None = Field(None, alias="userList")
84
+
85
+
86
+ class CloudProduct(BaseModel):
87
+ """Dataclass for cloud product details.
88
+ Care+ Service for Smart devices with Camera.
89
+ Subclass of many other device dataclasses.
90
+ """
91
+
92
+ charge_type: str | None = Field(None, alias="chargeType")
93
+ name: str | None = None
94
+ service_id: int | None = Field(None, alias="serviceId")
95
+ subscribe: int | None = None
96
+ work_indate: int | None = Field(None, alias="workIndate")
97
+ work_time: int | None = Field(None, alias="workTime")
98
+
99
+
100
+ class Wifi(BaseModel):
101
+ """Dataclass for Wi-Fi.
102
+ Subclass of many other device dataclasses.
103
+ """
104
+
105
+ bssid: str | None = None
106
+ rsq: int | None = None
107
+ ssid: str | None = None
108
+
109
+
110
+ class FirmwareDetail(BaseModel):
111
+ """Dataclass for firmware details.
112
+ Subclass of many other device dataclasses.
113
+ """
114
+
115
+ module: str | None = None
116
+ version: int | None = None
@@ -0,0 +1,15 @@
1
+ """PyPetkit exceptions."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ class PypetkitError(Exception):
7
+ """Class for PyPetkit exceptions."""
8
+
9
+
10
+ class PetkitTimeoutError(PypetkitError):
11
+ """Class for PyPetkit timeout exceptions."""
12
+
13
+
14
+ class PetkitConnectionError(PypetkitError):
15
+ """Class for PyPetkit connection exceptions."""
@@ -0,0 +1,247 @@
1
+ """Dataclasses for feeder data."""
2
+
3
+ from collections.abc import Callable
4
+ from typing import Any, ClassVar
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ from pypetkitapi.const import PetkitEndpoint
9
+ from pypetkitapi.containers import CloudProduct, FirmwareDetail, Wifi
10
+
11
+
12
+ class FeedItem(BaseModel):
13
+ """Dataclass for feed item data."""
14
+
15
+ id: str | None = None
16
+ name: str | None = None
17
+ time: int | None = None
18
+ amount: int | None = None
19
+ amount1: int | None = Field(None, alias="amount1")
20
+ amount2: int | None = Field(None, alias="amount2")
21
+
22
+
23
+ class FeedDailyList(BaseModel):
24
+ """Dataclass for feed daily list data."""
25
+
26
+ items: list[FeedItem] | None = None
27
+ repeats: int | None = None
28
+ suspended: int | None = None
29
+
30
+
31
+ class MultiFeedItem(BaseModel):
32
+ """Dataclass for multi feed item data."""
33
+
34
+ feed_daily_list: list[FeedDailyList] | None = Field(None, alias="feedDailyList")
35
+ is_executed: int | None = Field(None, alias="isExecuted")
36
+ user_id: str | None = Field(None, alias="userId")
37
+
38
+
39
+ class CameraMultiNew(BaseModel):
40
+ """Dataclass for camera multi new data."""
41
+
42
+ enable: int | None = None
43
+ rpt: str | None = None
44
+ time: list[tuple[int, int]] | None = None
45
+
46
+
47
+ class SettingsFeeder(BaseModel):
48
+ """Dataclass for settings."""
49
+
50
+ attire_id: int | None = Field(None, alias="attireId")
51
+ attire_switch: int | None = Field(None, alias="attireSwitch")
52
+ auto_product: int | None = Field(None, alias="autoProduct")
53
+ camera: int | None = None
54
+ camera_config: int | None = Field(None, alias="cameraConfig")
55
+ camera_multi_range: list | None = Field(None, alias="cameraMultiRange")
56
+ control_settings: int | None = Field(None, alias="controlSettings")
57
+ desiccant_notify: int | None = Field(None, alias="desiccantNotify")
58
+ detect_config: int | None = Field(None, alias="detectConfig")
59
+ detect_interval: int | None = Field(None, alias="detectInterval")
60
+ detect_multi_range: list | None = Field(None, alias="detectMultiRange")
61
+ eat_detection: int | None = Field(None, alias="eatDetection")
62
+ eat_notify: int | None = Field(None, alias="eatNotify")
63
+ eat_sensitivity: int | None = Field(None, alias="eatSensitivity")
64
+ eat_video: int | None = Field(None, alias="eatVideo")
65
+ feed_notify: int | None = Field(None, alias="feedNotify")
66
+ feed_picture: int | None = Field(None, alias="feedPicture")
67
+ food_notify: int | None = Field(None, alias="foodNotify")
68
+ food_warn: int | None = Field(None, alias="foodWarn")
69
+ food_warn_range: list[int] | None = Field(None, alias="foodWarnRange")
70
+ highlight: int | None = None
71
+ light_config: int | None = Field(None, alias="lightConfig")
72
+ light_mode: int | None = Field(None, alias="lightMode")
73
+ light_multi_range: list[tuple[int, int]] | None = Field(
74
+ None, alias="lightMultiRange"
75
+ )
76
+ live_encrypt: int | None = Field(None, alias="liveEncrypt")
77
+ low_battery_notify: int | None = Field(None, alias="lowBatteryNotify")
78
+ manual_lock: int | None = Field(None, alias="manualLock")
79
+ microphone: int | None = None
80
+ move_detection: int | None = Field(None, alias="moveDetection")
81
+ move_notify: int | None = Field(None, alias="moveNotify")
82
+ move_sensitivity: int | None = Field(None, alias="moveSensitivity")
83
+ night: int | None = None
84
+ num_limit: int | None = Field(None, alias="numLimit")
85
+ pet_detection: int | None = Field(None, alias="petDetection")
86
+ pet_notify: int | None = Field(None, alias="petNotify")
87
+ pet_sensitivity: int | None = Field(None, alias="petSensitivity")
88
+ pre_live: int | None = Field(None, alias="preLive")
89
+ selected_sound: int | None = Field(None, alias="selectedSound")
90
+ smart_frame: int | None = Field(None, alias="smartFrame")
91
+ sound_enable: int | None = Field(None, alias="soundEnable")
92
+ surplus_control: int | None = Field(None, alias="surplusControl")
93
+ surplus_standard: int | None = Field(None, alias="surplusStandard")
94
+ system_sound_enable: int | None = Field(None, alias="systemSoundEnable")
95
+ time_display: int | None = Field(None, alias="timeDisplay")
96
+ tone_config: int | None = Field(None, alias="toneConfig")
97
+ tone_mode: int | None = Field(None, alias="toneMode")
98
+ tone_multi_range: list[tuple[int, int]] | None = Field(None, alias="toneMultiRange")
99
+ upload: int | None = None
100
+ volume: int | None = None
101
+ feed_sound: int | None = Field(None, alias="feedSound")
102
+ factor: int | None = None
103
+ color_setting: int | None = Field(None, alias="colorSetting")
104
+ conservation: int | None = None
105
+ bucket_name1: str | None = Field(None, alias="bucketName1")
106
+ bucket_name2: str | None = Field(None, alias="bucketName2")
107
+ camera_multi_new: list[CameraMultiNew] | None = Field(None, alias="cameraMultiNew")
108
+
109
+
110
+ class FeedState(BaseModel):
111
+ """Dataclass for feed state data."""
112
+
113
+ eat_avg: int | None = Field(None, alias="eatAvg")
114
+ eat_count: int | None = Field(None, alias="eatCount")
115
+ eat_times: list[int] | None = Field(None, alias="eatTimes")
116
+ feed_times: dict | None = Field(None, alias="feedTimes")
117
+ times: int | None = None
118
+ add_amount_total: int | None = Field(None, alias="addAmountTotal")
119
+ plan_amount_total: int | None = Field(None, alias="planAmountTotal")
120
+ plan_real_amount_total: int | None = Field(None, alias="planRealAmountTotal")
121
+ real_amount_total: int | None = Field(None, alias="realAmountTotal")
122
+ add_amount_total1: int | None = Field(None, alias="addAmountTotal1")
123
+ add_amount_total2: int | None = Field(None, alias="addAmountTotal2")
124
+ plan_amount_total1: int | None = Field(None, alias="planAmountTotal1")
125
+ plan_amount_total2: int | None = Field(None, alias="planAmountTotal2")
126
+ plan_real_amount_total1: int | None = Field(None, alias="planRealAmountTotal1")
127
+ plan_real_amount_total2: int | None = Field(None, alias="planRealAmountTotal2")
128
+ real_amount_total1: int | None = Field(None, alias="realAmountTotal1")
129
+ real_amount_total2: int | None = Field(None, alias="realAmountTotal2")
130
+
131
+
132
+ class StateFeeder(BaseModel):
133
+ """Dataclass for state data."""
134
+
135
+ battery_power: int | None = Field(None, alias="batteryPower")
136
+ battery_status: int | None = Field(None, alias="batteryStatus")
137
+ bowl: int | None = None
138
+ camera_status: int | None = Field(None, alias="cameraStatus")
139
+ desiccant_left_days: int | None = Field(None, alias="desiccantLeftDays")
140
+ desiccant_time: int | None = Field(None, alias="desiccantTime")
141
+ door: int | None = None
142
+ feed_state: FeedState | None = Field(None, alias="feedState")
143
+ feeding: int | None = None
144
+ ota: int | None = None
145
+ overall: int | None = None
146
+ pim: int | None = None
147
+ runtime: int | None = None
148
+ wifi: Wifi | None = None
149
+ eating: int | None = None
150
+ food: int | None = None
151
+ food1: int | None = Field(None, alias="food1")
152
+ food2: int | None = Field(None, alias="food2")
153
+ conservation_status: int | None = Field(None, alias="conservationStatus")
154
+
155
+
156
+ class Feeder(BaseModel):
157
+ """Dataclass for feeder data."""
158
+
159
+ url_endpoint: ClassVar[PetkitEndpoint] = PetkitEndpoint.DEVICE_DETAIL
160
+ query_param: ClassVar[Callable] = lambda device_id: {"id": device_id}
161
+
162
+ auto_upgrade: int | None = Field(None, alias="autoUpgrade")
163
+ bt_mac: str | None = Field(None, alias="btMac")
164
+ cloud_product: CloudProduct | None = Field(None, alias="cloudProduct")
165
+ created_at: str | None = Field(None, alias="createdAt")
166
+ firmware: str | None = None
167
+ firmware_details: list[FirmwareDetail] | None = Field(None, alias="firmwareDetails")
168
+ hardware: int | None = None
169
+ id: int | None = None
170
+ locale: str | None = None
171
+ mac: str | None = None
172
+ model_code: int | None = Field(None, alias="modelCode")
173
+ multi_feed_item: MultiFeedItem | None = Field(None, alias="multiFeedItem")
174
+ name: str | None = None
175
+ secret: str | None = None
176
+ service_status: int | None = Field(None, alias="serviceStatus")
177
+ settings: SettingsFeeder | None = None
178
+ share_open: int | None = Field(None, alias="shareOpen")
179
+ signup_at: str | None = Field(None, alias="signupAt")
180
+ sn: str | None = None
181
+ state: StateFeeder | None = None
182
+ timezone: float | None = None
183
+ p2p_type: int | None = Field(None, alias="p2pType")
184
+ multi_config: bool | None = Field(None, alias="multiConfig")
185
+ device_type: str | None = Field(None, alias="deviceType")
186
+ manual_feed_id: int = 0
187
+
188
+ @classmethod
189
+ def get_endpoint(cls, device_type: str) -> str:
190
+ """Get the endpoint URL for the given device type."""
191
+ return cls.url_endpoint.value
192
+
193
+
194
+ class EventState(BaseModel):
195
+ """Dataclass for event state data."""
196
+
197
+ completed_at: str | None = Field(None, alias="completedAt")
198
+ err_code: int | None = Field(None, alias="errCode")
199
+ media: int | None = None
200
+ real_amount1: int | None = Field(None, alias="realAmount1")
201
+ real_amount2: int | None = Field(None, alias="realAmount2")
202
+ result: int | None = None
203
+ surplus_standard: int | None = Field(None, alias="surplusStandard")
204
+
205
+
206
+ class FeederRecord(BaseModel):
207
+ """Dataclass for feeder record data."""
208
+
209
+ aes_key: str | None = Field(None, alias="aesKey")
210
+ duration: int | None = None
211
+ event_id: str | None = Field(None, alias="eventId")
212
+ expire: int | None = None
213
+ mark: int | None = None
214
+ media_api: str | None = Field(None, alias="mediaApi")
215
+ start_time: int | None = Field(None, alias="startTime")
216
+ storage_space: int | None = Field(None, alias="storageSpace")
217
+ eat_video: int | None = Field(None, alias="eatVideo")
218
+ is_need_upload_video: int | None = Field(None, alias="isNeedUploadVideo")
219
+ preview: str | None = None
220
+ time: int | None = None
221
+ timestamp: int | None = None
222
+ aes_key1: str | None = Field(None, alias="aesKey1")
223
+ aes_key2: str | None = Field(None, alias="aesKey2")
224
+ amount1: int | None = Field(None, alias="amount1")
225
+ amount2: int | None = Field(None, alias="amount2")
226
+ completed_at: int | None = Field(None, alias="completedAt")
227
+ content: dict[str, Any] | None = None
228
+ desc: str | None = None
229
+ device_id: int | None = Field(None, alias="deviceId")
230
+ eat_end_time: int | None = Field(None, alias="eatEndTime")
231
+ eat_start_time: int | None = Field(None, alias="eatStartTime")
232
+ empty: int | None = None
233
+ end_time: int | None = Field(None, alias="endTime")
234
+ enum_event_type: str | None = Field(None, alias="enumEventType")
235
+ event: str | None = None
236
+ event_type: int | None = Field(None, alias="eventType")
237
+ expire1: int | None = Field(None, alias="expire1")
238
+ expire2: int | None = Field(None, alias="expire2")
239
+ id: str | None = None
240
+ is_executed: int | None = Field(None, alias="isExecuted")
241
+ media_list: list[Any] | None = Field(None, alias="mediaList")
242
+ name: str | None = None
243
+ preview1: str | None = Field(None, alias="preview1")
244
+ preview2: str | None = Field(None, alias="preview2")
245
+ src: int | None = None
246
+ state: EventState | None = None
247
+ status: int | None = None
@@ -0,0 +1,177 @@
1
+ """Dataclasses for Litter."""
2
+
3
+ from collections.abc import Callable
4
+ from typing import Any, ClassVar
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ from pypetkitapi.const import PetkitEndpoint
9
+ from pypetkitapi.containers import CloudProduct, FirmwareDetail, Wifi
10
+
11
+
12
+ class SettingsLitter(BaseModel):
13
+ """Dataclass for settings.
14
+ -> LitterData subclass.
15
+ """
16
+
17
+ auto_interval_min: int | None = Field(None, alias="autoIntervalMin")
18
+ auto_work: int | None = Field(None, alias="autoWork")
19
+ avoid_repeat: int | None = Field(None, alias="avoidRepeat")
20
+ bury: int | None = None
21
+ control_settings: int | None = Field(None, alias="controlSettings")
22
+ deep_clean: int | None = Field(None, alias="deepClean")
23
+ deep_refresh: int | None = Field(None, alias="deepRefresh")
24
+ deodorant_notify: int | None = Field(None, alias="deodorantNotify")
25
+ distrub_multi_range: list[list[int]] | None = Field(None, alias="distrubMultiRange")
26
+ disturb_config: int | None = Field(None, alias="disturbConfig")
27
+ disturb_mode: int | None = Field(None, alias="disturbMode")
28
+ disturb_range: list[int] | None = Field(None, alias="disturbRange")
29
+ downpos: int | None = None
30
+ dump_switch: int | None = Field(None, alias="dumpSwitch")
31
+ fixed_time_clear: int | None = Field(None, alias="fixedTimeClear")
32
+ kitten: int | None = None
33
+ kitten_percent: float | None = Field(None, alias="kittenPercent")
34
+ kitten_tips_time: int | None = Field(None, alias="kittenTipsTime")
35
+ lack_liquid_notify: int | None = Field(None, alias="lackLiquidNotify")
36
+ lack_sand_notify: int | None = Field(None, alias="lackSandNotify")
37
+ language: str | None = None
38
+ language_follow: int | None = Field(None, alias="languageFollow")
39
+ languages: list[str] | None = None
40
+ light_config: int | None = Field(None, alias="lightConfig")
41
+ light_mode: int | None = Field(None, alias="lightMode")
42
+ light_multi_range: list[Any] | None = Field(None, alias="lightMultiRange")
43
+ light_range: list[int] | None = Field(None, alias="lightRange")
44
+ lightest: int | None = Field(None, alias="lightest")
45
+ litter_full_notify: int | None = Field(None, alias="litterFullNotify")
46
+ manual_lock: int | None = Field(None, alias="manualLock")
47
+ pet_in_notify: int | None = Field(None, alias="petInNotify")
48
+ relate_k3_switch: int | None = Field(None, alias="relateK3Switch")
49
+ sand_type: int | None = Field(None, alias="sandType")
50
+ soft_mode: int | None = Field(None, alias="softMode")
51
+ still_time: int | None = Field(None, alias="stillTime")
52
+ stop_time: int | None = Field(None, alias="stopTime")
53
+ underweight: int | None = Field(None, alias="underweight")
54
+ unit: int | None = None
55
+ weight_popup: int | None = Field(None, alias="weightPopup")
56
+ work_notify: int | None = Field(None, alias="workNotify")
57
+ auto_product: int | None = Field(None, alias="autoProduct")
58
+ camera: int | None = None
59
+ camera_config: int | None = Field(None, alias="cameraConfig")
60
+ cleanning_notify: int | None = Field(None, alias="cleanningNotify")
61
+ garbage_notify: int | None = Field(None, alias="garbageNotify")
62
+ highlight: int | None = Field(None, alias="highlight")
63
+ light_assist: int | None = Field(None, alias="lightAssist")
64
+ live_encrypt: int | None = Field(None, alias="liveEncrypt")
65
+ microphone: int | None = None
66
+ move_notify: int | None = Field(None, alias="moveNotify")
67
+ night: int | None = None
68
+ package_standard: list[int] | None = Field(None, alias="packageStandard")
69
+ pet_detection: int | None = Field(None, alias="petDetection")
70
+ pet_notify: int | None = Field(None, alias="petNotify")
71
+ pre_live: int | None = Field(None, alias="preLive")
72
+ system_sound_enable: int | None = Field(None, alias="systemSoundEnable")
73
+ time_display: int | None = Field(None, alias="timeDisplay")
74
+ toilet_detection: int | None = Field(None, alias="toiletDetection")
75
+ toilet_notify: int | None = Field(None, alias="toiletNotify")
76
+ tone_config: int | None = Field(None, alias="toneConfig")
77
+ tone_mode: int | None = Field(None, alias="toneMode")
78
+ tone_multi_range: list[list[int]] | None = Field(None, alias="toneMultiRange")
79
+ tumbling: int | None = None
80
+ upload: int | None = None
81
+ volume: int | None = None
82
+ wander_detection: int | None = Field(None, alias="wanderDetection")
83
+
84
+
85
+ class StateLitter(BaseModel):
86
+ """Dataclass for state.
87
+ -> LitterData subclass.
88
+ """
89
+
90
+ box: int | None = None
91
+ box_full: bool | None = Field(None, alias="boxFull")
92
+ box_state: int | None = Field(None, alias="boxState")
93
+ deodorant_left_days: int | None = Field(None, alias="deodorantLeftDays")
94
+ frequent_restroom: int | None = Field(None, alias="frequentRestroom")
95
+ liquid_empty: bool | None = Field(None, alias="liquidEmpty")
96
+ liquid_lack: bool | None = Field(None, alias="liquidLack")
97
+ liquid_reset: int | None = Field(None, alias="liquidReset")
98
+ low_power: bool | None = Field(None, alias="lowPower")
99
+ offline_time: int | None = Field(None, alias="offlineTime")
100
+ ota: int | None = None
101
+ overall: int | None = None
102
+ pet_error: bool | None = Field(None, alias="petError")
103
+ pet_in_time: int | None = Field(None, alias="petInTime")
104
+ pim: int | None = None
105
+ power: int | None = None
106
+ sand_correct: int | None = Field(None, alias="sandCorrect")
107
+ sand_lack: bool | None = Field(None, alias="sandLack")
108
+ sand_percent: int | None = Field(None, alias="sandPercent")
109
+ sand_status: int | None = Field(None, alias="sandStatus")
110
+ sand_type: int | None = Field(None, alias="sandType")
111
+ sand_weight: int | None = Field(None, alias="sandWeight")
112
+ used_times: int | None = Field(None, alias="usedTimes")
113
+ wifi: Wifi | None = None
114
+ bagging_state: int | None = Field(None, alias="baggingState")
115
+ battery: int | None = None
116
+ box_store_state: int | None = Field(None, alias="boxStoreState")
117
+ camera_status: int | None = Field(None, alias="cameraStatus")
118
+ dump_state: int | None = Field(None, alias="dumpState")
119
+ liquid: int | None = None
120
+ pack_state: int | None = Field(None, alias="packState")
121
+ package_install: int | None = Field(None, alias="packageInstall")
122
+ package_secret: str | None = Field(None, alias="packageSecret")
123
+ package_sn: str | None = Field(None, alias="packageSn")
124
+ package_state: int | None = Field(None, alias="packageState")
125
+ pi_ins: int | None = Field(None, alias="piIns")
126
+ purification_left_days: int | None = Field(None, alias="purificationLeftDays")
127
+ seal_door_state: int | None = Field(None, alias="sealDoorState")
128
+ top_ins: int | None = Field(None, alias="topIns")
129
+ wander_time: int | None = Field(None, alias="wanderTime")
130
+
131
+
132
+ class Litter(BaseModel):
133
+ """Dataclass for Litter Data.
134
+ Supported devices = T4, T6
135
+ """
136
+
137
+ url_endpoint: ClassVar[PetkitEndpoint] = PetkitEndpoint.DEVICE_DETAIL
138
+ query_param: ClassVar[Callable] = lambda device_id: {"id": device_id}
139
+
140
+ auto_upgrade: int | None = Field(None, alias="autoUpgrade")
141
+ bt_mac: str | None = Field(None, alias="btMac")
142
+ created_at: str | None = Field(None, alias="createdAt")
143
+ firmware: str | None = None
144
+ firmware_details: list[FirmwareDetail] | None = Field(None, alias="firmwareDetails")
145
+ hardware: int | None = None
146
+ id: int | None = None
147
+ is_pet_out_tips: int | None = Field(None, alias="isPetOutTips")
148
+ locale: str | None = None
149
+ mac: str | None = None
150
+ maintenance_time: int | None = Field(None, alias="maintenanceTime")
151
+ multi_config: bool | None = Field(None, alias="multiConfig")
152
+ name: str | None = None
153
+ pet_in_tip_limit: int | None = Field(None, alias="petInTipLimit")
154
+ pet_out_tips: list[Any] | None = Field(None, alias="petOutTips")
155
+ secret: str | None = None
156
+ settings: SettingsLitter | None = None
157
+ share_open: int | None = Field(None, alias="shareOpen")
158
+ signup_at: str | None = Field(None, alias="signupAt")
159
+ sn: str | None = None
160
+ state: StateLitter | None = None
161
+ timezone: float | None = None
162
+ cloud_product: CloudProduct | None = Field(None, alias="cloudProduct") # For T5/T6
163
+ in_times: int | None = Field(None, alias="inTimes")
164
+ last_out_time: int | None = Field(None, alias="lastOutTime")
165
+ p2p_type: int | None = Field(None, alias="p2pType")
166
+ package_ignore_state: int | None = Field(None, alias="packageIgnoreState")
167
+ package_total_count: int | None = Field(None, alias="packageTotalCount")
168
+ package_used_count: int | None = Field(None, alias="packageUsedCount")
169
+ pet_out_records: list[list[int]] | None = Field(None, alias="petOutRecords")
170
+ service_status: int | None = Field(None, alias="serviceStatus")
171
+ total_time: int | None = Field(None, alias="totalTime")
172
+ device_type: str | None = Field(None, alias="deviceType")
173
+
174
+ @classmethod
175
+ def get_endpoint(cls, device_type: str) -> str:
176
+ """Get the endpoint URL for the given device type."""
177
+ return cls.url_endpoint.value