Add more Tractive sensors (#55170)

* Tractive, add more sensors

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* source

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Fix unit for sensor

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Device state

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Device state

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Tractive

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Tractive

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* unit

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* Handle unavailable

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* time

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* continue

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* remove sensor

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* style

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>

* tractive states

Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
This commit is contained in:
Daniel Hjelseth Høyer 2021-12-01 20:44:48 +01:00 committed by GitHub
parent 1fa0351447
commit fbaec76b8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 8 deletions

View file

@ -27,6 +27,7 @@ from .const import (
ATTR_LED,
ATTR_LIVE_TRACKING,
ATTR_MINUTES_ACTIVE,
ATTR_TRACKER_STATE,
CLIENT,
DOMAIN,
RECONNECT_INTERVAL,
@ -143,6 +144,8 @@ class TractiveClient:
self._hass = hass
self._client = client
self._user_id = user_id
self._last_hw_time = 0
self._last_pos_time = 0
self._listen_task: asyncio.Task | None = None
@property
@ -181,20 +184,29 @@ class TractiveClient:
if server_was_unavailable:
_LOGGER.debug("Tractive is back online")
server_was_unavailable = False
if event["message"] == "activity_update":
self._send_activity_update(event)
else:
if "hardware" in event:
self._send_hardware_update(event)
continue
if (
"hardware" in event
and self._last_hw_time != event["hardware"]["time"]
):
self._last_hw_time = event["hardware"]["time"]
self._send_hardware_update(event)
if "position" in event:
self._send_position_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)
except aiotractive.exceptions.TractiveError:
_LOGGER.debug(
"Tractive is not available. Internet connection is down? Sleeping %i seconds and retrying",
RECONNECT_INTERVAL.total_seconds(),
)
self._last_hw_time = 0
self._last_pos_time = 0
async_dispatcher_send(
self._hass, f"{SERVER_UNAVAILABLE}-{self._user_id}"
)
@ -206,6 +218,7 @@ class TractiveClient:
# Sometimes hardware event doesn't contain complete data.
payload = {
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"),
@ -229,6 +242,7 @@ class TractiveClient:
"latitude": event["position"]["latlong"][0],
"longitude": event["position"]["latlong"][1],
"accuracy": event["position"]["accuracy"],
"sensor_used": event["position"]["sensor_used"],
}
self._dispatch_tracker_event(
TRACKER_POSITION_UPDATED, event["tracker_id"], payload

View file

@ -11,6 +11,7 @@ ATTR_BUZZER = "buzzer"
ATTR_LED = "led"
ATTR_LIVE_TRACKING = "live_tracking"
ATTR_MINUTES_ACTIVE = "minutes_active"
ATTR_TRACKER_STATE = "tracker_state"
CLIENT = "client"
TRACKABLES = "trackables"

View file

@ -3,7 +3,10 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.device_tracker import SOURCE_TYPE_GPS
from homeassistant.components.device_tracker import (
SOURCE_TYPE_BLUETOOTH,
SOURCE_TYPE_GPS,
)
from homeassistant.components.device_tracker.config_entry import TrackerEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
@ -47,6 +50,7 @@ class TractiveDeviceTracker(TractiveEntity, TrackerEntity):
self._latitude: float = item.pos_report["latlong"][0]
self._longitude: float = item.pos_report["latlong"][1]
self._accuracy: int = item.pos_report["pos_uncertainty"]
self._source_type: str = item.pos_report["sensor_used"]
self._attr_name = f"{self._tracker_id} {item.trackable['details']['name']}"
self._attr_unique_id = item.trackable["_id"]
@ -54,6 +58,8 @@ class TractiveDeviceTracker(TractiveEntity, TrackerEntity):
@property
def source_type(self) -> str:
"""Return the source type, eg gps or router, of the device."""
if self._source_type == "PHONE":
return SOURCE_TYPE_BLUETOOTH
return SOURCE_TYPE_GPS
@property
@ -87,6 +93,7 @@ class TractiveDeviceTracker(TractiveEntity, TrackerEntity):
self._latitude = event["latitude"]
self._longitude = event["longitude"]
self._accuracy = event["accuracy"]
self._source_type = event["sensor_used"]
self._attr_available = True
self.async_write_ha_state()

View file

@ -24,6 +24,7 @@ from . import Trackables
from .const import (
ATTR_DAILY_GOAL,
ATTR_MINUTES_ACTIVE,
ATTR_TRACKER_STATE,
CLIENT,
DOMAIN,
SERVER_UNAVAILABLE,
@ -77,7 +78,9 @@ class TractiveHardwareSensor(TractiveSensor):
@callback
def handle_hardware_status_update(self, event: dict[str, Any]) -> None:
"""Handle hardware status update."""
self._attr_native_value = event[self.entity_description.key]
if (_state := event[self.entity_description.key]) is None:
return
self._attr_native_value = _state
self._attr_available = True
self.async_write_ha_state()
@ -140,6 +143,14 @@ SENSOR_TYPES: tuple[TractiveSensorEntityDescription, ...] = (
entity_class=TractiveHardwareSensor,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
TractiveSensorEntityDescription(
# Currently, only state operational and not_reporting are used
# More states are available by polling the data
key=ATTR_TRACKER_STATE,
name="Tracker state",
device_class="tractive__tracker_state",
entity_class=TractiveHardwareSensor,
),
TractiveSensorEntityDescription(
key=ATTR_MINUTES_ACTIVE,
name="Minutes Active",

View file

@ -0,0 +1,10 @@
{
"state": {
"tractive__tracker_state": {
"not_reporting": "Not reporting",
"operational": "Operational",
"system_shutdown_user": "System shutdown user",
"system_startup": "System startup"
}
}
}