1010 BinarySensorEntity ,
1111)
1212from homeassistant .config_entries import ConfigEntry
13- from homeassistant .core import HomeAssistant , callback
14- from homeassistant .helpers .dispatcher import async_dispatcher_connect
15- from surepy .entities import PetLocation , SurepyEntity
13+ from homeassistant .core import HomeAssistant
14+ from homeassistant .helpers .update_coordinator import CoordinatorEntity
15+ from surepy .entities import SurepyEntity
16+ from surepy .entities .devices import Hub as SureHub
1617from surepy .entities .pet import Pet as SurePet
1718from surepy .enums import EntityType , Location
1819
1920# pylint: disable=relative-beyond-top-level
2021from . import SurePetcareAPI
21- from .const import DOMAIN , SPC , SURE_MANUFACTURER , TOPIC_UPDATE
22+ from .const import DOMAIN , SPC , SURE_MANUFACTURER
2223
2324PARALLEL_UPDATES = 2
2425
@@ -45,13 +46,13 @@ async def async_setup_entry(
4546
4647 spc : SurePetcareAPI = hass .data [DOMAIN ][SPC ]
4748
48- for surepy_entity in spc .states .values ():
49+ for surepy_entity in spc .coordinator . data .values ():
4950
5051 if surepy_entity .type == EntityType .PET :
51- entities .append (Pet (surepy_entity .id , spc ))
52+ entities .append (Pet (spc . coordinator , surepy_entity .id , spc ))
5253
5354 elif surepy_entity .type == EntityType .HUB :
54- entities .append (Hub (surepy_entity .id , spc ))
55+ entities .append (Hub (spc . coordinator , surepy_entity .id , spc ))
5556
5657 # connectivity
5758 elif surepy_entity .type in [
@@ -60,28 +61,32 @@ async def async_setup_entry(
6061 EntityType .FEEDER ,
6162 EntityType .FELAQUA ,
6263 ]:
63- entities .append (DeviceConnectivity (surepy_entity .id , spc ))
64+ entities .append (DeviceConnectivity (spc . coordinator , surepy_entity .id , spc ))
6465
6566 async_add_entities (entities , True )
6667
6768
68- class SurePetcareBinarySensor (BinarySensorEntity ): # type: ignore
69+ class SurePetcareBinarySensor (CoordinatorEntity , BinarySensorEntity ):
6970 """A binary sensor implementation for Sure Petcare Entities."""
7071
7172 _attr_should_poll = False
7273
7374 def __init__ (
7475 self ,
76+ coordinator ,
7577 _id : int ,
7678 spc : SurePetcareAPI ,
7779 device_class : str ,
7880 ):
7981 """Initialize a Sure Petcare binary sensor."""
82+ super ().__init__ (coordinator )
8083
8184 self ._id : int = _id
8285 self ._spc : SurePetcareAPI = spc
8386
84- self ._surepy_entity : SurepyEntity = self ._spc .states [self ._id ]
87+ self ._coordinator = coordinator
88+
89+ self ._surepy_entity : SurepyEntity = self ._coordinator .data [self ._id ]
8590 self ._state : Any = self ._surepy_entity .raw_data ().get ("status" , {})
8691
8792 type_name = self ._surepy_entity .type .name .replace ("_" , " " ).title ()
@@ -120,7 +125,7 @@ def device_info(self):
120125
121126 device = {
122127 "identifiers" : {(DOMAIN , self ._id )},
123- "name" : self ._surepy_entity .name .capitalize (), # type: ignore
128+ "name" : self ._surepy_entity .name .capitalize (),
124129 "manufacturer" : SURE_MANUFACTURER ,
125130 "model" : model ,
126131 }
@@ -145,46 +150,13 @@ def device_info(self):
145150
146151 return device
147152
148- @callback
149- def _async_update (self ) -> None :
150- """Get the latest data and update the state."""
151-
152- self ._surepy_entity = self ._spc .states [self ._id ]
153- self ._state = self ._surepy_entity .raw_data ()["status" ]
154-
155- _LOGGER .debug (
156- "🐾 \x1b [38;2;0;255;0m·\x1b [0m %s updated" ,
157- self ._attr_name .replace (
158- f"{ self ._surepy_entity .type .name .replace ('_' , ' ' ).title ()} " , ""
159- ),
160- )
161-
162- async def async_added_to_hass (self ) -> None :
163- """Register callbacks."""
164-
165- self .async_on_remove (
166- async_dispatcher_connect (self .hass , TOPIC_UPDATE , self ._async_update )
167- )
168-
169- @callback
170- def update () -> None :
171- """Update the state."""
172- self .async_schedule_update_ha_state (True )
173-
174- # pylint: disable=attribute-defined-outside-init
175- self ._async_unsub_dispatcher_connect = async_dispatcher_connect (
176- self .hass , TOPIC_UPDATE , update
177- )
178-
179- self ._async_update ()
180-
181153
182154class Hub (SurePetcareBinarySensor ):
183155 """Sure Petcare Pet."""
184156
185- def __init__ (self , _id : int , spc : SurePetcareAPI ) -> None :
157+ def __init__ (self , coordinator , _id : int , spc : SurePetcareAPI ) -> None :
186158 """Initialize a Sure Petcare Hub."""
187- super ().__init__ (_id , spc , DEVICE_CLASS_CONNECTIVITY )
159+ super ().__init__ (coordinator , _id , spc , DEVICE_CLASS_CONNECTIVITY )
188160
189161 if self ._attr_device_info :
190162 self ._attr_device_info ["identifiers" ] = {(DOMAIN , str (self ._id ))}
@@ -195,30 +167,30 @@ def __init__(self, _id: int, spc: SurePetcareAPI) -> None:
195167 def is_on (self ) -> bool :
196168 """Return True if the hub is on."""
197169
198- if self ._state :
170+ hub : SureHub
171+
172+ if hub := self .coordinator .data [self ._id ]:
173+
199174 self ._attr_extra_state_attributes = {
200- "led_mode" : int (self ._surepy_entity .raw_data ()["status" ]["led_mode" ]),
201- "pairing_mode" : bool (
202- self ._surepy_entity .raw_data ()["status" ]["pairing_mode" ]
203- ),
175+ "led_mode" : int (hub .raw_data ()["status" ]["led_mode" ]),
176+ "pairing_mode" : bool (hub .raw_data ()["status" ]["pairing_mode" ]),
204177 }
205178
206- return bool (self . _state [ " online" ] )
179+ return bool (hub . online )
207180
208181
209182class Pet (SurePetcareBinarySensor ):
210183 """Sure Petcare Pet."""
211184
212- def __init__ (self , _id : int , spc : SurePetcareAPI ) -> None :
185+ def __init__ (self , coordinator , _id : int , spc : SurePetcareAPI ) -> None :
213186 """Initialize a Sure Petcare Pet."""
214- super ().__init__ (_id , spc , DEVICE_CLASS_PRESENCE )
187+ super ().__init__ (coordinator , _id , spc , DEVICE_CLASS_PRESENCE )
215188
216189 self ._surepy_entity : SurePet
217- self ._state : PetLocation
218190
219191 self ._attr_entity_picture = self ._surepy_entity .photo_url
220192
221- if self ._state :
193+ if self ._surepy_entity :
222194 self ._attr_extra_state_attributes = {
223195 "since" : self ._surepy_entity .location .since ,
224196 "where" : self ._surepy_entity .location .where ,
@@ -228,49 +200,34 @@ def __init__(self, _id: int, spc: SurePetcareAPI) -> None:
228200 @property
229201 def is_on (self ) -> bool :
230202 """Return True if the pet is at home."""
231- return self ._attr_is_on
232-
233- @callback
234- def _async_update (self ) -> None :
235- """Get the latest data and update the state."""
236-
237- self ._surepy_entity = self ._spc .states [self ._id ]
238- self ._state = self ._surepy_entity .location
239-
240- try :
241- self ._attr_is_on : bool = bool (
242- Location (self ._surepy_entity .location .where ) == Location .INSIDE
243- )
244- except (KeyError , TypeError ):
245- self ._attr_is_on : bool = False
246-
247- _LOGGER .debug (
248- "🐾 \x1b [38;2;0;255;0m·\x1b [0m %s updated" ,
249- self ._attr_name .replace (
250- f"{ self ._surepy_entity .type .name .replace ('_' , ' ' ).title ()} " , ""
251- ),
252- )
203+ pet : SurePet
204+ if pet := self .coordinator .data [self ._id ]:
205+ return bool (Location (pet .location .where ) == Location .INSIDE )
253206
254207
255208class DeviceConnectivity (SurePetcareBinarySensor ):
256209 """Sure Petcare Pet."""
257210
258- def __init__ (self , _id : int , spc : SurePetcareAPI ) -> None :
211+ def __init__ (self , coordinator , _id : int , spc : SurePetcareAPI ) -> None :
259212 """Initialize a Sure Petcare device connectivity sensor."""
260- super ().__init__ (_id , spc , DEVICE_CLASS_CONNECTIVITY )
213+ super ().__init__ (coordinator , _id , spc , DEVICE_CLASS_CONNECTIVITY )
261214
262215 self ._attr_name = f"{ self ._name } Connectivity"
263216 self ._attr_unique_id = (
264217 f"{ self ._surepy_entity .household_id } -{ self ._id } -connectivity"
265218 )
266219
267- if self ._state :
268- self ._attr_extra_state_attributes = {
269- "device_rssi" : f'{ self ._state ["signal" ]["device_rssi" ]:.2f} ' ,
270- "hub_rssi" : f'{ self ._state ["signal" ]["hub_rssi" ]:.2f} ' ,
220+ @property
221+ def extra_state_attributes (self ) -> dict [str , Any ]:
222+ if (data := self ._surepy_entity .raw_data ()) and (state := data .get ("status" )):
223+ return {
224+ "device_rssi" : f'{ state ["signal" ]["device_rssi" ]:.2f} ' ,
225+ "hub_rssi" : f'{ state ["signal" ]["hub_rssi" ]:.2f} ' ,
271226 }
272227
273- @callback
274- def _async_update (self ) -> None :
275- super ()._async_update ()
276- self ._attr_is_on = bool (self ._attr_extra_state_attributes )
228+ return {}
229+
230+ @property
231+ def is_on (self ) -> bool :
232+ """Return True if the pet is at home."""
233+ return bool (self .extra_state_attributes )
0 commit comments