Home Assistant Unofficial Reference 2024.12.1
device_tracker.py
Go to the documentation of this file.
1 """Support for GPS tracking MQTT enabled devices."""
2 
3 from __future__ import annotations
4 
5 import json
6 import logging
7 
8 import voluptuous as vol
9 
10 from homeassistant.components import mqtt
12  PLATFORM_SCHEMA as DEVICE_TRACKER_PLATFORM_SCHEMA,
13  AsyncSeeCallback,
14 )
15 from homeassistant.components.mqtt import CONF_QOS
16 from homeassistant.const import (
17  ATTR_BATTERY_LEVEL,
18  ATTR_GPS_ACCURACY,
19  ATTR_LATITUDE,
20  ATTR_LONGITUDE,
21  CONF_DEVICES,
22 )
23 from homeassistant.core import HomeAssistant, callback
25 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
26 
27 _LOGGER = logging.getLogger(__name__)
28 
29 GPS_JSON_PAYLOAD_SCHEMA = vol.Schema(
30  {
31  vol.Required(ATTR_LATITUDE): vol.Coerce(float),
32  vol.Required(ATTR_LONGITUDE): vol.Coerce(float),
33  vol.Optional(ATTR_GPS_ACCURACY): vol.Coerce(int),
34  vol.Optional(ATTR_BATTERY_LEVEL): vol.Coerce(str),
35  },
36  extra=vol.ALLOW_EXTRA,
37 )
38 
39 PLATFORM_SCHEMA = DEVICE_TRACKER_PLATFORM_SCHEMA.extend(mqtt.config.SCHEMA_BASE).extend(
40  {vol.Required(CONF_DEVICES): {cv.string: mqtt.valid_subscribe_topic}}
41 )
42 
43 
45  hass: HomeAssistant,
46  config: ConfigType,
47  async_see: AsyncSeeCallback,
48  discovery_info: DiscoveryInfoType | None = None,
49 ) -> bool:
50  """Set up the MQTT JSON tracker."""
51  # Make sure MQTT integration is enabled and the client is available
52  # We cannot count on dependencies as the device_tracker platform setup
53  # also will be triggered when mqtt is loading the `device_tracker` platform
54  if not await mqtt.async_wait_for_mqtt_client(hass):
55  _LOGGER.error("MQTT integration is not available")
56  return False
57 
58  devices = config[CONF_DEVICES]
59  qos = config[CONF_QOS]
60 
61  for dev_id, topic in devices.items():
62 
63  @callback
64  def async_message_received(msg, dev_id=dev_id):
65  """Handle received MQTT message."""
66  try:
67  data = GPS_JSON_PAYLOAD_SCHEMA(json.loads(msg.payload))
68  except vol.MultipleInvalid:
69  _LOGGER.error(
70  (
71  "Skipping update for following data "
72  "because of missing or malformatted data: %s"
73  ),
74  msg.payload,
75  )
76  return
77  except ValueError:
78  _LOGGER.error("Error parsing JSON payload: %s", msg.payload)
79  return
80 
81  kwargs = _parse_see_args(dev_id, data)
82  hass.async_create_task(async_see(**kwargs))
83 
84  await mqtt.async_subscribe(hass, topic, async_message_received, qos)
85 
86  return True
87 
88 
89 def _parse_see_args(dev_id, data):
90  """Parse the payload location parameters, into the format see expects."""
91  kwargs = {"gps": (data[ATTR_LATITUDE], data[ATTR_LONGITUDE]), "dev_id": dev_id}
92 
93  if ATTR_GPS_ACCURACY in data:
94  kwargs[ATTR_GPS_ACCURACY] = data[ATTR_GPS_ACCURACY]
95  if ATTR_BATTERY_LEVEL in data:
96  kwargs["battery"] = data[ATTR_BATTERY_LEVEL]
97  return kwargs
bool async_setup_scanner(HomeAssistant hass, ConfigType config, AsyncSeeCallback async_see, DiscoveryInfoType|None discovery_info=None)