|
1 | 1 | """Device tracker for SureHA pets.""" |
2 | 2 | import logging |
| 3 | +from typing import Any |
3 | 4 |
|
4 | | -from homeassistant.components.device_tracker.config_entry import TrackerEntity |
5 | | -from homeassistant.core import Config |
| 5 | +from homeassistant.components.device_tracker.config_entry import ScannerEntity |
| 6 | +from homeassistant.helpers.update_coordinator import CoordinatorEntity |
6 | 7 | from surepy.entities import EntityType |
7 | | -from surepy.entities.pet import Pet |
| 8 | +from surepy.entities.pet import Pet as SurePet |
| 9 | +from surepy.enums import Location |
8 | 10 |
|
9 | 11 | # pylint: disable=relative-beyond-top-level |
10 | 12 | from . import DOMAIN, SurePetcareAPI |
|
18 | 20 | async def async_setup_entry(hass, config_entry, async_add_entities): |
19 | 21 | """Set up the Pet tracker from config entry.""" |
20 | 22 |
|
21 | | - cfg = Config(hass) |
22 | | - config = cfg.as_dict() |
23 | | - |
24 | | - _LOGGER.debug("async_setup_entry: config=%s", config) |
25 | | - _LOGGER.debug("async_setup_entry: config[latitude]=%s", config["latitude"]) |
26 | | - |
27 | 23 | spc: SurePetcareAPI = hass.data[DOMAIN][SPC] |
28 | 24 |
|
29 | 25 | async_add_entities( |
30 | 26 | [ |
31 | | - SureDeviceTracker(pet.id, spc) |
32 | | - for pet in spc.states.values() |
| 27 | + SureDeviceTracker(spc.coordinator, pet.id, spc) |
| 28 | + for pet in spc.coordinator.data.values() |
33 | 29 | if pet.type == EntityType.PET |
34 | 30 | ], |
35 | 31 | True, |
36 | 32 | ) |
37 | 33 |
|
38 | 34 |
|
39 | | -class SureDeviceTracker(TrackerEntity): |
| 35 | +class SureDeviceTracker(CoordinatorEntity, ScannerEntity): |
40 | 36 | """Pet device tracker.""" |
41 | 37 |
|
42 | 38 | _attr_force_update = False |
43 | 39 | _attr_icon = "mdi:cat" |
44 | 40 |
|
45 | | - def __init__(self, _id: int, spc: SurePetcareAPI): |
| 41 | + def __init__(self, coordinator, _id: int, spc: SurePetcareAPI): |
46 | 42 | """Initialize the tracker.""" |
47 | | - # super().__init__(account, vehicle) |
| 43 | + super().__init__(coordinator) |
| 44 | + |
| 45 | + self._spc: SurePetcareAPI = spc |
| 46 | + self._coordinator = coordinator |
48 | 47 |
|
49 | 48 | self._id = _id |
50 | 49 | self._attr_unique_id = f"{self._id}-pet-tracker" |
51 | 50 |
|
52 | | - self._location = (None, None) |
| 51 | + self._surepy_entity: SurePet = self._coordinator.data[self._id] |
| 52 | + type_name = self._surepy_entity.type.name.replace("_", " ").title() |
| 53 | + name: str = ( |
| 54 | + # cover edge case where a device has no name set |
| 55 | + # (dont know how to do this but people have managed to do it ¯\_(ツ)_/¯) |
| 56 | + self._surepy_entity.name |
| 57 | + if self._surepy_entity.name |
| 58 | + else f"Unnamed {type_name}" |
| 59 | + ) |
53 | 60 |
|
54 | | - self._spc: SurePetcareAPI = spc |
55 | | - self._surepy_entity: Pet = self._spc.states[self._id] |
56 | | - self._attr_name = self._surepy_entity.name |
| 61 | + self._attr_name: str = f"{type_name} {name}" |
| 62 | + |
| 63 | + # picture of the pet that can be added via the sure app/website |
| 64 | + self._attr_entity_picture = self._surepy_entity.photo_url |
| 65 | + |
| 66 | + @property |
| 67 | + def is_connected(self) -> bool: |
| 68 | + """Return true if the device is connected to the network.""" |
| 69 | + return bool(self.location_name == "home") |
57 | 70 |
|
58 | 71 | @property |
59 | | - def latitude(self): |
60 | | - """Return latitude value of the pet.""" |
61 | | - return self._location[0] if self._location else None |
| 72 | + def extra_state_attributes(self) -> dict[str, Any]: |
| 73 | + """Return the additional attrs.""" |
| 74 | + |
| 75 | + pet: SurePet |
| 76 | + attrs: dict[str, Any] = {} |
| 77 | + |
| 78 | + if pet := self._coordinator.data[self._id]: |
| 79 | + |
| 80 | + attrs = { |
| 81 | + "since": pet.location.since, |
| 82 | + "where": pet.location.where, |
| 83 | + **pet.raw_data(), |
| 84 | + } |
| 85 | + |
| 86 | + return attrs |
62 | 87 |
|
63 | 88 | @property |
64 | | - def longitude(self): |
65 | | - """Return longitude value of the pet.""" |
66 | | - return self._location[1] if self._location else None |
| 89 | + def location_name(self) -> str: |
| 90 | + """Return 'home' if the pet is at home.""" |
| 91 | + |
| 92 | + pet: SurePet |
| 93 | + inside: bool = False |
| 94 | + |
| 95 | + if pet := self._coordinator.data[self._id]: |
| 96 | + inside = bool(pet.location.where == Location.INSIDE) |
| 97 | + |
| 98 | + return "home" if inside else "not_home" |
67 | 99 |
|
68 | 100 | @property |
69 | 101 | def source_type(self): |
70 | 102 | """Return the source type, eg gps or router, of the pet.""" |
71 | 103 | return SOURCE_TYPE_FLAP |
72 | | - |
73 | | - def update(self): |
74 | | - """Update state of the pet tracker.""" |
75 | | - self._location = (48.0, 9.9) if self._surepy_entity.location else (None, None) |
|
0 commit comments