pypetkitapi 1.12.1__py3-none-any.whl → 1.12.4__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/bluetooth.py +19 -4
- pypetkitapi/client.py +15 -9
- pypetkitapi/command.py +4 -3
- pypetkitapi/const.py +5 -0
- pypetkitapi/containers.py +3 -3
- pypetkitapi/media.py +4 -3
- {pypetkitapi-1.12.1.dist-info → pypetkitapi-1.12.4.dist-info}/METADATA +1 -1
- pypetkitapi-1.12.4.dist-info/RECORD +19 -0
- pypetkitapi-1.12.1.dist-info/RECORD +0 -19
- {pypetkitapi-1.12.1.dist-info → pypetkitapi-1.12.4.dist-info}/LICENSE +0 -0
- {pypetkitapi-1.12.1.dist-info → pypetkitapi-1.12.4.dist-info}/WHEEL +0 -0
pypetkitapi/__init__.py
CHANGED
pypetkitapi/bluetooth.py
CHANGED
@@ -41,6 +41,9 @@ class BluetoothManager:
|
|
41
41
|
if not isinstance(water_fountain, WaterFountain):
|
42
42
|
_LOGGER.error("Water fountain with ID %s not found.", fountain_id)
|
43
43
|
raise TypeError(f"Water fountain with ID {fountain_id} not found.")
|
44
|
+
if water_fountain.device_nfo is None:
|
45
|
+
raise ValueError(f"Device info not found for fountain {fountain_id}")
|
46
|
+
|
44
47
|
return water_fountain
|
45
48
|
|
46
49
|
async def check_relay_availability(self, fountain_id: int) -> bool:
|
@@ -94,7 +97,11 @@ class BluetoothManager:
|
|
94
97
|
response = await self.client.req.request(
|
95
98
|
method=HTTPMethod.POST,
|
96
99
|
url=PetkitEndpoint.BLE_CONNECT,
|
97
|
-
data={
|
100
|
+
data={
|
101
|
+
"bleId": fountain_id,
|
102
|
+
"type": water_fountain.device_nfo.type, # type: ignore[union-attr]
|
103
|
+
"mac": water_fountain.mac,
|
104
|
+
},
|
98
105
|
headers=await self.client.get_session_id(),
|
99
106
|
)
|
100
107
|
if response != {"state": 1}:
|
@@ -111,7 +118,11 @@ class BluetoothManager:
|
|
111
118
|
response = await self.client.req.request(
|
112
119
|
method=HTTPMethod.POST,
|
113
120
|
url=PetkitEndpoint.BLE_POLL,
|
114
|
-
data={
|
121
|
+
data={
|
122
|
+
"bleId": fountain_id,
|
123
|
+
"type": water_fountain.device_nfo.type, # type: ignore[union-attr]
|
124
|
+
"mac": water_fountain.mac,
|
125
|
+
},
|
115
126
|
headers=await self.client.get_session_id(),
|
116
127
|
)
|
117
128
|
if response == 1:
|
@@ -149,7 +160,11 @@ class BluetoothManager:
|
|
149
160
|
await self.client.req.request(
|
150
161
|
method=HTTPMethod.POST,
|
151
162
|
url=PetkitEndpoint.BLE_CANCEL,
|
152
|
-
data={
|
163
|
+
data={
|
164
|
+
"bleId": fountain_id,
|
165
|
+
"type": water_fountain.device_nfo.type, # type: ignore[union-attr]
|
166
|
+
"mac": water_fountain.mac,
|
167
|
+
},
|
153
168
|
headers=await self.client.get_session_id(),
|
154
169
|
)
|
155
170
|
_LOGGER.debug("BLE connection closed successfully (id %s)", fountain_id)
|
@@ -206,7 +221,7 @@ class BluetoothManager:
|
|
206
221
|
"cmd": cmd_code,
|
207
222
|
"data": cmd_data,
|
208
223
|
"mac": water_fountain.mac,
|
209
|
-
"type":
|
224
|
+
"type": water_fountain.device_nfo.type, # type: ignore[union-attr]
|
210
225
|
},
|
211
226
|
headers=await self.client.get_session_id(),
|
212
227
|
)
|
pypetkitapi/client.py
CHANGED
@@ -504,7 +504,6 @@ class PetKitClient:
|
|
504
504
|
"""Collect data from litter data to populate pet stats.
|
505
505
|
:param stats_data: Litter data.
|
506
506
|
"""
|
507
|
-
|
508
507
|
if not stats_data.device_nfo:
|
509
508
|
_LOGGER.warning(
|
510
509
|
"No device info for %s can't populate pet infos", stats_data
|
@@ -513,17 +512,24 @@ class PetKitClient:
|
|
513
512
|
|
514
513
|
pets_list = await self.get_pets_list()
|
515
514
|
for pet in pets_list:
|
516
|
-
if
|
517
|
-
|
518
|
-
and stats_data.device_records
|
519
|
-
):
|
515
|
+
if stats_data.device_nfo.device_type in [T3, T4]:
|
516
|
+
await self.init_pet_stats(pet)
|
520
517
|
await self._process_litter_no_camera(pet, stats_data)
|
521
|
-
elif
|
522
|
-
|
523
|
-
and stats_data.device_pet_graph_out
|
524
|
-
):
|
518
|
+
elif stats_data.device_nfo.device_type in [T5, T6]:
|
519
|
+
await self.init_pet_stats(pet)
|
525
520
|
await self._process_litter_camera(pet, stats_data)
|
526
521
|
|
522
|
+
@staticmethod
|
523
|
+
async def init_pet_stats(pet: Pet) -> None:
|
524
|
+
"""Initialize pet stats.
|
525
|
+
Allow pet stats to be displayed in HA even if no data is available.
|
526
|
+
:param pet: Pet data.
|
527
|
+
"""
|
528
|
+
pet.last_litter_usage = 0
|
529
|
+
pet.last_device_used = "Unknown"
|
530
|
+
pet.last_duration_usage = 0
|
531
|
+
pet.last_measured_weight = 0
|
532
|
+
|
527
533
|
async def _process_litter_no_camera(self, pet: Pet, device_records: Litter) -> None:
|
528
534
|
"""Process litter T3/T4 records (litter without camera).
|
529
535
|
:param pet: Pet data.
|
pypetkitapi/command.py
CHANGED
@@ -17,6 +17,7 @@ from pypetkitapi.const import (
|
|
17
17
|
FEEDER_MINI,
|
18
18
|
K2,
|
19
19
|
K3,
|
20
|
+
PET,
|
20
21
|
T3,
|
21
22
|
T4,
|
22
23
|
T5,
|
@@ -265,11 +266,11 @@ ACTIONS_MAP = {
|
|
265
266
|
supported_device=[D3],
|
266
267
|
),
|
267
268
|
PetCommand.PET_UPDATE_SETTING: CmdData(
|
268
|
-
endpoint=PetkitEndpoint.
|
269
|
+
endpoint=PetkitEndpoint.PET_UPDATE_SETTING,
|
269
270
|
params=lambda pet, setting: {
|
270
|
-
"petId": pet,
|
271
|
+
"petId": pet.pet_id,
|
271
272
|
"kv": json.dumps(setting),
|
272
273
|
},
|
273
|
-
supported_device=
|
274
|
+
supported_device=[PET],
|
274
275
|
),
|
275
276
|
}
|
pypetkitapi/const.py
CHANGED
@@ -139,6 +139,8 @@ class PetkitEndpoint(StrEnum):
|
|
139
139
|
LOGIN = "user/login"
|
140
140
|
GET_LOGIN_CODE = "user/sendcodeforquicklogin"
|
141
141
|
REFRESH_SESSION = "user/refreshsession"
|
142
|
+
DETAILS = "user/details2"
|
143
|
+
UNREAD_STATUS = "user/unreadStatus"
|
142
144
|
FAMILY_LIST = "group/family/list"
|
143
145
|
REFRESH_HOME_V2 = "refreshHomeV2"
|
144
146
|
|
@@ -195,3 +197,6 @@ class PetkitEndpoint(StrEnum):
|
|
195
197
|
SCHEDULE_REMOVE = "schedule/remove"
|
196
198
|
SCHEDULE_COMPLETE = "schedule/complete"
|
197
199
|
SCHEDULE_HISTORY = "schedule/userHistorySchedules"
|
200
|
+
|
201
|
+
# Pet
|
202
|
+
PET_UPDATE_SETTING = "updatepetprops"
|
pypetkitapi/containers.py
CHANGED
@@ -84,10 +84,10 @@ class Pet(BaseModel):
|
|
84
84
|
device_nfo: Device | None = None # Device is now optional
|
85
85
|
|
86
86
|
# Litter stats
|
87
|
-
last_litter_usage: int =
|
87
|
+
last_litter_usage: int | None = None
|
88
88
|
last_device_used: str | None = None
|
89
|
-
last_duration_usage: int =
|
90
|
-
last_measured_weight: int =
|
89
|
+
last_duration_usage: int | None = None
|
90
|
+
last_measured_weight: int | None = None
|
91
91
|
|
92
92
|
def __init__(self, **data):
|
93
93
|
"""Initialize the Pet dataclass.
|
pypetkitapi/media.py
CHANGED
@@ -272,13 +272,14 @@ class MediaManager:
|
|
272
272
|
media_cloud: MediaCloud, missing_image: bool, missing_video: bool
|
273
273
|
) -> None:
|
274
274
|
"""Log details about missing media."""
|
275
|
-
log_msg = "Media missing for event %s: "
|
276
275
|
details = []
|
277
276
|
if missing_image:
|
278
277
|
details.append("IMAGE")
|
279
278
|
if missing_video:
|
280
279
|
details.append("VIDEO")
|
281
|
-
_LOGGER.debug(
|
280
|
+
_LOGGER.debug(
|
281
|
+
"Media missing for event : %s %s", media_cloud.event_id, " + ".join(details)
|
282
|
+
)
|
282
283
|
|
283
284
|
async def _process_feeder(self, feeder: Feeder) -> list[MediaCloud]:
|
284
285
|
"""Process media files for a Feeder device.
|
@@ -321,7 +322,7 @@ class MediaManager:
|
|
321
322
|
cp_sub = self.is_subscription_active(device_obj)
|
322
323
|
|
323
324
|
if not feeder_id or not record.items:
|
324
|
-
_LOGGER.
|
325
|
+
_LOGGER.debug("Missing feeder_id or items for record")
|
325
326
|
return media_files
|
326
327
|
|
327
328
|
for item in record.items:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
pypetkitapi/__init__.py,sha256=6zdURz_Sh7_mlBC4sHerwEOSoagp00FRioQHhswxuBA,2107
|
2
|
+
pypetkitapi/bluetooth.py,sha256=Nhmuy6s6V4_A5pgf_WrUc_3cW9P5gh6mSDN23vGoiBY,9534
|
3
|
+
pypetkitapi/client.py,sha256=62QzLypzCa6nEfR-Ihams6uQuYyKpu6yrFfnjfFu1Cc,30057
|
4
|
+
pypetkitapi/command.py,sha256=k04iC0ONiFx7pkr-LJI7qT3RprQ3ojT0jP6KWQk8eTQ,7514
|
5
|
+
pypetkitapi/const.py,sha256=76mR_g6qpqmkSj968W0lLyQAkAPenjk5dcs8ryWJUVA,4732
|
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=3PrjKNXYX7F1wXyXPxWFAJsQk2jlaFL7-dwVpMwy94o,26889
|
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.4.dist-info/LICENSE,sha256=u5jNkZEn6YMrtN4Kr5rU3TcBJ5-eAt0qMx4JDsbsnzM,1074
|
17
|
+
pypetkitapi-1.12.4.dist-info/METADATA,sha256=4UPiRUzvSuL7N9BsK_NwH-s5FjzL-SA6ZK1n3z7cFBE,6946
|
18
|
+
pypetkitapi-1.12.4.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
19
|
+
pypetkitapi-1.12.4.dist-info/RECORD,,
|
@@ -1,19 +0,0 @@
|
|
1
|
-
pypetkitapi/__init__.py,sha256=T4726e-xkLSV7y0cs9BXcEebn6vm4dLV2_96YqjmJ0k,2107
|
2
|
-
pypetkitapi/bluetooth.py,sha256=JIj6mA5D1ZUUFSvnYco1XiGDbF4exKIU50zQIJMXLII,8976
|
3
|
-
pypetkitapi/client.py,sha256=9K95_UuuBBsMYAssN8QrtLnS27IPso4Rnvn663RRs5Y,29760
|
4
|
-
pypetkitapi/command.py,sha256=cMCUutZCQo9Ddvjl_FYR5UjU_CqFz1iyetMznYwjpzM,7500
|
5
|
-
pypetkitapi/const.py,sha256=W0cWpBvOySEaPvVAnQHLeIWYEqKG051mVNv-qsfjo7I,4609
|
6
|
-
pypetkitapi/containers.py,sha256=F_uyDBD0a5QD4s_ArjYiKTAAg1XHYBvmV_lEnO9RQ-U,4786
|
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=5XeiTQCaIgMisaZxdvdKK9RvDKmTR0zRBhKKXKBHTXI,26904
|
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.1.dist-info/LICENSE,sha256=u5jNkZEn6YMrtN4Kr5rU3TcBJ5-eAt0qMx4JDsbsnzM,1074
|
17
|
-
pypetkitapi-1.12.1.dist-info/METADATA,sha256=zn4bNIG96NlL3PQ87aTIaSMo0VDXW4eru8ZbeXFyphE,6946
|
18
|
-
pypetkitapi-1.12.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
19
|
-
pypetkitapi-1.12.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|