MQTT device_tracker payload parsed incorrectly by Home Assistant — how can I see what HA is actually evaluating?

TL;DR

  • I publish a JSON payload with device_tracker.location set to “home”/“not_home”.
  • My MQTT device_tracker sometimes ends up in the wrong state or stays stale.
  • I’m looking for concrete ways to observe how Home Assistant evaluates value_template and matches it to payload_home/payload_not_home (logs, traces, debugging tools), and for any known pitfalls.

Context

  • I’m using the MQTT device_tracker platform.
  • JSON is published using Home Assistant’s mqtt.publish service via Tasker on Android.
  • Messages are received on the expected topic and consumed by other MQTT sensors fine, but the device_tracker state in HA is occasionally wrong or doesn’t update as expected.

Current YAML (device_tracker)
Note: state_value_template is deprecated, so I’m using value_template.

mqtt:
  device_tracker:
    - name: "Posizione"
      object_id: "tablet_di_simone"
      unique_id: "tablet_di_simone"
      icon: "mdi:cellphone"
      device:
        name: "Tablet di Simone"
        identifiers: !secret tablet_di_simone_identifiers
        manufacturer: !secret tablet_di_simone_manufacturer
        model: !secret tablet_di_simone_model
        sw_version: !secret tablet_di_simone_sw_version
      state_topic: "Dispositivi/Simone/tablet"
      value_template: "{{ value_json.device_tracker.location }}"
      payload_home: "home"
      payload_not_home: "not_home"
      payload_reset: "None"
      json_attributes_topic: "Dispositivi/Simone/tablet"
      json_attributes_template: "{{ value_json.device_tracker.attributes | tojson }}"

Example payload being published
Note: The home coordinates and Wi‑Fi BSSID below are fictional placeholders for privacy.

{
  "device_tracker": {
    "location": "home",
    "attributes": {
      "source_type": "gps",
      "latitude": 45.464211,
      "longitude": 9.191383,
      "gps_accuracy": 10,
      "altitude": 62.66,
      "speed": 0.0
    }
  },
  "battery_stats": {
    "battery": 43,
    "battery_charging": false,
    "battery_health": "Buono",
    "battery_temperature": 28.7,
    "battery_power_source": "Batteria",
    "energy_saving": false,
    "time_until_charged": 0
  },
  "connectivity": {
    "bluetooth": "on",
    "wifi": "on",
    "wifi_connected": true,
    "wifi_ssid": "HomeWiFi_2G",
    "wifi_bssid": "AA:BB:CC:DD:EE:FF",
    "local_ip_address": "192.168.1.107"
  },
  "attività": { "attività": "still" },
  "device_lost": { "device_lost": false },
  "alarm_clock": { "alarm_clock": true, "attributes": { "Prossima sveglia": 1762408800 } },
  "sleeping_mode": false,
  "last_status_updated": 1762368399
}

Symptoms

  • The device_tracker state occasionally doesn’t reflect the latest payload (“home” vs “not_home”), or it stays stale after reconnects/restarts.
  • Other sensors that parse the same JSON work as expected, which makes me think this is about how the device_tracker template is evaluated or how payload matching happens.

What I expected

  • Each incoming message with location “home” or “not_home” should reliably update the entity state to home/not_home, and attributes should reflect the nested JSON.

What I’ve tried

  • Set logger to debug for MQTT and device_tracker:
    logger:
      default: warn
      logs:
        homeassistant.components.mqtt: debug
        homeassistant.components.device_tracker: debug
        homeassistant.helpers.template: debug
    
  • Verified the topic and payload in Developer Tools > MQTT > “Listen to a topic” (Dispositivi/Simone/#).
  • Ensured the JSON path matches my payload (value_json.device_tracker.location).
  • Normalized the output (lower/trim) in a test template to avoid whitespace/case issues.
  • Considered retained messages: I can clear (-n -r) on the state topic to eliminate stale retained states if that’s a common trap.
  • Full HA restart after config changes.

Questions for the community

  1. How can I see exactly what string HA thinks the template produced for value_template on each message? Is there a built-in trace/log that shows:
    • The raw incoming payload,
    • The evaluated result of value_template,
    • The final decision vs payload_home/payload_not_home?
  2. Are there known pitfalls when using MQTT device_tracker with nested JSON + json_attributes_template? For example:
    • Cases where Jinja returns a Python None which becomes the string “None”,
    • Retained messages forcing stale states after restart,
    • Case/whitespace sensitivities in payload matching.
  3. Is there a recommended “best practice” template for robust parsing here (e.g., defensive checks for missing keys)?
  4. Any tips to differentiate issues caused by:
    • Template evaluation (wrong/missing path),
    • Retained vs live messages,
    • Broker reconnects (message order/duplicates),
    • Attribute parsing failures?

Minimal reproducible test I can run

  • Publish from Developer Tools > MQTT to Dispositivi/Simone/tablet with:
    {
      "device_tracker": {
        "location": "home",
        "attributes": { "source_type": "gps", "latitude": 45.464211, "longitude": 9.191383, "gps_accuracy": 10 }
      }
    }
    
    retain=false, QoS=0.
  • Expect the entity to switch to home; repeat with not_home.
  • If this works but real-world messages don’t, I suspect retained or timing/interleaving.

Thanks in advance for pointers on how to trace template evaluation for MQTT device_trackers (or confirm retained vs. live messages causing mismatches). Links to docs/tools or example debug snippets would be greatly appreciated!