Skip to content

Commit 9600c14

Browse files
zendiljjjonesjr33
andauthored
Add 'Reset Desiccant' and desiccant frequency number input to Granary Smart Camera Feeder (#201)
* add reset desiccant functionality to smart camera feeder * fix wrong method name on desiccant frequency number input * add key value for desiccant frequency api call * modify api call to reset desiccant to use json returned from session.post() vice a resp object * modify api call to reset desiccant to use object returned from session.post() * spelling error * squash! modify api call to reset desiccant to use json returned from session.post() vice a resp object * check response.code vice status in desiccant reset. add 0 to successful response codes * response may be None or {} depending on if the session refreshed the token * use NumberMode vice str for desiccant mode type --------- Co-authored-by: Jamie Jones <29973406+jjjonesjr33@users.noreply.github.com>
1 parent 2349139 commit 9600c14

5 files changed

Lines changed: 56 additions & 11 deletions

File tree

custom_components/petlibro/api.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,24 +1223,25 @@ async def set_desiccant_reset(self, serial: str) -> JSON:
12231223
})
12241224

12251225
# Granary smart feeder quirk: response can be None on success
1226-
if response is None:
1226+
if response is None or response == {}:
12271227
_LOGGER.debug("Desiccant reset set successfully, got no extra data")
12281228
return
12291229

12301230
# Check if response is already parsed (since response is an integer here)
12311231
if isinstance(response, int):
12321232
_LOGGER.debug(f"Desiccant reset set successfully, returned code: {response}")
12331233
return response
1234+
1235+
# Check if response code indicates success
1236+
if response.code == 200 or response.code == 0:
1237+
_LOGGER.debug(f"Desiccant reset set successfully, returned code: {response.status}")
1238+
return response
12341239

1235-
# If response is a dictionary (JSON), handle it
1236-
response_data = await response.json()
1237-
_LOGGER.debug(f"Desiccant reset response data: {response_data}")
1240+
# If not response 200 assume failure
1241+
else:
1242+
raise PetLibroAPIError(f"Failed to trigger desiccant reset: {response.msg}")
12381243

1239-
# Check if the response indicates success
1240-
if response.status != 200 or response_data.get("code") != 0:
1241-
raise PetLibroAPIError(f"Failed to trigger desiccant reset: {response_data.get('msg')}")
1242-
1243-
return response_data
1244+
return response
12441245

12451246
except aiohttp.ClientError as err:
12461247
_LOGGER.error(f"Failed to trigger desiccant reset for device {serial}: {err}")

custom_components/petlibro/button.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ class PetLibroButtonEntityDescription(ButtonEntityDescription, PetLibroEntityDes
150150
set_fn=lambda device: device.set_light_off(),
151151
name="Turn Off Indicator"
152152
),
153+
PetLibroButtonEntityDescription[GranarySmartCameraFeeder](
154+
key="desiccant_reset",
155+
translation_key="desiccant_reset",
156+
set_fn=lambda device: device.set_desiccant_reset(),
157+
name="Desiccant Replaced"
158+
),
153159
],
154160
OneRFIDSmartFeeder: [
155161
PetLibroButtonEntityDescription[OneRFIDSmartFeeder](

custom_components/petlibro/devices/feeders/granary_smart_camera_feeder.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ def manual_feed_quantity(self):
347347
_LOGGER.warning(f"manual_feed_quantity is None for {self.serial}, setting default to 1.")
348348
self._manual_feed_quantity = 1 # Default value
349349
return self._manual_feed_quantity
350+
351+
@property
352+
def desiccant_frequency(self) -> float:
353+
frequency = self._data.get("realInfo", {}).get("changeDesiccantFrequency")
354+
return frequency if isinstance(frequency, (float, int)) else 0
350355

351356
# Error-handling updated for set_feeding_plan
352357
async def set_feeding_plan(self, value: bool) -> None:
@@ -492,3 +497,22 @@ def update_progress(self) -> float:
492497

493498
progress = upgrade_data.get("progress")
494499
return float(progress) if progress is not None else 0.0
500+
501+
async def set_desiccant_cycle(self, value: float) -> None:
502+
_LOGGER.debug(f"Setting desiccant frequency to {value} for {self.serial}")
503+
try:
504+
key = "DESICCANT"
505+
await self.api.set_desiccant_cycle(self.serial, value, key)
506+
await self.refresh() # Refresh the state after the action
507+
except aiohttp.ClientError as err:
508+
_LOGGER.error(f"Failed to set desiccant cycle for {self.serial}: {err}")
509+
raise PetLibroAPIError(f"Error setting desiccant cycle: {err}")
510+
511+
async def set_desiccant_reset(self) -> None:
512+
_LOGGER.debug(f"Triggering desiccant reset for {self.serial}")
513+
try:
514+
await self.api.set_desiccant_reset(self.serial)
515+
await self.refresh() # Refresh the state after the action
516+
except aiohttp.ClientError as err:
517+
_LOGGER.error(f"Failed to trigger desiccant reset for {self.serial}: {err}")
518+
raise PetLibroAPIError(f"Error triggering desiccant reset: {err}")

custom_components/petlibro/devices/feeders/granary_smart_feeder.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,8 @@ async def set_light_off(self) -> None:
477477
async def set_desiccant_cycle(self, value: float) -> None:
478478
_LOGGER.debug(f"Setting desiccant frequency to {value} for {self.serial}")
479479
try:
480-
await self.api.set_desiccant_cycle(self.serial, value)
480+
key = "DESICCANT"
481+
await self.api.set_desiccant_cycle(self.serial, value, key)
481482
await self.refresh() # Refresh the state after the action
482483
except aiohttp.ClientError as err:
483484
_LOGGER.error(f"Failed to set desiccant cycle for {self.serial}: {err}")

custom_components/petlibro/number.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ def _handle_coordinator_update(self) -> None:
221221
native_min_value=1,
222222
native_step=1,
223223
value_fn=lambda device: device.desiccant_frequency,
224-
method=lambda device, value: device.set_desiccant_frequency(value),
224+
method=lambda device, value: device.set_desiccant_cycle(value),
225225
name="Desiccant Frequency",
226226
),
227227
],
@@ -234,6 +234,19 @@ def _handle_coordinator_update(self) -> None:
234234
mode=NumberMode.SLIDER,
235235
petlibro_unit=APIKey.FEED_UNIT,
236236
),
237+
PetLibroNumberEntityDescription[GranarySmartCameraFeeder](
238+
key="desiccant_frequency",
239+
translation_key="desiccant_frequency",
240+
icon="mdi:calendar-alert",
241+
native_unit_of_measurement="Days",
242+
mode=NumberMode.BOX,
243+
native_max_value=60,
244+
native_min_value=1,
245+
native_step=1,
246+
value_fn=lambda device: device.desiccant_frequency,
247+
method=lambda device, value: device.set_desiccant_cycle(value),
248+
name="Desiccant Frequency",
249+
),
237250
],
238251
OneRFIDSmartFeeder: [
239252
PetLibroNumberEntityDescription[OneRFIDSmartFeeder](

0 commit comments

Comments
 (0)