mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Add sensor entities to Traccar Server (#111374)
This commit is contained in:
parent
e473914407
commit
a1ae4ec23d
@ -1482,6 +1482,7 @@ omit =
|
|||||||
homeassistant/components/traccar_server/device_tracker.py
|
homeassistant/components/traccar_server/device_tracker.py
|
||||||
homeassistant/components/traccar_server/entity.py
|
homeassistant/components/traccar_server/entity.py
|
||||||
homeassistant/components/traccar_server/helpers.py
|
homeassistant/components/traccar_server/helpers.py
|
||||||
|
homeassistant/components/traccar_server/sensor.py
|
||||||
homeassistant/components/tractive/__init__.py
|
homeassistant/components/tractive/__init__.py
|
||||||
homeassistant/components/tractive/binary_sensor.py
|
homeassistant/components/tractive/binary_sensor.py
|
||||||
homeassistant/components/tractive/device_tracker.py
|
homeassistant/components/tractive/device_tracker.py
|
||||||
|
@ -30,7 +30,7 @@ from .const import (
|
|||||||
)
|
)
|
||||||
from .coordinator import TraccarServerCoordinator
|
from .coordinator import TraccarServerCoordinator
|
||||||
|
|
||||||
PLATFORMS: list[Platform] = [Platform.DEVICE_TRACKER]
|
PLATFORMS: list[Platform] = [Platform.DEVICE_TRACKER, Platform.SENSOR]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
@ -10,12 +10,8 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_ADDRESS,
|
|
||||||
ATTR_ALTITUDE,
|
|
||||||
ATTR_CATEGORY,
|
ATTR_CATEGORY,
|
||||||
ATTR_GEOFENCE,
|
|
||||||
ATTR_MOTION,
|
ATTR_MOTION,
|
||||||
ATTR_SPEED,
|
|
||||||
ATTR_STATUS,
|
ATTR_STATUS,
|
||||||
ATTR_TRACCAR_ID,
|
ATTR_TRACCAR_ID,
|
||||||
ATTR_TRACKER,
|
ATTR_TRACKER,
|
||||||
@ -44,23 +40,13 @@ class TraccarServerDeviceTracker(TraccarServerEntity, TrackerEntity):
|
|||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
_attr_name = None
|
_attr_name = None
|
||||||
|
|
||||||
@property
|
|
||||||
def battery_level(self) -> int:
|
|
||||||
"""Return battery value of the device."""
|
|
||||||
return self.traccar_position["attributes"].get("batteryLevel", -1)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self) -> dict[str, Any]:
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
"""Return device specific attributes."""
|
"""Return device specific attributes."""
|
||||||
geofence_name = self.traccar_geofence["name"] if self.traccar_geofence else None
|
|
||||||
return {
|
return {
|
||||||
**self.traccar_attributes,
|
**self.traccar_attributes,
|
||||||
ATTR_ADDRESS: self.traccar_position["address"],
|
|
||||||
ATTR_ALTITUDE: self.traccar_position["altitude"],
|
|
||||||
ATTR_CATEGORY: self.traccar_device["category"],
|
ATTR_CATEGORY: self.traccar_device["category"],
|
||||||
ATTR_GEOFENCE: geofence_name,
|
|
||||||
ATTR_MOTION: self.traccar_position["attributes"].get("motion", False),
|
ATTR_MOTION: self.traccar_position["attributes"].get("motion", False),
|
||||||
ATTR_SPEED: self.traccar_position["speed"],
|
|
||||||
ATTR_STATUS: self.traccar_device["status"],
|
ATTR_STATUS: self.traccar_device["status"],
|
||||||
ATTR_TRACCAR_ID: self.traccar_device["id"],
|
ATTR_TRACCAR_ID: self.traccar_device["id"],
|
||||||
ATTR_TRACKER: DOMAIN,
|
ATTR_TRACKER: DOMAIN,
|
||||||
|
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import REDACTED, async_redact_data
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_ADDRESS, CONF_LATITUDE, CONF_LONGITUDE
|
from homeassistant.const import CONF_ADDRESS, CONF_LATITUDE, CONF_LONGITUDE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -13,21 +13,23 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er
|
|||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .coordinator import TraccarServerCoordinator
|
from .coordinator import TraccarServerCoordinator
|
||||||
|
|
||||||
TO_REDACT = {
|
KEYS_TO_REDACT = {
|
||||||
|
"area", # This is the polygon area of a geofence
|
||||||
CONF_ADDRESS,
|
CONF_ADDRESS,
|
||||||
CONF_LATITUDE,
|
CONF_LATITUDE,
|
||||||
CONF_LONGITUDE,
|
CONF_LONGITUDE,
|
||||||
"area", # This is the polygon area of a geofence
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _entity_state(
|
def _entity_state(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entity: er.RegistryEntry,
|
entity: er.RegistryEntry,
|
||||||
|
coordinator: TraccarServerCoordinator,
|
||||||
) -> dict[str, Any] | None:
|
) -> dict[str, Any] | None:
|
||||||
|
states_to_redact = {x["position"]["address"] for x in coordinator.data.values()}
|
||||||
return (
|
return (
|
||||||
{
|
{
|
||||||
"state": state.state,
|
"state": state.state if state.state not in states_to_redact else REDACTED,
|
||||||
"attributes": state.attributes,
|
"attributes": state.attributes,
|
||||||
}
|
}
|
||||||
if (state := hass.states.get(entity.entity_id))
|
if (state := hass.states.get(entity.entity_id))
|
||||||
@ -57,12 +59,13 @@ async def async_get_config_entry_diagnostics(
|
|||||||
{
|
{
|
||||||
"enity_id": entity.entity_id,
|
"enity_id": entity.entity_id,
|
||||||
"disabled": entity.disabled,
|
"disabled": entity.disabled,
|
||||||
"state": _entity_state(hass, entity),
|
"unit_of_measurement": entity.unit_of_measurement,
|
||||||
|
"state": _entity_state(hass, entity, coordinator),
|
||||||
}
|
}
|
||||||
for entity in entities
|
for entity in entities
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
TO_REDACT,
|
KEYS_TO_REDACT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -81,6 +84,7 @@ async def async_get_device_diagnostics(
|
|||||||
include_disabled_entities=True,
|
include_disabled_entities=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.config_entries.async_reload(entry.entry_id)
|
||||||
return async_redact_data(
|
return async_redact_data(
|
||||||
{
|
{
|
||||||
"subscription_status": coordinator.client.subscription_status,
|
"subscription_status": coordinator.client.subscription_status,
|
||||||
@ -90,10 +94,11 @@ async def async_get_device_diagnostics(
|
|||||||
{
|
{
|
||||||
"enity_id": entity.entity_id,
|
"enity_id": entity.entity_id,
|
||||||
"disabled": entity.disabled,
|
"disabled": entity.disabled,
|
||||||
"state": _entity_state(hass, entity),
|
"unit_of_measurement": entity.unit_of_measurement,
|
||||||
|
"state": _entity_state(hass, entity, coordinator),
|
||||||
}
|
}
|
||||||
for entity in entities
|
for entity in entities
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
TO_REDACT,
|
KEYS_TO_REDACT,
|
||||||
)
|
)
|
||||||
|
15
homeassistant/components/traccar_server/icons.json
Normal file
15
homeassistant/components/traccar_server/icons.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"altitude": {
|
||||||
|
"default": "mdi:altimeter"
|
||||||
|
},
|
||||||
|
"address": {
|
||||||
|
"default": "mdi:map-marker"
|
||||||
|
},
|
||||||
|
"geofence": {
|
||||||
|
"default": "mdi:map-marker"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
125
homeassistant/components/traccar_server/sensor.py
Normal file
125
homeassistant/components/traccar_server/sensor.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
"""Support for Traccar server sensors."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Generic, Literal, TypeVar, cast
|
||||||
|
|
||||||
|
from pytraccar import DeviceModel, GeofenceModel, PositionModel
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
SensorStateClass,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfLength, UnitOfSpeed
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
|
from .const import DOMAIN
|
||||||
|
from .coordinator import TraccarServerCoordinator
|
||||||
|
from .entity import TraccarServerEntity
|
||||||
|
|
||||||
|
_T = TypeVar("_T")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class TraccarServerSensorEntityDescription(Generic[_T], SensorEntityDescription):
|
||||||
|
"""Describe Traccar Server sensor entity."""
|
||||||
|
|
||||||
|
data_key: Literal["position", "device", "geofence", "attributes"]
|
||||||
|
entity_registry_enabled_default = False
|
||||||
|
entity_category = EntityCategory.DIAGNOSTIC
|
||||||
|
value_fn: Callable[[_T], StateType]
|
||||||
|
|
||||||
|
|
||||||
|
TRACCAR_SERVER_SENSOR_ENTITY_DESCRIPTIONS = (
|
||||||
|
TraccarServerSensorEntityDescription[PositionModel](
|
||||||
|
key="attributes.batteryLevel",
|
||||||
|
data_key="position",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
suggested_display_precision=0,
|
||||||
|
value_fn=lambda x: x["attributes"].get("batteryLevel", -1),
|
||||||
|
),
|
||||||
|
TraccarServerSensorEntityDescription[PositionModel](
|
||||||
|
key="speed",
|
||||||
|
data_key="position",
|
||||||
|
device_class=SensorDeviceClass.SPEED,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfSpeed.KNOTS,
|
||||||
|
suggested_display_precision=0,
|
||||||
|
value_fn=lambda x: x["speed"],
|
||||||
|
),
|
||||||
|
TraccarServerSensorEntityDescription[PositionModel](
|
||||||
|
key="altitude",
|
||||||
|
data_key="position",
|
||||||
|
translation_key="altitude",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfLength.METERS,
|
||||||
|
suggested_display_precision=1,
|
||||||
|
value_fn=lambda x: x["altitude"],
|
||||||
|
),
|
||||||
|
TraccarServerSensorEntityDescription[PositionModel](
|
||||||
|
key="address",
|
||||||
|
data_key="position",
|
||||||
|
translation_key="address",
|
||||||
|
value_fn=lambda x: x["address"],
|
||||||
|
),
|
||||||
|
TraccarServerSensorEntityDescription[GeofenceModel | None](
|
||||||
|
key="name",
|
||||||
|
data_key="geofence",
|
||||||
|
translation_key="geofence",
|
||||||
|
value_fn=lambda x: x["name"] if x else None,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up sensor entities."""
|
||||||
|
coordinator: TraccarServerCoordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
async_add_entities(
|
||||||
|
TraccarServerSensor(
|
||||||
|
coordinator=coordinator,
|
||||||
|
device=entry["device"],
|
||||||
|
description=cast(TraccarServerSensorEntityDescription, description),
|
||||||
|
)
|
||||||
|
for entry in coordinator.data.values()
|
||||||
|
for description in TRACCAR_SERVER_SENSOR_ENTITY_DESCRIPTIONS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TraccarServerSensor(TraccarServerEntity, SensorEntity):
|
||||||
|
"""Represent a tracked device."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
entity_description: TraccarServerSensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator: TraccarServerCoordinator,
|
||||||
|
device: DeviceModel,
|
||||||
|
description: TraccarServerSensorEntityDescription[_T],
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the Traccar Server sensor."""
|
||||||
|
super().__init__(coordinator, device)
|
||||||
|
self.entity_description = description
|
||||||
|
self._attr_unique_id = (
|
||||||
|
f"{device['uniqueId']}_{description.data_key}_{description.key}"
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_value(self) -> StateType:
|
||||||
|
"""Return the value of the sensor."""
|
||||||
|
return self.entity_description.value_fn(
|
||||||
|
getattr(self, f"traccar_{self.entity_description.data_key}")
|
||||||
|
)
|
@ -41,5 +41,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"address": {
|
||||||
|
"name": "Address"
|
||||||
|
},
|
||||||
|
"altitude": {
|
||||||
|
"name": "Altitude"
|
||||||
|
},
|
||||||
|
"geofence": {
|
||||||
|
"name": "Geofence"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"id": 0,
|
"id": 0,
|
||||||
"name": "X-Wing",
|
"name": "X-Wing",
|
||||||
"uniqueId": "abc123",
|
"uniqueId": "abc123",
|
||||||
"status": "unknown",
|
"status": "online",
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"lastUpdate": "1970-01-01T00:00:00Z",
|
"lastUpdate": "1970-01-01T00:00:00Z",
|
||||||
"positionId": 0,
|
"positionId": 0,
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
"network": {},
|
"network": {},
|
||||||
"geofenceIds": [0],
|
"geofenceIds": [0],
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"custom_attr_1": "custom_attr_1_value"
|
"custom_attr_1": "custom_attr_1_value",
|
||||||
|
"batteryLevel": 15.00000867601
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -17,5 +17,7 @@
|
|||||||
"coordinateFormat": null,
|
"coordinateFormat": null,
|
||||||
"openIdEnabled": true,
|
"openIdEnabled": true,
|
||||||
"openIdForce": true,
|
"openIdForce": true,
|
||||||
"attributes": {}
|
"attributes": {
|
||||||
|
"speedUnit": "kn"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
'name': 'X-Wing',
|
'name': 'X-Wing',
|
||||||
'phone': None,
|
'phone': None,
|
||||||
'positionId': 0,
|
'positionId': 0,
|
||||||
'status': 'unknown',
|
'status': 'online',
|
||||||
'uniqueId': 'abc123',
|
'uniqueId': 'abc123',
|
||||||
}),
|
}),
|
||||||
'geofence': dict({
|
'geofence': dict({
|
||||||
@ -47,6 +47,7 @@
|
|||||||
'address': '**REDACTED**',
|
'address': '**REDACTED**',
|
||||||
'altitude': 546841384638,
|
'altitude': 546841384638,
|
||||||
'attributes': dict({
|
'attributes': dict({
|
||||||
|
'batteryLevel': 15.00000867601,
|
||||||
'custom_attr_1': 'custom_attr_1_value',
|
'custom_attr_1': 'custom_attr_1_value',
|
||||||
}),
|
}),
|
||||||
'course': 360,
|
'course': 360,
|
||||||
@ -75,25 +76,84 @@
|
|||||||
'enity_id': 'device_tracker.x_wing',
|
'enity_id': 'device_tracker.x_wing',
|
||||||
'state': dict({
|
'state': dict({
|
||||||
'attributes': dict({
|
'attributes': dict({
|
||||||
'address': '**REDACTED**',
|
|
||||||
'altitude': 546841384638,
|
|
||||||
'battery_level': -1,
|
|
||||||
'category': 'starfighter',
|
'category': 'starfighter',
|
||||||
'custom_attr_1': 'custom_attr_1_value',
|
'custom_attr_1': 'custom_attr_1_value',
|
||||||
'friendly_name': 'X-Wing',
|
'friendly_name': 'X-Wing',
|
||||||
'geofence': 'Tatooine',
|
|
||||||
'gps_accuracy': 3.5,
|
'gps_accuracy': 3.5,
|
||||||
'latitude': '**REDACTED**',
|
'latitude': '**REDACTED**',
|
||||||
'longitude': '**REDACTED**',
|
'longitude': '**REDACTED**',
|
||||||
'motion': False,
|
'motion': False,
|
||||||
'source_type': 'gps',
|
'source_type': 'gps',
|
||||||
'speed': 4568795,
|
'status': 'online',
|
||||||
'status': 'unknown',
|
|
||||||
'traccar_id': 0,
|
'traccar_id': 0,
|
||||||
'tracker': 'traccar_server',
|
'tracker': 'traccar_server',
|
||||||
}),
|
}),
|
||||||
'state': 'not_home',
|
'state': 'not_home',
|
||||||
}),
|
}),
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': False,
|
||||||
|
'enity_id': 'sensor.x_wing_battery',
|
||||||
|
'state': dict({
|
||||||
|
'attributes': dict({
|
||||||
|
'device_class': 'battery',
|
||||||
|
'friendly_name': 'X-Wing Battery',
|
||||||
|
'state_class': 'measurement',
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
'state': '15.00000867601',
|
||||||
|
}),
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': False,
|
||||||
|
'enity_id': 'sensor.x_wing_speed',
|
||||||
|
'state': dict({
|
||||||
|
'attributes': dict({
|
||||||
|
'device_class': 'speed',
|
||||||
|
'friendly_name': 'X-Wing Speed',
|
||||||
|
'state_class': 'measurement',
|
||||||
|
'unit_of_measurement': 'kn',
|
||||||
|
}),
|
||||||
|
'state': '4568795',
|
||||||
|
}),
|
||||||
|
'unit_of_measurement': 'kn',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': False,
|
||||||
|
'enity_id': 'sensor.x_wing_altitude',
|
||||||
|
'state': dict({
|
||||||
|
'attributes': dict({
|
||||||
|
'friendly_name': 'X-Wing Altitude',
|
||||||
|
'state_class': 'measurement',
|
||||||
|
'unit_of_measurement': 'm',
|
||||||
|
}),
|
||||||
|
'state': '546841384638',
|
||||||
|
}),
|
||||||
|
'unit_of_measurement': 'm',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': False,
|
||||||
|
'enity_id': 'sensor.x_wing_address',
|
||||||
|
'state': dict({
|
||||||
|
'attributes': dict({
|
||||||
|
'friendly_name': 'X-Wing Address',
|
||||||
|
}),
|
||||||
|
'state': '**REDACTED**',
|
||||||
|
}),
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': False,
|
||||||
|
'enity_id': 'sensor.x_wing_geofence',
|
||||||
|
'state': dict({
|
||||||
|
'attributes': dict({
|
||||||
|
'friendly_name': 'X-Wing Geofence',
|
||||||
|
}),
|
||||||
|
'state': 'Tatooine',
|
||||||
|
}),
|
||||||
|
'unit_of_measurement': None,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
'subscription_status': 'disconnected',
|
'subscription_status': 'disconnected',
|
||||||
@ -130,7 +190,7 @@
|
|||||||
'name': 'X-Wing',
|
'name': 'X-Wing',
|
||||||
'phone': None,
|
'phone': None,
|
||||||
'positionId': 0,
|
'positionId': 0,
|
||||||
'status': 'unknown',
|
'status': 'online',
|
||||||
'uniqueId': 'abc123',
|
'uniqueId': 'abc123',
|
||||||
}),
|
}),
|
||||||
'geofence': dict({
|
'geofence': dict({
|
||||||
@ -147,6 +207,7 @@
|
|||||||
'address': '**REDACTED**',
|
'address': '**REDACTED**',
|
||||||
'altitude': 546841384638,
|
'altitude': 546841384638,
|
||||||
'attributes': dict({
|
'attributes': dict({
|
||||||
|
'batteryLevel': 15.00000867601,
|
||||||
'custom_attr_1': 'custom_attr_1_value',
|
'custom_attr_1': 'custom_attr_1_value',
|
||||||
}),
|
}),
|
||||||
'course': 360,
|
'course': 360,
|
||||||
@ -170,10 +231,41 @@
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
'entities': list([
|
'entities': list([
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_battery',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_speed',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': 'kn',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_altitude',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': 'm',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_address',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_geofence',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
}),
|
||||||
dict({
|
dict({
|
||||||
'disabled': True,
|
'disabled': True,
|
||||||
'enity_id': 'device_tracker.x_wing',
|
'enity_id': 'device_tracker.x_wing',
|
||||||
'state': None,
|
'state': None,
|
||||||
|
'unit_of_measurement': None,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
'subscription_status': 'disconnected',
|
'subscription_status': 'disconnected',
|
||||||
@ -210,7 +302,7 @@
|
|||||||
'name': 'X-Wing',
|
'name': 'X-Wing',
|
||||||
'phone': None,
|
'phone': None,
|
||||||
'positionId': 0,
|
'positionId': 0,
|
||||||
'status': 'unknown',
|
'status': 'online',
|
||||||
'uniqueId': 'abc123',
|
'uniqueId': 'abc123',
|
||||||
}),
|
}),
|
||||||
'geofence': dict({
|
'geofence': dict({
|
||||||
@ -227,6 +319,7 @@
|
|||||||
'address': '**REDACTED**',
|
'address': '**REDACTED**',
|
||||||
'altitude': 546841384638,
|
'altitude': 546841384638,
|
||||||
'attributes': dict({
|
'attributes': dict({
|
||||||
|
'batteryLevel': 15.00000867601,
|
||||||
'custom_attr_1': 'custom_attr_1_value',
|
'custom_attr_1': 'custom_attr_1_value',
|
||||||
}),
|
}),
|
||||||
'course': 360,
|
'course': 360,
|
||||||
@ -250,30 +343,56 @@
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
'entities': list([
|
'entities': list([
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_battery',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_speed',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': 'kn',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_altitude',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': 'm',
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_address',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
}),
|
||||||
|
dict({
|
||||||
|
'disabled': True,
|
||||||
|
'enity_id': 'sensor.x_wing_geofence',
|
||||||
|
'state': None,
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
}),
|
||||||
dict({
|
dict({
|
||||||
'disabled': False,
|
'disabled': False,
|
||||||
'enity_id': 'device_tracker.x_wing',
|
'enity_id': 'device_tracker.x_wing',
|
||||||
'state': dict({
|
'state': dict({
|
||||||
'attributes': dict({
|
'attributes': dict({
|
||||||
'address': '**REDACTED**',
|
|
||||||
'altitude': 546841384638,
|
|
||||||
'battery_level': -1,
|
|
||||||
'category': 'starfighter',
|
'category': 'starfighter',
|
||||||
'custom_attr_1': 'custom_attr_1_value',
|
'custom_attr_1': 'custom_attr_1_value',
|
||||||
'friendly_name': 'X-Wing',
|
'friendly_name': 'X-Wing',
|
||||||
'geofence': 'Tatooine',
|
|
||||||
'gps_accuracy': 3.5,
|
'gps_accuracy': 3.5,
|
||||||
'latitude': '**REDACTED**',
|
'latitude': '**REDACTED**',
|
||||||
'longitude': '**REDACTED**',
|
'longitude': '**REDACTED**',
|
||||||
'motion': False,
|
'motion': False,
|
||||||
'source_type': 'gps',
|
'source_type': 'gps',
|
||||||
'speed': 4568795,
|
'status': 'online',
|
||||||
'status': 'unknown',
|
|
||||||
'traccar_id': 0,
|
'traccar_id': 0,
|
||||||
'tracker': 'traccar_server',
|
'tracker': 'traccar_server',
|
||||||
}),
|
}),
|
||||||
'state': 'not_home',
|
'state': 'not_home',
|
||||||
}),
|
}),
|
||||||
|
'unit_of_measurement': None,
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
'subscription_status': 'disconnected',
|
'subscription_status': 'disconnected',
|
||||||
|
@ -44,6 +44,7 @@ async def test_device_diagnostics(
|
|||||||
mock_config_entry: MockConfigEntry,
|
mock_config_entry: MockConfigEntry,
|
||||||
snapshot: SnapshotAssertion,
|
snapshot: SnapshotAssertion,
|
||||||
device_registry: dr.DeviceRegistry,
|
device_registry: dr.DeviceRegistry,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test device diagnostics."""
|
"""Test device diagnostics."""
|
||||||
await setup_integration(hass, mock_config_entry)
|
await setup_integration(hass, mock_config_entry)
|
||||||
@ -58,6 +59,15 @@ async def test_device_diagnostics(
|
|||||||
for device in dr.async_entries_for_config_entry(
|
for device in dr.async_entries_for_config_entry(
|
||||||
device_registry, mock_config_entry.entry_id
|
device_registry, mock_config_entry.entry_id
|
||||||
):
|
):
|
||||||
|
entities = er.async_entries_for_device(
|
||||||
|
entity_registry,
|
||||||
|
device_id=device.id,
|
||||||
|
include_disabled_entities=True,
|
||||||
|
)
|
||||||
|
# Enable all entitits to show everything in snapshots
|
||||||
|
for entity in entities:
|
||||||
|
entity_registry.async_update_entity(entity.entity_id, disabled_by=None)
|
||||||
|
|
||||||
result = await get_diagnostics_for_device(
|
result = await get_diagnostics_for_device(
|
||||||
hass, hass_client, mock_config_entry, device=device
|
hass, hass_client, mock_config_entry, device=device
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user