@@ -98,6 +98,9 @@ class LitterRobot4(LitterRobot): # pylint: disable=abstract-method
98
98
_litter_level = LITTER_LEVEL_EMPTY
99
99
_litter_level_exp : datetime | None = None
100
100
101
+ _firmware_details : dict [str , bool | dict [str , str ]] | None = None
102
+ _firmware_details_requested : datetime | None = None
103
+
101
104
def __init__ (self , data : dict , account : Account ) -> None :
102
105
"""Initialize a Litter-Robot 4."""
103
106
super ().__init__ (data , account )
@@ -496,46 +499,58 @@ async def get_insight(
496
499
],
497
500
)
498
501
499
- async def get_firmware_details (self ) -> dict [str , bool | dict [str , str ]] | None :
502
+ async def get_firmware_details (
503
+ self , force_check : bool = False
504
+ ) -> dict [str , bool | dict [str , str ]] | None :
500
505
"""Get the firmware details."""
501
- data = await self ._post (
502
- json = {
503
- "query" : """
504
- query getFirmwareDetails($serial: String!) {
505
- litterRobot4CompareFirmwareVersion(serial: $serial) {
506
- isEspFirmwareUpdateNeeded
507
- isPicFirmwareUpdateNeeded
508
- isLaserboardFirmwareUpdateNeeded
509
- latestFirmware {
510
- espFirmwareVersion
511
- picFirmwareVersion
512
- laserBoardFirmwareVersion
506
+ if (
507
+ force_check
508
+ or not self ._firmware_details
509
+ or (requested := self ._firmware_details_requested ) is None
510
+ or requested + timedelta (minutes = 15 ) < utcnow ()
511
+ ):
512
+ data = await self ._post (
513
+ json = {
514
+ "query" : """
515
+ query getFirmwareDetails($serial: String!) {
516
+ litterRobot4CompareFirmwareVersion(serial: $serial) {
517
+ isEspFirmwareUpdateNeeded
518
+ isPicFirmwareUpdateNeeded
519
+ isLaserboardFirmwareUpdateNeeded
520
+ latestFirmware {
521
+ espFirmwareVersion
522
+ picFirmwareVersion
523
+ laserBoardFirmwareVersion
524
+ }
513
525
}
514
526
}
515
- }
516
- """ ,
517
- "variables" : {"serial" : self .serial },
518
- }
519
- )
520
- data = cast (Dict [str , Dict [str , Dict [str , Union [bool , Dict [str , str ]]]]], data )
521
- return data .get ("data" , {}).get ("litterRobot4CompareFirmwareVersion" , {})
527
+ """ ,
528
+ "variables" : {"serial" : self .serial },
529
+ }
530
+ )
531
+ self ._firmware_details = (
532
+ cast (Dict [str , Dict [str , Dict [str , Union [bool , Dict [str , str ]]]]], data )
533
+ .get ("data" , {})
534
+ .get ("litterRobot4CompareFirmwareVersion" , {})
535
+ )
536
+ self ._firmware_details_requested = utcnow ()
537
+ return self ._firmware_details
522
538
523
- async def get_latest_firmware (self ) -> str | None :
539
+ async def get_latest_firmware (self , force_check : bool = False ) -> str | None :
524
540
"""Get the latest firmware available."""
525
- if (firmware := await self .get_firmware_details ()) is None :
541
+ if (firmware := await self .get_firmware_details (force_check )) is None :
526
542
return None
527
543
528
- latest_firmware = (firmware ).get ("latestFirmware" , {})
529
- latest_firmware = cast (Dict [str , str ], latest_firmware )
544
+ latest_firmware = cast (Dict [str , str ], firmware .get ("latestFirmware" , {}))
530
545
return (
531
546
f"ESP: { latest_firmware .get ('espFirmwareVersion' )} / "
532
547
f"PIC: { latest_firmware .get ('picFirmwareVersion' )} / "
533
548
f"TOF: { latest_firmware .get ('laserBoardFirmwareVersion' )} "
534
549
)
535
550
536
- async def has_firmware_update (self ) -> bool :
551
+ async def has_firmware_update (self , force_check : bool = False ) -> bool :
537
552
"""Check if a firmware update is available."""
538
- if (firmware := await self .get_firmware_details ()) is None :
553
+ if (firmware := await self .get_firmware_details (force_check )) is None :
539
554
return False
540
555
return any (value for value in firmware .values () if isinstance (value , bool ))
541
556
0 commit comments