{
  "id": "meshcore-ha",
  "name": "MeshCore for Home Assistant",
  "short_name": "MeshCore HA",
  "kind": "integration",
  "status": "active",
  "maturity": "beta",
  "description": "Custom Home Assistant integration for monitoring and controlling MeshCore nodes over USB, BLE or TCP, with sensors, services, diagnostics and optional map upload support.",
  "maintainers": [
    {
      "name": "meshcore-dev",
      "url": "https://github.com/meshcore-dev"
    },
    {
      "name": "Alex Wolden",
      "url": "https://github.com/awolden"
    }
  ],
  "repository": "https://github.com/meshcore-dev/meshcore-ha",
  "documentation": "https://meshcore-dev.github.io/meshcore-ha/",
  "license": "MIT",
  "languages": [
    "python"
  ],
  "platforms": [
    "home-assistant"
  ],
  "interfaces": [
    "gui",
    "api"
  ],
  "connections": [
    "ble",
    "serial",
    "usb",
    "tcp",
    "mqtt"
  ],
  "capabilities": [
    "messaging",
    "contacts",
    "node-configuration",
    "monitoring",
    "telemetry",
    "mapping",
    "automation"
  ],
  "install": [
    {
      "type": "hacs",
      "package": "meshcore-dev/meshcore-ha",
      "url": "https://github.com/meshcore-dev/meshcore-ha"
    },
    {
      "type": "source",
      "url": "https://github.com/meshcore-dev/meshcore-ha"
    },
    {
      "type": "manual",
      "url": "https://meshcore-dev.github.io/meshcore-ha/"
    }
  ],
  "popularity": {
    "githubStars": 212,
    "githubForks": 52,
    "githubWatchers": 11,
    "githubOpenIssues": 47,
    "githubContributors": 30,
    "lastChecked": "2026-06-23"
  },
  "verification": {
    "sourceAvailable": true,
    "releasesAvailable": true,
    "signedReleases": false,
    "ciBuilds": true,
    "hasDocumentation": true,
    "lastChecked": "2026-06-23",
    "notes": [
      "README labels the integration as work in progress and notes BLE has not been thoroughly tested."
    ]
  },
  "tags": [
    "smart-home",
    "hacs",
    "home-assistant"
  ],
  "last_reviewed": "2026-06-23",
  "source": {
    "path": "data/software/meshcore-ha/software.yaml",
    "updatedAt": "2026-06-23T23:23:42+02:00"
  },
  "latest_version": "2.8.0",
  "released": "2026-06-18",
  "releases": [
    {
      "version": "v2.8.0",
      "name": "v2.8.0",
      "datetime": "2026-06-18T01:55:11Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.8.0",
      "prerelease": false,
      "notes": "## Features\n\n- **Unified Contact Discovery Mode** (#261) — the two overlapping contact-discovery flags (`disable_contact_discovery` and the never-shipped `large_mesh_mode`) are collapsed into a single **Contact Discovery Mode** select with three choices:\n  - **Entity per contact** (default) — one diagnostic binary_sensor per discovered contact, same as before.\n  - **Data only** — discovered (un-added) contacts are tracked as data with no per-contact entity, while added/curated contacts keep theirs. On dense meshes this avoids hundreds of low-utility entities and the entity-registry churn they drive. The dropdown, services, chat panel, an aggregate summary sensor, and `meshcore.get_discovered_contact` all keep working.\n  - **Disabled** — no discovered-contact processing at all.\n\n  Set it at install time or in Configure → Global Settings.\n\n## Fixes\n\n- **Telemetry/GPS AttributeError from untracked nodes** (#266) — `_get_node_info` assumed a dict-shaped `public_key`; a TELEMETRY/GPS event from a node that wasn't a tracked repeater/client/root raised `AttributeError` on the string-shaped key and killed the handler.\n- **node_status sensor stuck \"Disconnected\"** (#267) — the status callback set its value but never pushed state, so the header indicator could show disconnected (while actually connected) until the next device event. Now pushes on event and seeds an initial value at setup.\n- **UTC-aware MQTT timestamps** (#259) — status, raw event, and normalized packet payloads now emit offset-aware ISO 8601 timestamps so consumers don't misread local time as UTC. Fixes #258.\n- **Quiet benign reconnect-race log noise** (#268) — the `no_event_received` result from the `get_msg` loops during config re-add / reconnect is downgraded to debug; real errors still log at ERROR.\n- **Flood-scope `*` wildcard** (#263) — a raw `*` entry in the flood-scope allowlist is now recognized as the global wildcard and skipped, instead of deriving a junk transport key for a non-existent `#*` region.\n\n## Notes\n\n- **Migration on first start**: existing installs migrate config entry v2 → v3 automatically. `disable_contact_discovery=true` maps to **Disabled**; otherwise the mode defaults to **Entity per contact**, so behavior is unchanged unless you opt into **Data only**. No reload, no entity-registry churn.\n- **MQTT timestamp format change** (#259): the `time`/`date` display fields in MQTT packet payloads now reflect UTC wall-clock rather than local time. If you parse those downstream, note the shift.\n- Minimum Home Assistant version remains `2023.8.0`. No `meshcore-py` floor change (still `>=2.3.7`).",
      "notesHtml": "<h2>Features</h2>\n<ul>\n<li><p><strong>Unified Contact Discovery Mode</strong> (#261) — the two overlapping contact-discovery flags (<code>disable_contact_discovery</code> and the never-shipped <code>large_mesh_mode</code>) are collapsed into a single <strong>Contact Discovery Mode</strong> select with three choices:</p>\n<ul>\n<li><strong>Entity per contact</strong> (default) — one diagnostic binary_sensor per discovered contact, same as before.</li>\n<li><strong>Data only</strong> — discovered (un-added) contacts are tracked as data with no per-contact entity, while added/curated contacts keep theirs. On dense meshes this avoids hundreds of low-utility entities and the entity-registry churn they drive. The dropdown, services, chat panel, an aggregate summary sensor, and <code>meshcore.get_discovered_contact</code> all keep working.</li>\n<li><strong>Disabled</strong> — no discovered-contact processing at all.</li>\n</ul>\n<p>Set it at install time or in Configure → Global Settings.</p>\n</li>\n</ul>\n<h2>Fixes</h2>\n<ul>\n<li><strong>Telemetry/GPS AttributeError from untracked nodes</strong> (#266) — <code>_get_node_info</code> assumed a dict-shaped <code>public_key</code>; a TELEMETRY/GPS event from a node that wasn't a tracked repeater/client/root raised <code>AttributeError</code> on the string-shaped key and killed the handler.</li>\n<li><strong>node_status sensor stuck \"Disconnected\"</strong> (#267) — the status callback set its value but never pushed state, so the header indicator could show disconnected (while actually connected) until the next device event. Now pushes on event and seeds an initial value at setup.</li>\n<li><strong>UTC-aware MQTT timestamps</strong> (#259) — status, raw event, and normalized packet payloads now emit offset-aware ISO 8601 timestamps so consumers don't misread local time as UTC. Fixes #258.</li>\n<li><strong>Quiet benign reconnect-race log noise</strong> (#268) — the <code>no_event_received</code> result from the <code>get_msg</code> loops during config re-add / reconnect is downgraded to debug; real errors still log at ERROR.</li>\n<li><strong>Flood-scope <code>*</code> wildcard</strong> (#263) — a raw <code>*</code> entry in the flood-scope allowlist is now recognized as the global wildcard and skipped, instead of deriving a junk transport key for a non-existent <code>#*</code> region.</li>\n</ul>\n<h2>Notes</h2>\n<ul>\n<li><strong>Migration on first start</strong>: existing installs migrate config entry v2 → v3 automatically. <code>disable_contact_discovery=true</code> maps to <strong>Disabled</strong>; otherwise the mode defaults to <strong>Entity per contact</strong>, so behavior is unchanged unless you opt into <strong>Data only</strong>. No reload, no entity-registry churn.</li>\n<li><strong>MQTT timestamp format change</strong> (#259): the <code>time</code>/<code>date</code> display fields in MQTT packet payloads now reflect UTC wall-clock rather than local time. If you parse those downstream, note the shift.</li>\n<li>Minimum Home Assistant version remains <code>2023.8.0</code>. No <code>meshcore-py</code> floor change (still <code>&gt;=2.3.7</code>).</li>\n</ul>\n"
    },
    {
      "version": "v2.7.0",
      "name": "v2.7.0",
      "datetime": "2026-06-01T02:44:44Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.7.0",
      "prerelease": false,
      "notes": "## Features\n\n- **Self-diagnostic sensors for the companion node** (#251) — opt-in polling of the locally-attached companion's `get_stats_core` / `get_stats_radio` / `get_stats_packets`, exposed as 13+ new sensors on the main device. Local-transport queries only — no mesh traffic.\n- **Region-scoped channel broadcasts** (#250) — new `scope` parameter on `meshcore.send_channel_message` for TC_FLOOD region-scoped sends. Optional `flood_scopes` allowlist in global settings labels incoming scoped messages with their region name.\n- **Remove orphan devices from the UI** (#247) — repeater, client, and contact devices that are no longer tracked can now be deleted via the HA device page. Hub and live devices are refused. Closes #229.\n- **Repeater neighbor count sensor** (#228) — per-repeater count of active neighbors derived from the existing neighbor list.\n- **hop_count + snr on incoming channel messages** (#245) — logbook event now carries SNR and hop count for channel traffic, matching the existing DM behavior.\n- **Conditional recipient type selection** (#218) — adapts the message-input UI based on the chosen recipient.\n\n## Fixes\n\n- **Region-scope (TC_FLOOD) RX_LOG correlation** (#246) — fixes a 4-byte transport-code offset that broke RX_LOG correlation for all region-scoped messages and corrects the AES plaintext offset. Closes #237, #242, #198.\n- **path_hash_size on rx_log correlation entry** (#249) — completes #226 by propagating the per-hop hash width to every consumer of `meshcore_message`.\n- **execute_command response normalization** (#248) — `req_*_sync` helpers that return plain dicts, lists, scalars, or `None` are now surfaced correctly instead of being silently dropped or raising a confusing error.\n- **Discovered-contact cleanup post-#236** (#252) — repairs four cleanup paths that the #236 unique_id migration left looking up entities by the old format.\n- **Recorder cap on discovered-contact select** (#254) — `options` is now excluded from recorder state, dodging the 16 KiB per-state attribute cap that fired warnings on dense meshes. Closes #243.\n- **Removed `hass.helpers.entity_registry.async_get()` accessor** (#253) — switched to `er.async_get(hass)` in three contact services. Fixes `AttributeError` on recent HA core.\n- **MQTT startup wait** (#244) — fixes a task that blocked HA boot.\n- **recv errors as count + measurement** (#239) — corrects sensor types.\n- **multi-entry message_sent fan-out** (#235) — filters by entry_id.\n- **Contact-diagnostic unique_id scoping** (#236) — scoped by entry_id with one-time migration.\n- **TZ-aware UTC timestamp on meshcore_message** (#234).\n- **RX_LOG multi-byte path size parsing** (#226).\n\n## Docs\n\n- Companion Integration API page (#217)\n- ESPHome BLE bridge workaround (#223)\n- Discord community channel linked in README + docs site\n\n## Notes\n\n- Minimum Home Assistant version remains `2023.8.0`.\n- The `meshcore-py` floor is `>=2.3.7` (was bumped in #222).\n- #236's unique_id migration runs once per install on first start of this release. Entities migrate automatically. Users on the broken cleanup state from earlier #236-only installs will see the Phase 4 orphan sweep clean up stale registry entries (covered by #252).\n- #251 self-diagnostics defaults off. Enable in Global Settings if you want the new sensors.",
      "notesHtml": "<h2>Features</h2>\n<ul>\n<li><strong>Self-diagnostic sensors for the companion node</strong> (#251) — opt-in polling of the locally-attached companion's <code>get_stats_core</code> / <code>get_stats_radio</code> / <code>get_stats_packets</code>, exposed as 13+ new sensors on the main device. Local-transport queries only — no mesh traffic.</li>\n<li><strong>Region-scoped channel broadcasts</strong> (#250) — new <code>scope</code> parameter on <code>meshcore.send_channel_message</code> for TC_FLOOD region-scoped sends. Optional <code>flood_scopes</code> allowlist in global settings labels incoming scoped messages with their region name.</li>\n<li><strong>Remove orphan devices from the UI</strong> (#247) — repeater, client, and contact devices that are no longer tracked can now be deleted via the HA device page. Hub and live devices are refused. Closes #229.</li>\n<li><strong>Repeater neighbor count sensor</strong> (#228) — per-repeater count of active neighbors derived from the existing neighbor list.</li>\n<li><strong>hop_count + snr on incoming channel messages</strong> (#245) — logbook event now carries SNR and hop count for channel traffic, matching the existing DM behavior.</li>\n<li><strong>Conditional recipient type selection</strong> (#218) — adapts the message-input UI based on the chosen recipient.</li>\n</ul>\n<h2>Fixes</h2>\n<ul>\n<li><strong>Region-scope (TC_FLOOD) RX_LOG correlation</strong> (#246) — fixes a 4-byte transport-code offset that broke RX_LOG correlation for all region-scoped messages and corrects the AES plaintext offset. Closes #237, #242, #198.</li>\n<li><strong>path_hash_size on rx_log correlation entry</strong> (#249) — completes #226 by propagating the per-hop hash width to every consumer of <code>meshcore_message</code>.</li>\n<li><strong>execute_command response normalization</strong> (#248) — <code>req_*_sync</code> helpers that return plain dicts, lists, scalars, or <code>None</code> are now surfaced correctly instead of being silently dropped or raising a confusing error.</li>\n<li><strong>Discovered-contact cleanup post-#236</strong> (#252) — repairs four cleanup paths that the #236 unique_id migration left looking up entities by the old format.</li>\n<li><strong>Recorder cap on discovered-contact select</strong> (#254) — <code>options</code> is now excluded from recorder state, dodging the 16 KiB per-state attribute cap that fired warnings on dense meshes. Closes #243.</li>\n<li><strong>Removed <code>hass.helpers.entity_registry.async_get()</code> accessor</strong> (#253) — switched to <code>er.async_get(hass)</code> in three contact services. Fixes <code>AttributeError</code> on recent HA core.</li>\n<li><strong>MQTT startup wait</strong> (#244) — fixes a task that blocked HA boot.</li>\n<li><strong>recv errors as count + measurement</strong> (#239) — corrects sensor types.</li>\n<li><strong>multi-entry message_sent fan-out</strong> (#235) — filters by entry_id.</li>\n<li><strong>Contact-diagnostic unique_id scoping</strong> (#236) — scoped by entry_id with one-time migration.</li>\n<li><strong>TZ-aware UTC timestamp on meshcore_message</strong> (#234).</li>\n<li><strong>RX_LOG multi-byte path size parsing</strong> (#226).</li>\n</ul>\n<h2>Docs</h2>\n<ul>\n<li>Companion Integration API page (#217)</li>\n<li>ESPHome BLE bridge workaround (#223)</li>\n<li>Discord community channel linked in README + docs site</li>\n</ul>\n<h2>Notes</h2>\n<ul>\n<li>Minimum Home Assistant version remains <code>2023.8.0</code>.</li>\n<li>The <code>meshcore-py</code> floor is <code>&gt;=2.3.7</code> (was bumped in #222).</li>\n<li>#236's unique_id migration runs once per install on first start of this release. Entities migrate automatically. Users on the broken cleanup state from earlier #236-only installs will see the Phase 4 orphan sweep clean up stale registry entries (covered by #252).</li>\n<li>#251 self-diagnostics defaults off. Enable in Global Settings if you want the new sensors.</li>\n</ul>\n"
    },
    {
      "version": "v2.6.0",
      "name": "v2.6.0",
      "datetime": "2026-04-28T05:19:48Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.6.0",
      "prerelease": false,
      "notes": "## Features\n\n- **Structured query services for companion integrations** (#216) — new `meshcore.get_contacts`, `meshcore.get_channels`, and `meshcore.trace` services return typed responses so companions don't have to scrape `execute_command` output.\n- **SNR + hop count on incoming DM events** (#215) — `meshcore_message` events now include `hop_count` (always) and `snr` (V3 firmware) for direct messages, matching what was already available for channel messages via `rx_log_data`.\n- **Repeater neighbor sensors** (#211) — per-repeater SNR and activity sensors with auto-cleanup of stale neighbors, plus an opt-in toggle and configurable airtime cost in the global settings.\n- **Per-device online binary sensor** (#209) — replaces the imprecise global `device.connected` flag with per-device `binary_sensor.*_online` entities derived from `_last_successful_request` timing.\n- **Stale discovered-contact cleanup** (#183) — new `days_threshold` parameter on `clear_discovered_contacts`, plus an opt-in daily auto-cleanup with a configurable threshold.\n- **Adaptive RX_LOG poll-wait** (#182) — replaces the blocking 500ms sleep on incoming channel messages with a 50ms-step poll that fires as soon as data arrives, with a background pass for late-arriving repeater RX_LOGs delivered as `meshcore_delivery_update` events.\n\n## Fixes\n\n- **Entity-identity stabilization** (#201) — removes device name from `unique_id` (one-time startup migration), refreshes SELF_INFO after config-modifying commands, and adds missing `async_write_ha_state()` so frontend updates without a reload.\n- **Map uploader** (#200) — corrects ADV_TYPE_CHAT and points the uploader at meshcore.io.\n- **Telemetry sensors** (#191) — restores missing `device_class` and units on telemetry sensors.\n- **execute_command AttributeError** (#190) — removes a stale `set_command_result` call.\n\n## Docs\n\n- README now links to the [meshcore-card](https://github.com/jpettitt/meshcore-card) Lovelace card (#220).\n- Installation docs USB firmware note (#133).\n\n## Notes\n\n- **Migration on first start**: #201 strips device names from `unique_id` once per upgrade; entities migrate automatically. Some users may see a brief reload as the registry updates.\n- The minimum Home Assistant version remains `2023.8.0`.",
      "notesHtml": "<h2>Features</h2>\n<ul>\n<li><strong>Structured query services for companion integrations</strong> (#216) — new <code>meshcore.get_contacts</code>, <code>meshcore.get_channels</code>, and <code>meshcore.trace</code> services return typed responses so companions don't have to scrape <code>execute_command</code> output.</li>\n<li><strong>SNR + hop count on incoming DM events</strong> (#215) — <code>meshcore_message</code> events now include <code>hop_count</code> (always) and <code>snr</code> (V3 firmware) for direct messages, matching what was already available for channel messages via <code>rx_log_data</code>.</li>\n<li><strong>Repeater neighbor sensors</strong> (#211) — per-repeater SNR and activity sensors with auto-cleanup of stale neighbors, plus an opt-in toggle and configurable airtime cost in the global settings.</li>\n<li><strong>Per-device online binary sensor</strong> (#209) — replaces the imprecise global <code>device.connected</code> flag with per-device <code>binary_sensor.*_online</code> entities derived from <code>_last_successful_request</code> timing.</li>\n<li><strong>Stale discovered-contact cleanup</strong> (#183) — new <code>days_threshold</code> parameter on <code>clear_discovered_contacts</code>, plus an opt-in daily auto-cleanup with a configurable threshold.</li>\n<li><strong>Adaptive RX_LOG poll-wait</strong> (#182) — replaces the blocking 500ms sleep on incoming channel messages with a 50ms-step poll that fires as soon as data arrives, with a background pass for late-arriving repeater RX_LOGs delivered as <code>meshcore_delivery_update</code> events.</li>\n</ul>\n<h2>Fixes</h2>\n<ul>\n<li><strong>Entity-identity stabilization</strong> (#201) — removes device name from <code>unique_id</code> (one-time startup migration), refreshes SELF_INFO after config-modifying commands, and adds missing <code>async_write_ha_state()</code> so frontend updates without a reload.</li>\n<li><strong>Map uploader</strong> (#200) — corrects ADV_TYPE_CHAT and points the uploader at meshcore.io.</li>\n<li><strong>Telemetry sensors</strong> (#191) — restores missing <code>device_class</code> and units on telemetry sensors.</li>\n<li><strong>execute_command AttributeError</strong> (#190) — removes a stale <code>set_command_result</code> call.</li>\n</ul>\n<h2>Docs</h2>\n<ul>\n<li>README now links to the <a href=\"https://github.com/jpettitt/meshcore-card\" target=\"_blank\" rel=\"noopener noreferrer\">meshcore-card</a> Lovelace card (#220).</li>\n<li>Installation docs USB firmware note (#133).</li>\n</ul>\n<h2>Notes</h2>\n<ul>\n<li><strong>Migration on first start</strong>: #201 strips device names from <code>unique_id</code> once per upgrade; entities migrate automatically. Some users may see a brief reload as the registry updates.</li>\n<li>The minimum Home Assistant version remains <code>2023.8.0</code>.</li>\n</ul>\n"
    },
    {
      "version": "v2.5.0",
      "name": "v2.5.0",
      "datetime": "2026-04-01T16:21:30Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.5.0",
      "prerelease": false,
      "notes": "## What's New\n\n### Map Auto Uploader\nAutomatically uploads repeater and room server adverts to [map.meshcore.dev](https://map.meshcore.dev) when your companion hears them. No separate bot needed. Enable in Global Settings. Requires `ENABLE_PRIVATE_KEY_EXPORT=1` on firmware. (#163)\n\n### Message Delivery Feedback\nNew `Last Message Delivery` sensor shows real-time delivery status for sent messages. Channel messages show repeater count (progressive updates as relays arrive). Direct messages show ACK confirmation. (#168)\n\n### Instant Message Delivery\nSubscribes to the firmware's `MESSAGES_WAITING` push notification for near-instant message fetching instead of waiting for the poll interval. (#177)\n\n### Reconfigure Connection\nChange your connection type (USB/BLE/TCP) or parameters without deleting and re-adding the integration. All settings are preserved. Look for the \"Reconfigure\" button on the integration page. (#187)\n\n### Public Key Change Detection\nDetects when a companion device's public key changes (e.g., after firmware reflash) and automatically migrates all entity IDs. Creates a repair notification for any manual references that need updating. (#169)\n\n### Companion Prefix Sensor\nNew sensor showing the device's routing prefix based on `path_hash_mode`, with live updates from SELF_INFO events. (#169)\n\n## Fixes\n\n- **Repeater status/telemetry timeouts** — Fixed login check (was comparing against wrong event type), switched to SDK sync methods with firmware-calculated timeouts. Multi-hop repeaters now respond reliably. (#185)\n- **coordinator.data set to None** — `_async_update_data` now returns `result_data` so HA's coordinator framework has valid data. Fixes `NoneType has no attribute 'get'` crashes. (#171)\n- **Repeater firmware version not updating** — Re-queries firmware version when editing a repeater in Manage Devices. (#179)\n- **Edit repeater clears password** — Password field no longer gets overwritten with empty string when saving other settings. (#179)\n- **set_flood_scope type** — Fixed parameter type from `int` to `str`. (#181)\n- **Conditional message polling** — Replaced unconditional `get_msg()` every 5s with a 60-second safety-net poll, reducing ~17,280 unnecessary commands/day on quiet meshes. (#186)\n- **mesh_core returns None when disconnected** — Prevents startup crashes when device isn't available. (#163)\n- **ConfigEntryNotReady on connection failure** — HA retries connection automatically instead of leaving the integration in a broken state. (#173)\n\n## Other\n\n- Dutch and Slovak translations for new features\n- Last command result sensor for dashboard CLI feedback (#163)\n- Channel select now filters unused/empty channels (#163)\n- `execute_command` supports `return_response` for automation use (#169)\n- OptionsFlow updated to HA 2024+ pattern (#163)\n- Deprecated `logger.warn()` calls replaced with `logger.warning()`",
      "notesHtml": "<h2>What's New</h2>\n<h3>Map Auto Uploader</h3>\n<p>Automatically uploads repeater and room server adverts to <a href=\"https://map.meshcore.dev/\" target=\"_blank\" rel=\"noopener noreferrer\">map.meshcore.dev</a> when your companion hears them. No separate bot needed. Enable in Global Settings. Requires <code>ENABLE_PRIVATE_KEY_EXPORT=1</code> on firmware. (#163)</p>\n<h3>Message Delivery Feedback</h3>\n<p>New <code>Last Message Delivery</code> sensor shows real-time delivery status for sent messages. Channel messages show repeater count (progressive updates as relays arrive). Direct messages show ACK confirmation. (#168)</p>\n<h3>Instant Message Delivery</h3>\n<p>Subscribes to the firmware's <code>MESSAGES_WAITING</code> push notification for near-instant message fetching instead of waiting for the poll interval. (#177)</p>\n<h3>Reconfigure Connection</h3>\n<p>Change your connection type (USB/BLE/TCP) or parameters without deleting and re-adding the integration. All settings are preserved. Look for the \"Reconfigure\" button on the integration page. (#187)</p>\n<h3>Public Key Change Detection</h3>\n<p>Detects when a companion device's public key changes (e.g., after firmware reflash) and automatically migrates all entity IDs. Creates a repair notification for any manual references that need updating. (#169)</p>\n<h3>Companion Prefix Sensor</h3>\n<p>New sensor showing the device's routing prefix based on <code>path_hash_mode</code>, with live updates from SELF_INFO events. (#169)</p>\n<h2>Fixes</h2>\n<ul>\n<li><strong>Repeater status/telemetry timeouts</strong> — Fixed login check (was comparing against wrong event type), switched to SDK sync methods with firmware-calculated timeouts. Multi-hop repeaters now respond reliably. (#185)</li>\n<li><strong>coordinator.data set to None</strong> — <code>_async_update_data</code> now returns <code>result_data</code> so HA's coordinator framework has valid data. Fixes <code>NoneType has no attribute 'get'</code> crashes. (#171)</li>\n<li><strong>Repeater firmware version not updating</strong> — Re-queries firmware version when editing a repeater in Manage Devices. (#179)</li>\n<li><strong>Edit repeater clears password</strong> — Password field no longer gets overwritten with empty string when saving other settings. (#179)</li>\n<li><strong>set_flood_scope type</strong> — Fixed parameter type from <code>int</code> to <code>str</code>. (#181)</li>\n<li><strong>Conditional message polling</strong> — Replaced unconditional <code>get_msg()</code> every 5s with a 60-second safety-net poll, reducing ~17,280 unnecessary commands/day on quiet meshes. (#186)</li>\n<li><strong>mesh_core returns None when disconnected</strong> — Prevents startup crashes when device isn't available. (#163)</li>\n<li><strong>ConfigEntryNotReady on connection failure</strong> — HA retries connection automatically instead of leaving the integration in a broken state. (#173)</li>\n</ul>\n<h2>Other</h2>\n<ul>\n<li>Dutch and Slovak translations for new features</li>\n<li>Last command result sensor for dashboard CLI feedback (#163)</li>\n<li>Channel select now filters unused/empty channels (#163)</li>\n<li><code>execute_command</code> supports <code>return_response</code> for automation use (#169)</li>\n<li>OptionsFlow updated to HA 2024+ pattern (#163)</li>\n<li>Deprecated <code>logger.warn()</code> calls replaced with <code>logger.warning()</code></li>\n</ul>\n"
    },
    {
      "version": "V2.4.1",
      "name": "V2.4.1",
      "datetime": "2026-03-07T16:20:29Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/V2.4.1",
      "prerelease": false,
      "notes": "* Bump meshcore requirement to >=2.2.24 by @yellowcooln in https://github.com/meshcore-dev/meshcore-ha/pull/155\r\n* Fix LetsMesh MQTT Status Parity: Accurate Startup Metadata, Radio Format Alignment, and Secure Owner Claims by @yellowcooln in https://github.com/meshcore-dev/meshcore-ha/pull/152",
      "notesHtml": "<ul>\n<li>Bump meshcore requirement to &gt;=2.2.24 by @yellowcooln in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/155\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/155</a></li>\n<li>Fix LetsMesh MQTT Status Parity: Accurate Startup Metadata, Radio Format Alignment, and Secure Owner Claims by @yellowcooln in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/152\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/152</a></li>\n</ul>\n"
    },
    {
      "version": "v2.4.0",
      "name": "V2.4.0",
      "datetime": "2026-03-03T03:07:52Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.4.0",
      "prerelease": false,
      "notes": "### MQTT Upload Support\r\n- Multi-broker MQTT upload with full UI configuration\r\n- LetsMesh integration with EdDSA auth-token support (Python fallback when CLI unavailable)\r\n- Per-broker owner/email JWT claim settings\r\n- Periodic MQTT status metrics for LetsMesh observer support\r\n- Packet-only publishing aligned with meshcoretomqtt format\r\n- Broker connection status binary sensors\r\n- Auto-fetch device private key for auth tokens\r\n- Packet hash stabilization to reduce LetsMesh duplicates\r\n\r\n### Execute Command Improvements\r\n- Bump `meshcore` to `>=2.2.15` with synced command parameter mappings\r\n- Functional syntax support: `set_coords(37.7749, -122.4194)` (fixes #111)\r\n- Supports positional args, keyword args, strings, numbers, booleans, and bytes literals\r\n- Add `set_flood_scope` command\r\n\r\n### Discovered Contacts Management\r\n- New opt-in FIFO limit for discovered contacts (configurable max, default 100 when enabled)\r\n- Oldest contacts evicted first; re-advertisements refresh queue position\r\n- Evicted contacts have binary sensor entities automatically removed\r\n- New `meshcore.clear_discovered_contacts` service to remove all at once\r\n\r\n### Bug Fixes\r\n- Fix duplicate entry setup and guard static path registration\r\n- Fix options menu contact detection for repeaters and clients\r\n- Fix missing log argument\r\n- Only cleanup devices associated with the current entry\r\n\r\n### Telemetry\r\n- Support negative current readings (charging vs discharging)\r\n- Add power sensor, display current in mA\r\n- 2-character pubkey prefix for display\r\n\r\n### Documentation\r\n- Add MQTT upload documentation page\r\n- Document functional command syntax in services docs\r\n- Add contact FIFO limit section to contacts docs\r\n- Replace manual storage file deletion with `clear_discovered_contacts` service\r\n\r\n### Housekeeping\r\n- Add `__pycache__/`, `*.pyc`, `.pytest_cache` to `.gitignore`\r\n- Add test infrastructure and unit tests for command parsing and contact eviction",
      "notesHtml": "<h3>MQTT Upload Support</h3>\n<ul>\n<li>Multi-broker MQTT upload with full UI configuration</li>\n<li>LetsMesh integration with EdDSA auth-token support (Python fallback when CLI unavailable)</li>\n<li>Per-broker owner/email JWT claim settings</li>\n<li>Periodic MQTT status metrics for LetsMesh observer support</li>\n<li>Packet-only publishing aligned with meshcoretomqtt format</li>\n<li>Broker connection status binary sensors</li>\n<li>Auto-fetch device private key for auth tokens</li>\n<li>Packet hash stabilization to reduce LetsMesh duplicates</li>\n</ul>\n<h3>Execute Command Improvements</h3>\n<ul>\n<li>Bump <code>meshcore</code> to <code>&gt;=2.2.15</code> with synced command parameter mappings</li>\n<li>Functional syntax support: <code>set_coords(37.7749, -122.4194)</code> (fixes #111)</li>\n<li>Supports positional args, keyword args, strings, numbers, booleans, and bytes literals</li>\n<li>Add <code>set_flood_scope</code> command</li>\n</ul>\n<h3>Discovered Contacts Management</h3>\n<ul>\n<li>New opt-in FIFO limit for discovered contacts (configurable max, default 100 when enabled)</li>\n<li>Oldest contacts evicted first; re-advertisements refresh queue position</li>\n<li>Evicted contacts have binary sensor entities automatically removed</li>\n<li>New <code>meshcore.clear_discovered_contacts</code> service to remove all at once</li>\n</ul>\n<h3>Bug Fixes</h3>\n<ul>\n<li>Fix duplicate entry setup and guard static path registration</li>\n<li>Fix options menu contact detection for repeaters and clients</li>\n<li>Fix missing log argument</li>\n<li>Only cleanup devices associated with the current entry</li>\n</ul>\n<h3>Telemetry</h3>\n<ul>\n<li>Support negative current readings (charging vs discharging)</li>\n<li>Add power sensor, display current in mA</li>\n<li>2-character pubkey prefix for display</li>\n</ul>\n<h3>Documentation</h3>\n<ul>\n<li>Add MQTT upload documentation page</li>\n<li>Document functional command syntax in services docs</li>\n<li>Add contact FIFO limit section to contacts docs</li>\n<li>Replace manual storage file deletion with <code>clear_discovered_contacts</code> service</li>\n</ul>\n<h3>Housekeeping</h3>\n<ul>\n<li>Add <code>__pycache__/</code>, <code>*.pyc</code>, <code>.pytest_cache</code> to <code>.gitignore</code></li>\n<li>Add test infrastructure and unit tests for command parsing and contact eviction</li>\n</ul>\n"
    },
    {
      "version": "V2.3.0",
      "name": "V2.3.0",
      "datetime": "2026-02-05T20:47:45Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/V2.3.0",
      "prerelease": false,
      "notes": "* Fixes issues with non-normalized repeater names and the latest versions of home assistant",
      "notesHtml": "<ul>\n<li>Fixes issues with non-normalized repeater names and the latest versions of home assistant</li>\n</ul>\n"
    },
    {
      "version": "v2.2.5",
      "name": "v2.2.5",
      "datetime": "2026-01-26T21:21:19Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.2.5",
      "prerelease": false,
      "notes": "Fix documentation link",
      "notesHtml": "<p>Fix documentation link</p>\n"
    },
    {
      "version": "v2.2.4",
      "name": "v2.2.4",
      "datetime": "2025-12-27T22:18:30Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.2.4",
      "prerelease": false,
      "notes": "Fix issue with broken contact select options",
      "notesHtml": "<p>Fix issue with broken contact select options</p>\n"
    },
    {
      "version": "v2.2.3",
      "name": "v2.2.3",
      "datetime": "2025-11-28T06:03:49Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.2.3",
      "prerelease": false,
      "notes": "Fixes minor issue with sensors reverting to discovered after being added to the connected client.",
      "notesHtml": "<p>Fixes minor issue with sensors reverting to discovered after being added to the connected client.</p>\n"
    },
    {
      "version": "v2.2.2",
      "name": "v2.2.2",
      "datetime": "2025-11-27T06:39:05Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.2.2",
      "prerelease": false,
      "notes": "- Fixes some bugs preventing proper contact sensor synchronization when adding/removing contacts.\r\n- Changes RX and TX Airtime sensors to be TOTAL_INCREASING",
      "notesHtml": "<ul>\n<li>Fixes some bugs preventing proper contact sensor synchronization when adding/removing contacts.</li>\n<li>Changes RX and TX Airtime sensors to be TOTAL_INCREASING</li>\n</ul>\n"
    },
    {
      "version": "v2.2.1",
      "name": "v2.2.1",
      "datetime": "2025-11-23T17:58:52Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.2.1",
      "prerelease": false,
      "notes": "#### New Features\r\n\r\n  **RX_LOG Correlation**\r\n\r\n  - Automatic RX_LOG parsing and decryption - RX_LOG_DATA events are now automatically parsed and decrypted when\r\n  GroupText payloads are detected\r\n  - Multi-reception correlation - meshcore_message events now include rx_log_data with radio metrics (SNR, RSSI) and path\r\n   information from all mesh receptions\r\n  - Path visualization - See which routes your messages took through the mesh network\r\n\r\n  Example rx_log_data includes:\r\n  - Signal quality (SNR/RSSI)\r\n  - Mesh path (hop nodes)\r\n  - Channel hash\r\n  - Multiple receptions from different routes\r\n\r\n  **Contact Management**\r\n\r\n  - Remove discovered contact service - New service to clean up discovered contacts from Home Assistant without removing from \r\n  node\r\n  - Disable contact discovery toggle - New global setting to disable automatic contact sensor creation for large networks (500+ \r\n  contacts)\r\n\r\n  #### Improvements\r\n\r\n  **Performance & Reliability**\r\n\r\n  - Rate limiting - Token bucket refill rate reduced from 180s to 120s (2 minutes instead of 3)\r\n  - Auto-disable inactive devices - Tracked repeaters/clients automatically disable after 5 days without successful\r\n  requests (120 hours)\r\n  - Increased sensor timeout tolerance - Sensors now wait 3x the update interval before marking unavailable (previously\r\n  1.5x)\r\n  - Event-driven contact updates - Removed contact refresh interval setting in favor of real-time NEW_CONTACT event handling\r\n\r\n  **Bug Fixes**\r\n\r\n  - Fixed service parameter types for change_contact_path and change_contact_flags methods",
      "notesHtml": "<h4>New Features</h4>\n<p>  <strong>RX_LOG Correlation</strong></p>\n<ul>\n<li>Automatic RX_LOG parsing and decryption - RX_LOG_DATA events are now automatically parsed and decrypted when\n  GroupText payloads are detected</li>\n<li>Multi-reception correlation - meshcore_message events now include rx_log_data with radio metrics (SNR, RSSI) and path\n   information from all mesh receptions</li>\n<li>Path visualization - See which routes your messages took through the mesh network</li>\n</ul>\n<p>  Example rx_log_data includes:</p>\n<ul>\n<li>Signal quality (SNR/RSSI)</li>\n<li>Mesh path (hop nodes)</li>\n<li>Channel hash</li>\n<li>Multiple receptions from different routes</li>\n</ul>\n<p>  <strong>Contact Management</strong></p>\n<ul>\n<li>Remove discovered contact service - New service to clean up discovered contacts from Home Assistant without removing from \n  node</li>\n<li>Disable contact discovery toggle - New global setting to disable automatic contact sensor creation for large networks (500+ \n  contacts)</li>\n</ul>\n<h4>Improvements</h4>\n<p>  <strong>Performance &amp; Reliability</strong></p>\n<ul>\n<li>Rate limiting - Token bucket refill rate reduced from 180s to 120s (2 minutes instead of 3)</li>\n<li>Auto-disable inactive devices - Tracked repeaters/clients automatically disable after 5 days without successful\n  requests (120 hours)</li>\n<li>Increased sensor timeout tolerance - Sensors now wait 3x the update interval before marking unavailable (previously\n  1.5x)</li>\n<li>Event-driven contact updates - Removed contact refresh interval setting in favor of real-time NEW_CONTACT event handling</li>\n</ul>\n<p>  <strong>Bug Fixes</strong></p>\n<ul>\n<li>Fixed service parameter types for change_contact_path and change_contact_flags methods</li>\n</ul>\n"
    },
    {
      "version": "v2.2.0",
      "name": "v2.2.0",
      "datetime": "2025-10-29T05:04:29Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.2.0",
      "prerelease": false,
      "notes": "# MeshCore Home Assistant Integration - Version 2.2.0\r\n\r\n  ## 🚀 Major Features\r\n\r\n  ### Token Bucket Rate Limiting\r\n  - **New**: Intelligent rate limiting to protect mesh network from excessive traffic\r\n  - **Configuration**: 20 token burst capacity, 1 token refills every 3 minutes\r\n  - **Impact**: Sustains ~20 requests per hour across all tracked devices\r\n  - **Sensor**: Exposes a sensor to track the rate limiting bucket capacity overtime\r\n  - **Behavior**: Requests are skipped (not queued) when tokens depleted, logged as debug messages\r\n  - **Documentation**: Comprehensive rate limiting guide in remote device tracking docs\r\n\r\n  ### Device Disabling\r\n  - **New**: Temporarily disable repeaters or clients without removing them\r\n  - **Access**: Available in config flow → Manage Monitored Devices → Edit\r\n  - **Use Cases**:\r\n    - Maintenance windows\r\n    - Reducing network traffic\r\n    - Testing network performance\r\n    - Isolating problematic devices\r\n  - **Result**: All status, telemetry, and login requests stopped while entities remain\r\n\r\n  ### Manual Contact Management Mode\r\n  - **New**: Automatic manual contact mode on startup\r\n  - **Discovered Contacts**: New select entity for contacts not yet added to node\r\n  - **Added Contacts**: Separate select entity for contacts already on your node\r\n  - **Persistence**: Discovered contacts saved to `.storage/meshcore.<entry_id>.discovered_contacts`\r\n  - **Services**:\r\n    - `meshcore.add_selected_contact` - Add discovered contacts via UI\r\n    - `meshcore.remove_selected_contact` - Remove contacts via UI\r\n    - `meshcore.cleanup_unavailable_contacts` - Remove all unavailable contact sensors\r\n  - **Immediate Updates**: Contact list refreshes immediately on add/remove operations\r\n\r\n  ## ✨ Enhancements\r\n\r\n  ### Channel Improvements\r\n  - **Channel Select Entity**: Now displays actual channel names instead of \"Channel 0\"\r\n  - **Format**: \"Name (idx)\" e.g., \"#pdx (1)\", \"work (2)\"\r\n  - **Unused Channels**: Display as \"(unused) (idx)\" when not configured\r\n  - **Auto-Update**: Channel info refreshes immediately after `set_channel` commands\r\n  - **Documentation**: Complete guide on hash-based channel encryption and configuration UI\r\n\r\n  ### Channel Message Service\r\n  - **Fix**: Now correctly reads `channel_idx` from channel select entity attributes\r\n  - **Previous Issue**: Tried to parse channel index from display string\r\n  - **Result**: Works with new channel name format\r\n\r\n  ## 🐛 Bug Fixes\r\n\r\n  ### Reduced Login Packets\r\n  - **Fix**: Reduced excessive login attempts to repeaters\r\n  - **Reason**: Login is rarely the failure case in established sessions\r\n  - **Impact**: Reduces unnecessary mesh network traffic\r\n\r\n  ### Special Characters in Contact Names\r\n  - **Fix**: Handles names with parentheses correctly (e.g., \"Queen Anne (Soon)\")\r\n  - **Method**: Regex-based parsing extracts rightmost parentheses content\r\n  - **Centralized**: New `extract_pubkey_from_selection()` utility function\r\n\r\n  ## 🔄 Migration Notes\r\n\r\n  No breaking changes - all new features are additive. Existing configurations will continue to work without modification.",
      "notesHtml": "<h1>MeshCore Home Assistant Integration - Version 2.2.0</h1>\n<h2>🚀 Major Features</h2>\n<h3>Token Bucket Rate Limiting</h3>\n<ul>\n<li><strong>New</strong>: Intelligent rate limiting to protect mesh network from excessive traffic</li>\n<li><strong>Configuration</strong>: 20 token burst capacity, 1 token refills every 3 minutes</li>\n<li><strong>Impact</strong>: Sustains ~20 requests per hour across all tracked devices</li>\n<li><strong>Sensor</strong>: Exposes a sensor to track the rate limiting bucket capacity overtime</li>\n<li><strong>Behavior</strong>: Requests are skipped (not queued) when tokens depleted, logged as debug messages</li>\n<li><strong>Documentation</strong>: Comprehensive rate limiting guide in remote device tracking docs</li>\n</ul>\n<h3>Device Disabling</h3>\n<ul>\n<li><strong>New</strong>: Temporarily disable repeaters or clients without removing them</li>\n<li><strong>Access</strong>: Available in config flow → Manage Monitored Devices → Edit</li>\n<li><strong>Use Cases</strong>:<ul>\n<li>Maintenance windows</li>\n<li>Reducing network traffic</li>\n<li>Testing network performance</li>\n<li>Isolating problematic devices</li>\n</ul>\n</li>\n<li><strong>Result</strong>: All status, telemetry, and login requests stopped while entities remain</li>\n</ul>\n<h3>Manual Contact Management Mode</h3>\n<ul>\n<li><strong>New</strong>: Automatic manual contact mode on startup</li>\n<li><strong>Discovered Contacts</strong>: New select entity for contacts not yet added to node</li>\n<li><strong>Added Contacts</strong>: Separate select entity for contacts already on your node</li>\n<li><strong>Persistence</strong>: Discovered contacts saved to <code>.storage/meshcore.&lt;entry_id&gt;.discovered_contacts</code></li>\n<li><strong>Services</strong>:<ul>\n<li><code>meshcore.add_selected_contact</code> - Add discovered contacts via UI</li>\n<li><code>meshcore.remove_selected_contact</code> - Remove contacts via UI</li>\n<li><code>meshcore.cleanup_unavailable_contacts</code> - Remove all unavailable contact sensors</li>\n</ul>\n</li>\n<li><strong>Immediate Updates</strong>: Contact list refreshes immediately on add/remove operations</li>\n</ul>\n<h2>✨ Enhancements</h2>\n<h3>Channel Improvements</h3>\n<ul>\n<li><strong>Channel Select Entity</strong>: Now displays actual channel names instead of \"Channel 0\"</li>\n<li><strong>Format</strong>: \"Name (idx)\" e.g., \"#pdx (1)\", \"work (2)\"</li>\n<li><strong>Unused Channels</strong>: Display as \"(unused) (idx)\" when not configured</li>\n<li><strong>Auto-Update</strong>: Channel info refreshes immediately after <code>set_channel</code> commands</li>\n<li><strong>Documentation</strong>: Complete guide on hash-based channel encryption and configuration UI</li>\n</ul>\n<h3>Channel Message Service</h3>\n<ul>\n<li><strong>Fix</strong>: Now correctly reads <code>channel_idx</code> from channel select entity attributes</li>\n<li><strong>Previous Issue</strong>: Tried to parse channel index from display string</li>\n<li><strong>Result</strong>: Works with new channel name format</li>\n</ul>\n<h2>🐛 Bug Fixes</h2>\n<h3>Reduced Login Packets</h3>\n<ul>\n<li><strong>Fix</strong>: Reduced excessive login attempts to repeaters</li>\n<li><strong>Reason</strong>: Login is rarely the failure case in established sessions</li>\n<li><strong>Impact</strong>: Reduces unnecessary mesh network traffic</li>\n</ul>\n<h3>Special Characters in Contact Names</h3>\n<ul>\n<li><strong>Fix</strong>: Handles names with parentheses correctly (e.g., \"Queen Anne (Soon)\")</li>\n<li><strong>Method</strong>: Regex-based parsing extracts rightmost parentheses content</li>\n<li><strong>Centralized</strong>: New <code>extract_pubkey_from_selection()</code> utility function</li>\n</ul>\n<h2>🔄 Migration Notes</h2>\n<p>  No breaking changes - all new features are additive. Existing configurations will continue to work without modification.</p>\n"
    },
    {
      "version": "v2.1.12",
      "name": "v2.1.12",
      "datetime": "2025-10-22T20:05:36Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.1.12",
      "prerelease": false,
      "notes": "Add more decimal places to battery sensors\r\nAdd delay on server startup to avoid corrupting connections\r\nFix bug with repeater settings not persisting",
      "notesHtml": "<p>Add more decimal places to battery sensors\nAdd delay on server startup to avoid corrupting connections\nFix bug with repeater settings not persisting</p>\n"
    },
    {
      "version": "v2.1.11",
      "name": "v2.1.11",
      "datetime": "2025-10-19T03:13:31Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.1.11",
      "prerelease": false,
      "notes": "## What's Changed\r\n* Fix issue with nodes not resetting by @awolden in https://github.com/meshcore-dev/meshcore-ha/pull/89",
      "notesHtml": "<h2>What's Changed</h2>\n<ul>\n<li>Fix issue with nodes not resetting by @awolden in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/89\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/89</a></li>\n</ul>\n"
    },
    {
      "version": "v2.1.10",
      "name": "v2.1.10",
      "datetime": "2025-10-15T15:12:10Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.1.10",
      "prerelease": false,
      "notes": "- Adds channel name support. Channel name will now be used in logs and sensors instead of the index\r\n- Fixes a bug with sensors going stale after an hour if the configured interval was longer than an hour\r\n- Updates the default refresh interval to be 2 hours",
      "notesHtml": "<ul>\n<li>Adds channel name support. Channel name will now be used in logs and sensors instead of the index</li>\n<li>Fixes a bug with sensors going stale after an hour if the configured interval was longer than an hour</li>\n<li>Updates the default refresh interval to be 2 hours</li>\n</ul>\n"
    },
    {
      "version": "v2.1.9",
      "name": "v2.1.9",
      "datetime": "2025-10-13T19:08:28Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.1.9",
      "prerelease": false,
      "notes": "## What's Changed\r\n* Battery Percentage calc by @oliverl-21 in https://github.com/meshcore-dev/meshcore-ha/pull/77\r\n* Make all services translatable + update sk translation. by @jose1711 in https://github.com/meshcore-dev/meshcore-ha/pull/79\r\n* Add sensor support by @awolden in https://github.com/meshcore-dev/meshcore-ha/pull/84\r\n\r\n## New Contributors\r\n* @oliverl-21 made their first contribution in https://github.com/meshcore-dev/meshcore-ha/pull/77\r\n\r\n**Full Changelog**: https://github.com/meshcore-dev/meshcore-ha/compare/v2.1.8...v2.1.9",
      "notesHtml": "<h2>What's Changed</h2>\n<ul>\n<li>Battery Percentage calc by @oliverl-21 in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/77\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/77</a></li>\n<li>Make all services translatable + update sk translation. by @jose1711 in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/79\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/79</a></li>\n<li>Add sensor support by @awolden in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/84\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/84</a></li>\n</ul>\n<h2>New Contributors</h2>\n<ul>\n<li>@oliverl-21 made their first contribution in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/77\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/77</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/meshcore-dev/meshcore-ha/compare/v2.1.8...v2.1.9\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/compare/v2.1.8...v2.1.9</a></p>\n"
    },
    {
      "version": "v2.1.8",
      "name": "v2.1.8",
      "datetime": "2025-10-05T18:15:37Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.1.8",
      "prerelease": false,
      "notes": "- Improved call spacing to reduce collisions\r\n- Added more translation keys\r\n- Added flag to disable path resetting",
      "notesHtml": "<ul>\n<li>Improved call spacing to reduce collisions</li>\n<li>Added more translation keys</li>\n<li>Added flag to disable path resetting</li>\n</ul>\n"
    },
    {
      "version": "v2.1.7",
      "name": "2.1.7",
      "datetime": "2025-10-03T22:48:02Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.1.7",
      "prerelease": false,
      "notes": "### Reliability Tracking Sensors\r\n  - **Request Success/Failure Counters**: New sensors track all over-the-wire communication attempts for\r\n  each monitored node\r\n  - **Complete Coverage**: Tracks login, status, and telemetry requests for comprehensive network health\r\n  monitoring\r\n  - **Troubleshooting**: Identify problematic nodes and routing issues with detailed success/failure\r\n  metrics\r\n\r\n  ### Flexible Update Intervals\r\n  - **Removed Maximum Limits**: Update intervals now support unlimited maximums \r\n  - **Unified Minimums**: Both repeaters and clients use consistent 300-second minimum intervals\r\n  - **Better Configuration**: Support for very long intervals (hours or days) for low-power scenarios\r\n\r\n  ### Enhanced Failure Handling\r\n  - **Smarter Backoff**: Dynamic base interval calculation ensures exactly 5 retries fit within configured\r\n   update windows\r\n  - **Faster Path Recovery**: Path reset now triggers after 3 failures (was 5) for quicker routing\r\n  recovery\r\n  - **Improved Login Logic**: Fixed bug where timeouts/unexpected responses were incorrectly counted as\r\n  successes\r\n\r\n  ## 🐛 Bug Fixes\r\n  - **Login Success Detection**: Now properly validates login responses instead of treating non-errors as\r\n  success\r\n- **path reset** - fixed an issue where path was not being set my the pubkey prefix arg",
      "notesHtml": "<h3>Reliability Tracking Sensors</h3>\n<ul>\n<li><strong>Request Success/Failure Counters</strong>: New sensors track all over-the-wire communication attempts for\n  each monitored node</li>\n<li><strong>Complete Coverage</strong>: Tracks login, status, and telemetry requests for comprehensive network health\n  monitoring</li>\n<li><strong>Troubleshooting</strong>: Identify problematic nodes and routing issues with detailed success/failure\n  metrics</li>\n</ul>\n<h3>Flexible Update Intervals</h3>\n<ul>\n<li><strong>Removed Maximum Limits</strong>: Update intervals now support unlimited maximums </li>\n<li><strong>Unified Minimums</strong>: Both repeaters and clients use consistent 300-second minimum intervals</li>\n<li><strong>Better Configuration</strong>: Support for very long intervals (hours or days) for low-power scenarios</li>\n</ul>\n<h3>Enhanced Failure Handling</h3>\n<ul>\n<li><strong>Smarter Backoff</strong>: Dynamic base interval calculation ensures exactly 5 retries fit within configured\n   update windows</li>\n<li><strong>Faster Path Recovery</strong>: Path reset now triggers after 3 failures (was 5) for quicker routing\n  recovery</li>\n<li><strong>Improved Login Logic</strong>: Fixed bug where timeouts/unexpected responses were incorrectly counted as\n  successes</li>\n</ul>\n<h2>🐛 Bug Fixes</h2>\n<ul>\n<li><strong>Login Success Detection</strong>: Now properly validates login responses instead of treating non-errors as\n  success</li>\n<li><strong>path reset</strong> - fixed an issue where path was not being set my the pubkey prefix arg</li>\n</ul>\n"
    },
    {
      "version": "v2.1.6",
      "name": "v2.1.6",
      "datetime": "2025-09-28T15:35:52Z",
      "url": "https://github.com/meshcore-dev/meshcore-ha/releases/tag/v2.1.6",
      "prerelease": false,
      "notes": "## What's Changed\r\n* Fix byte conversion by @awolden in https://github.com/meshcore-dev/meshcore-ha/pull/65\r\n\r\n\r\n**Full Changelog**: https://github.com/meshcore-dev/meshcore-ha/compare/v2.1.5...v2.1.6",
      "notesHtml": "<h2>What's Changed</h2>\n<ul>\n<li>Fix byte conversion by @awolden in <a href=\"https://github.com/meshcore-dev/meshcore-ha/pull/65\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/pull/65</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/meshcore-dev/meshcore-ha/compare/v2.1.5...v2.1.6\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/meshcore-ha/compare/v2.1.5...v2.1.6</a></p>\n"
    }
  ],
  "changelogSource": "github",
  "changelogUpdatedAt": "2026-06-23T19:22:18.102Z"
}
