diff --git a/homeassistant/components/tractive/__init__.py b/homeassistant/components/tractive/__init__.py index 300d7ebafc7f..8dd0ed8e91b8 100644 --- a/homeassistant/components/tractive/__init__.py +++ b/homeassistant/components/tractive/__init__.py @@ -24,11 +24,8 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send from .const import ( ATTR_ACTIVITY_LABEL, - ATTR_BUZZER, ATTR_CALORIES, ATTR_DAILY_GOAL, - ATTR_LED, - ATTR_LIVE_TRACKING, ATTR_MINUTES_ACTIVE, ATTR_MINUTES_DAY_SLEEP, ATTR_MINUTES_NIGHT_SLEEP, @@ -40,10 +37,12 @@ from .const import ( DOMAIN, RECONNECT_INTERVAL, SERVER_UNAVAILABLE, + SWITCH_KEY_MAP, TRACKABLES, TRACKER_ACTIVITY_STATUS_UPDATED, TRACKER_HARDWARE_STATUS_UPDATED, TRACKER_POSITION_UPDATED, + TRACKER_SWITCH_STATUS_UPDATED, TRACKER_WELLNESS_STATUS_UPDATED, ) @@ -225,13 +224,16 @@ class TractiveClient: ): self._last_hw_time = event["hardware"]["time"] self._send_hardware_update(event) - if ( "position" in event and self._last_pos_time != event["position"]["time"] ): self._last_pos_time = event["position"]["time"] self._send_position_update(event) + # If any key belonging to the switch is present in the event, + # we send a switch status update + if bool(set(SWITCH_KEY_MAP.values()).intersection(event)): + self._send_switch_update(event) except aiotractive.exceptions.UnauthorizedError: self._config_entry.async_start_reauth(self._hass) await self.unsubscribe() @@ -266,14 +268,21 @@ class TractiveClient: ATTR_BATTERY_LEVEL: event["hardware"]["battery_level"], ATTR_TRACKER_STATE: event["tracker_state"].lower(), ATTR_BATTERY_CHARGING: event["charging_state"] == "CHARGING", - ATTR_LIVE_TRACKING: event.get("live_tracking", {}).get("active"), - ATTR_BUZZER: event.get("buzzer_control", {}).get("active"), - ATTR_LED: event.get("led_control", {}).get("active"), } self._dispatch_tracker_event( TRACKER_HARDWARE_STATUS_UPDATED, event["tracker_id"], payload ) + def _send_switch_update(self, event: dict[str, Any]) -> None: + # Sometimes the event contains data for all switches, sometimes only for one. + payload = {} + for switch, key in SWITCH_KEY_MAP.items(): + if switch_data := event.get(key): + payload[switch] = switch_data["active"] + self._dispatch_tracker_event( + TRACKER_SWITCH_STATUS_UPDATED, event["tracker_id"], payload + ) + def _send_activity_update(self, event: dict[str, Any]) -> None: payload = { ATTR_MINUTES_ACTIVE: event["progress"]["achieved_minutes"], diff --git a/homeassistant/components/tractive/const.py b/homeassistant/components/tractive/const.py index 254a8c274f3d..acb4f6f7487c 100644 --- a/homeassistant/components/tractive/const.py +++ b/homeassistant/components/tractive/const.py @@ -26,9 +26,16 @@ CLIENT_ID = "625e5349c3c3b41c28a669f1" CLIENT = "client" TRACKABLES = "trackables" +TRACKER_ACTIVITY_STATUS_UPDATED = f"{DOMAIN}_tracker_activity_updated" TRACKER_HARDWARE_STATUS_UPDATED = f"{DOMAIN}_tracker_hardware_status_updated" TRACKER_POSITION_UPDATED = f"{DOMAIN}_tracker_position_updated" -TRACKER_ACTIVITY_STATUS_UPDATED = f"{DOMAIN}_tracker_activity_updated" +TRACKER_SWITCH_STATUS_UPDATED = f"{DOMAIN}_tracker_switch_updated" TRACKER_WELLNESS_STATUS_UPDATED = f"{DOMAIN}_tracker_wellness_updated" SERVER_UNAVAILABLE = f"{DOMAIN}_server_unavailable" + +SWITCH_KEY_MAP = { + ATTR_LIVE_TRACKING: "live_tracking", + ATTR_BUZZER: "buzzer_control", + ATTR_LED: "led_control", +} diff --git a/homeassistant/components/tractive/switch.py b/homeassistant/components/tractive/switch.py index 55acdb9bdcd8..58c82bd6514f 100644 --- a/homeassistant/components/tractive/switch.py +++ b/homeassistant/components/tractive/switch.py @@ -21,7 +21,7 @@ from .const import ( CLIENT, DOMAIN, TRACKABLES, - TRACKER_HARDWARE_STATUS_UPDATED, + TRACKER_SWITCH_STATUS_UPDATED, ) from .entity import TractiveEntity @@ -99,11 +99,10 @@ class TractiveSwitch(TractiveEntity, SwitchEntity): client, item.trackable, item.tracker_details, - f"{TRACKER_HARDWARE_STATUS_UPDATED}-{item.tracker_details['_id']}", + f"{TRACKER_SWITCH_STATUS_UPDATED}-{item.tracker_details['_id']}", ) self._attr_unique_id = f"{item.trackable['_id']}_{description.key}" - self._attr_available = False self._tracker = item.tracker self._method = getattr(self, description.method) self.entity_description = description @@ -111,9 +110,15 @@ class TractiveSwitch(TractiveEntity, SwitchEntity): @callback def handle_status_update(self, event: dict[str, Any]) -> None: """Handle status update.""" + if self.entity_description.key not in event: + return + + # We received an event, so the service is online and the switch entities should + # be available. + self._attr_available = True self._attr_is_on = event[self.entity_description.key] - super().handle_status_update(event) + self.async_write_ha_state() async def async_turn_on(self, **kwargs: Any) -> None: """Turn on a switch."""