mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Provide better debug capabilities for the Traccar Server integration (#113868)
This commit is contained in:
parent
c5f6925948
commit
83cf59e6a8
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from logging import DEBUG as LOG_LEVEL_DEBUG
|
||||
from typing import TYPE_CHECKING, Any, TypedDict
|
||||
|
||||
from pytraccar import (
|
||||
@ -92,8 +93,18 @@ class TraccarServerCoordinator(DataUpdateCoordinator[TraccarServerCoordinatorDat
|
||||
|
||||
self._geofences = geofences
|
||||
|
||||
if self.logger.isEnabledFor(LOG_LEVEL_DEBUG):
|
||||
self.logger.debug("Received devices: %s", devices)
|
||||
self.logger.debug("Received positions: %s", positions)
|
||||
|
||||
for position in positions:
|
||||
if (device := get_device(position["deviceId"], devices)) is None:
|
||||
device_id = position["deviceId"]
|
||||
if (device := get_device(device_id, devices)) is None:
|
||||
self.logger.debug(
|
||||
"Device %s not found for position: %s",
|
||||
device_id,
|
||||
position["id"],
|
||||
)
|
||||
continue
|
||||
|
||||
if (
|
||||
@ -102,9 +113,14 @@ class TraccarServerCoordinator(DataUpdateCoordinator[TraccarServerCoordinatorDat
|
||||
device, position
|
||||
)
|
||||
) is None:
|
||||
self.logger.debug(
|
||||
"Skipping position update %s for %s due to accuracy filter",
|
||||
position["id"],
|
||||
device_id,
|
||||
)
|
||||
continue
|
||||
|
||||
data[device["id"]] = {
|
||||
data[device_id] = {
|
||||
"device": device,
|
||||
"geofence": get_first_geofence(
|
||||
geofences,
|
||||
@ -122,8 +138,8 @@ class TraccarServerCoordinator(DataUpdateCoordinator[TraccarServerCoordinatorDat
|
||||
self._should_log_subscription_error = True
|
||||
update_devices = set()
|
||||
for device in data.get("devices") or []:
|
||||
device_id = device["id"]
|
||||
if device_id not in self.data:
|
||||
if (device_id := device["id"]) not in self.data:
|
||||
self.logger.debug("Device %s not found in data", device_id)
|
||||
continue
|
||||
|
||||
if (
|
||||
@ -139,8 +155,12 @@ class TraccarServerCoordinator(DataUpdateCoordinator[TraccarServerCoordinatorDat
|
||||
update_devices.add(device_id)
|
||||
|
||||
for position in data.get("positions") or []:
|
||||
device_id = position["deviceId"]
|
||||
if device_id not in self.data:
|
||||
if (device_id := position["deviceId"]) not in self.data:
|
||||
self.logger.debug(
|
||||
"Device %s for position %s not found in data",
|
||||
device_id,
|
||||
position["id"],
|
||||
)
|
||||
continue
|
||||
|
||||
if (
|
||||
@ -149,6 +169,11 @@ class TraccarServerCoordinator(DataUpdateCoordinator[TraccarServerCoordinatorDat
|
||||
self.data[device_id]["device"], position
|
||||
)
|
||||
) is None:
|
||||
self.logger.debug(
|
||||
"Skipping position update %s for %s due to accuracy filter",
|
||||
position["id"],
|
||||
device_id,
|
||||
)
|
||||
continue
|
||||
|
||||
self.data[device_id]["position"] = position
|
||||
|
@ -21,6 +21,20 @@ TO_REDACT = {
|
||||
}
|
||||
|
||||
|
||||
def _entity_state(
|
||||
hass: HomeAssistant,
|
||||
entity: er.RegistryEntry,
|
||||
) -> dict[str, Any] | None:
|
||||
return (
|
||||
{
|
||||
"state": state.state,
|
||||
"attributes": state.attributes,
|
||||
}
|
||||
if (state := hass.states.get(entity.entity_id))
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
@ -43,10 +57,9 @@ async def async_get_config_entry_diagnostics(
|
||||
{
|
||||
"enity_id": entity.entity_id,
|
||||
"disabled": entity.disabled,
|
||||
"state": {"state": state.state, "attributes": state.attributes},
|
||||
"state": _entity_state(hass, entity),
|
||||
}
|
||||
for entity in entities
|
||||
if (state := hass.states.get(entity.entity_id)) is not None
|
||||
],
|
||||
},
|
||||
TO_REDACT,
|
||||
@ -77,10 +90,9 @@ async def async_get_device_diagnostics(
|
||||
{
|
||||
"enity_id": entity.entity_id,
|
||||
"disabled": entity.disabled,
|
||||
"state": {"state": state.state, "attributes": state.attributes},
|
||||
"state": _entity_state(hass, entity),
|
||||
}
|
||||
for entity in entities
|
||||
if (state := hass.states.get(entity.entity_id)) is not None
|
||||
],
|
||||
},
|
||||
TO_REDACT,
|
||||
|
@ -99,6 +99,86 @@
|
||||
'subscription_status': 'disconnected',
|
||||
})
|
||||
# ---
|
||||
# name: test_device_diagnostics_with_disabled_entity[X-Wing]
|
||||
dict({
|
||||
'config_entry_options': dict({
|
||||
'custom_attributes': list([
|
||||
'custom_attr_1',
|
||||
]),
|
||||
'events': list([
|
||||
'device_moving',
|
||||
]),
|
||||
'max_accuracy': 5.0,
|
||||
'skip_accuracy_filter_for': list([
|
||||
]),
|
||||
}),
|
||||
'coordinator_data': dict({
|
||||
'0': dict({
|
||||
'attributes': dict({
|
||||
'custom_attr_1': 'custom_attr_1_value',
|
||||
}),
|
||||
'device': dict({
|
||||
'attributes': dict({
|
||||
}),
|
||||
'category': 'starfighter',
|
||||
'contact': None,
|
||||
'disabled': False,
|
||||
'groupId': 0,
|
||||
'id': 0,
|
||||
'lastUpdate': '1970-01-01T00:00:00Z',
|
||||
'model': '1337',
|
||||
'name': 'X-Wing',
|
||||
'phone': None,
|
||||
'positionId': 0,
|
||||
'status': 'unknown',
|
||||
'uniqueId': 'abc123',
|
||||
}),
|
||||
'geofence': dict({
|
||||
'area': '**REDACTED**',
|
||||
'attributes': dict({
|
||||
}),
|
||||
'calendarId': 0,
|
||||
'description': "A harsh desert world orbiting twin suns in the galaxy's Outer Rim",
|
||||
'id': 0,
|
||||
'name': 'Tatooine',
|
||||
}),
|
||||
'position': dict({
|
||||
'accuracy': 3.5,
|
||||
'address': '**REDACTED**',
|
||||
'altitude': 546841384638,
|
||||
'attributes': dict({
|
||||
'custom_attr_1': 'custom_attr_1_value',
|
||||
}),
|
||||
'course': 360,
|
||||
'deviceId': 0,
|
||||
'deviceTime': '1970-01-01T00:00:00Z',
|
||||
'fixTime': '1970-01-01T00:00:00Z',
|
||||
'geofenceIds': list([
|
||||
0,
|
||||
]),
|
||||
'id': 0,
|
||||
'latitude': '**REDACTED**',
|
||||
'longitude': '**REDACTED**',
|
||||
'network': dict({
|
||||
}),
|
||||
'outdated': True,
|
||||
'protocol': 'C-3PO',
|
||||
'serverTime': '1970-01-01T00:00:00Z',
|
||||
'speed': 4568795,
|
||||
'valid': True,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'entities': list([
|
||||
dict({
|
||||
'disabled': True,
|
||||
'enity_id': 'device_tracker.x_wing',
|
||||
'state': None,
|
||||
}),
|
||||
]),
|
||||
'subscription_status': 'disconnected',
|
||||
})
|
||||
# ---
|
||||
# name: test_entry_diagnostics[entry]
|
||||
dict({
|
||||
'config_entry_options': dict({
|
||||
|
@ -6,7 +6,7 @@ from unittest.mock import AsyncMock
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from .common import setup_integration
|
||||
|
||||
@ -63,3 +63,42 @@ async def test_device_diagnostics(
|
||||
)
|
||||
|
||||
assert result == snapshot(name=device.name)
|
||||
|
||||
|
||||
async def test_device_diagnostics_with_disabled_entity(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_traccar_api_client: Generator[AsyncMock, None, None],
|
||||
mock_config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test device diagnostics with disabled entity."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
devices = dr.async_entries_for_config_entry(
|
||||
hass.helpers.device_registry.async_get(hass),
|
||||
mock_config_entry.entry_id,
|
||||
)
|
||||
|
||||
assert len(devices) == 1
|
||||
|
||||
for device in dr.async_entries_for_config_entry(
|
||||
hass.helpers.device_registry.async_get(hass), mock_config_entry.entry_id
|
||||
):
|
||||
for entry in er.async_entries_for_device(
|
||||
entity_registry,
|
||||
device.id,
|
||||
include_disabled_entities=True,
|
||||
):
|
||||
entity_registry.async_update_entity(
|
||||
entry.entity_id,
|
||||
disabled_by=er.RegistryEntryDisabler.USER,
|
||||
)
|
||||
|
||||
result = await get_diagnostics_for_device(
|
||||
hass, hass_client, mock_config_entry, device=device
|
||||
)
|
||||
|
||||
assert result == snapshot(name=device.name)
|
||||
|
Loading…
x
Reference in New Issue
Block a user