{
  "schemaVersion": 3,
  "generatedAt": "2026-06-21T10:28:38.575Z",
  "counts": {
    "firmwares": 20,
    "devices": 97,
    "vendors": 23,
    "compatibility": 2
  },
  "firmwares": [
    {
      "id": "meshcore-official",
      "name": "MeshCore (Official)",
      "type": "official",
      "maintainer": "meshcore-dev (community project, originated by Scott Powell / ripplebiz)",
      "maintainers": [
        {
          "name": "meshcore-dev",
          "url": "https://github.com/meshcore-dev"
        },
        {
          "name": "Scott Powell"
        },
        {
          "name": "ripplebiz",
          "url": "https://github.com/ripplebiz"
        }
      ],
      "description": "The official MeshCore firmware — a lightweight C++ library and firmware for multi-hop packet routing over LoRa radios. It powers decentralized, self-healing mesh networks for off-grid, emergency and tactical communication, with prebuilt images and a web flasher.\n",
      "repository": "https://github.com/meshcore-dev/MeshCore",
      "website": "https://meshcore.io",
      "license": "MIT",
      "changelog": {
        "source": "script",
        "script": "fetch-changelog.js"
      },
      "status": "active",
      "lifecycle": "active",
      "maturity": "stable",
      "distribution": "official",
      "lineage": {
        "kind": "upstream"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "sensor"
      ],
      "features": [
        "Multi-hop packet routing",
        "End-to-end encrypted DMs",
        "BLE / USB / TCP companion clients",
        "Web, iOS, Android, Python & NodeJS clients",
        "Native flood-advert traffic management (1.16+)",
        "Web-based flasher"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true,
          "rawPacketSend": true,
          "rawPacketObserve": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "webFlasher": true,
          "ota": true,
          "bleDfu": true,
          "configurationBackup": true
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": false,
          "mqtt": false,
          "kissModem": true
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": true,
          "lowPowerRx": true
        }
      },
      "devices": [
        {
          "id": "ebyte-eora-s3",
          "status": "supported",
          "target": "ebyte_eora_s3",
          "platformio_board": "ebyte_eora-s3"
        },
        {
          "id": "gatiot-gat562-30s",
          "status": "supported",
          "target": "gat562_30s_mesh_kit",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562-evb-pro",
          "status": "supported",
          "target": "gat562_mesh_evb_pro",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562",
          "status": "supported",
          "target": "gat562_mesh_tracker_pro",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562-tracker-pro",
          "status": "supported",
          "target": "gat562_mesh_tracker_pro",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562-watch13",
          "status": "supported",
          "target": "gat562_mesh_watch13",
          "platformio_board": "rak4631"
        },
        {
          "id": "generic-e22",
          "status": "supported",
          "target": "generic-e22",
          "platformio_board": "esp32doit-devkit-v1"
        },
        {
          "id": "generic-espnow",
          "status": "supported",
          "target": "generic_espnow",
          "platformio_board": "esp32-c3-devkitm-1"
        },
        {
          "id": "heltec-ct62",
          "status": "supported",
          "target": "heltec_ct62",
          "platformio_board": "esp32-c3-devkitm-1"
        },
        {
          "id": "heltec-e213",
          "status": "supported",
          "target": "heltec_e213",
          "platformio_board": "heltec_e213"
        },
        {
          "id": "heltec-e290",
          "status": "supported",
          "target": "heltec_e290",
          "platformio_board": "heltec_e290"
        },
        {
          "id": "heltec-mesh-solar",
          "status": "supported",
          "target": "heltec_mesh_solar",
          "platformio_board": "heltec_mesh_solar"
        },
        {
          "id": "heltec-t096",
          "status": "supported",
          "target": "heltec_t096",
          "platformio_board": "heltec_t096"
        },
        {
          "id": "heltec-t1",
          "status": "supported",
          "target": "heltec_t1",
          "platformio_board": "heltec_t1"
        },
        {
          "id": "heltec-t114",
          "status": "supported",
          "target": "heltec_t114",
          "platformio_board": "heltec_t114"
        },
        {
          "id": "heltec-t190",
          "status": "supported",
          "target": "heltec_t190",
          "platformio_board": "heltec_t190"
        },
        {
          "id": "heltec-wt3",
          "status": "supported",
          "target": "heltec_tracker",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "heltec-wt2",
          "status": "supported",
          "target": "heltec_tracker_v2",
          "platformio_board": "heltec_tracker_v2"
        },
        {
          "id": "heltec-v2",
          "status": "supported",
          "target": "heltec_v2",
          "platformio_board": "heltec_wifi_lora_32_V2"
        },
        {
          "id": "heltec-v3",
          "status": "supported",
          "target": "heltec_v3",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "heltec-wsl3",
          "status": "supported",
          "target": "heltec_v3",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "heltec-v4",
          "status": "supported",
          "target": "heltec_v4",
          "platformio_board": "heltec_v4"
        },
        {
          "id": "heltec-v4-exp",
          "status": "supported",
          "target": "heltec_v4",
          "platformio_board": "heltec_v4"
        },
        {
          "id": "heltec-paper",
          "status": "supported",
          "target": "heltec_wireless_paper",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "ikoka-handheld",
          "status": "supported",
          "target": "ikoka_handheld_nrf",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "ikoka-nano",
          "status": "supported",
          "target": "ikoka_nano_nrf",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "ikoka-stick",
          "status": "supported",
          "target": "ikoka_stick_nrf",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "keepteen-lt1",
          "status": "supported",
          "target": "keepteen_lt1",
          "platformio_board": "keepteen_lt1"
        },
        {
          "id": "lilygo-t3-s3-sx126x",
          "status": "supported",
          "target": "lilygo_t3s3",
          "platformio_board": "t3_s3_v1_x"
        },
        {
          "id": "lilygo-t3-s3-sx127x",
          "status": "supported",
          "target": "lilygo_t3s3_sx1276",
          "platformio_board": "t3_s3_v1_x"
        },
        {
          "id": "lilygo-t-impulse-plus",
          "status": "supported",
          "target": "lilygo_t_impulse_plus",
          "platformio_board": "lilygo_t_impulse_plus_nrf52840"
        },
        {
          "id": "lilygo-tbeam-1w",
          "status": "supported",
          "target": "lilygo_tbeam_1w",
          "platformio_board": "t_beam_1w"
        },
        {
          "id": "lilygo-t-beam-sx1262",
          "status": "supported",
          "target": "lilygo_tbeam_SX1262",
          "platformio_board": "ttgo-t-beam"
        },
        {
          "id": "lilygo-t-beam-1-2-sx1276",
          "status": "supported",
          "target": "lilygo_tbeam_SX1276",
          "platformio_board": "ttgo-t-beam"
        },
        {
          "id": "lilygo-tbeam-supreme",
          "status": "supported",
          "target": "lilygo_tbeam_supreme_SX1262",
          "platformio_board": "t_beams3_supreme"
        },
        {
          "id": "lilygo-t-deck-community",
          "status": "supported",
          "target": "lilygo_tdeck",
          "platformio_board": "t-deck"
        },
        {
          "id": "lilygo-t-deck",
          "status": "supported",
          "target": "lilygo_tdeck",
          "platformio_board": "t-deck"
        },
        {
          "id": "lilygo-techo",
          "status": "supported",
          "target": "lilygo_techo",
          "platformio_board": "t-echo"
        },
        {
          "id": "lilygo-techo-card",
          "status": "supported",
          "target": "lilygo_techo_card",
          "platformio_board": "t-echo"
        },
        {
          "id": "lilygo-techo-lite",
          "status": "supported",
          "target": "lilygo_techo_lite",
          "platformio_board": "t-echo"
        },
        {
          "id": "lilygo-teth-elite",
          "status": "supported",
          "target": "lilygo_teth_elite",
          "platformio_board": "esp32s3box"
        },
        {
          "id": "lilygo-tlora-c6",
          "status": "supported",
          "target": "lilygo_tlora_c6",
          "platformio_board": "esp32-c6-devkitm-1"
        },
        {
          "id": "lilygo-tlora-1-6",
          "status": "supported",
          "target": "lilygo_tlora_v2_1",
          "platformio_board": "ttgo-lora32-v1"
        },
        {
          "id": "m5stack-unit-c6l",
          "status": "supported",
          "target": "m5stack_unit_c6l",
          "platformio_board": "esp32-c6-devkitm-1"
        },
        {
          "id": "heltec-meshpocket",
          "status": "supported",
          "target": "mesh_pocket",
          "platformio_board": "heltec_mesh_pocket"
        },
        {
          "id": "meshadventurer",
          "status": "supported",
          "target": "meshadventurer",
          "platformio_board": "esp32doit-devkit-v1"
        },
        {
          "id": "meshtiny",
          "status": "supported",
          "target": "meshtiny",
          "platformio_board": "meshtiny"
        },
        {
          "id": "minewsemi-me25ls01",
          "status": "supported",
          "target": "minewsemi_me25ls01",
          "platformio_board": "minewsemi_me25ls01"
        },
        {
          "id": "muziworks-r1-neo",
          "status": "supported",
          "target": "muziworks_r1_neo",
          "platformio_board": "rak4631"
        },
        {
          "id": "nano-g2",
          "status": "supported",
          "target": "nano_g2_ultra",
          "platformio_board": "nano-g2-ultra"
        },
        {
          "id": "nibble-screen-connect",
          "status": "supported",
          "target": "nibble_screen_connect",
          "platformio_board": "esp32-s3-zero"
        },
        {
          "id": "faketec",
          "status": "supported",
          "target": "promicro",
          "platformio_board": "promicro_nrf52840"
        },
        {
          "id": "rak-11310",
          "status": "supported",
          "target": "rak11310",
          "platformio_board": "rakwireless_rak11300"
        },
        {
          "id": "rak-3112",
          "status": "supported",
          "target": "rak3112",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "rak-13302",
          "status": "supported",
          "target": "rak3401",
          "platformio_board": "rak3401"
        },
        {
          "id": "rak-3x72",
          "status": "supported",
          "target": "rak3x72",
          "platformio_board": "rak3172"
        },
        {
          "id": "rak-4631",
          "status": "supported",
          "target": "rak4631",
          "platformio_board": "rak4631"
        },
        {
          "id": "rak-wismesh-tag",
          "status": "supported",
          "target": "rak_wismesh_tag",
          "platformio_board": "rak4631"
        },
        {
          "id": "rpi-picow",
          "status": "supported",
          "target": "rpi_picow",
          "platformio_board": "rpipicow"
        },
        {
          "id": "sensecap-indicator-espnow",
          "status": "supported",
          "target": "sensecap_indicator-espnow",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "sensecap-solar-p1",
          "status": "supported",
          "target": "sensecap_solar",
          "platformio_board": "seeed_sensecap_solar"
        },
        {
          "id": "sensecap-solar-p1-pro",
          "status": "supported",
          "target": "sensecap_solar",
          "platformio_board": "seeed_sensecap_solar"
        },
        {
          "id": "station-g2",
          "status": "supported",
          "target": "station_g2",
          "platformio_board": "station-g2"
        },
        {
          "id": "station-g3",
          "status": "supported",
          "target": "station_g3_esp32",
          "platformio_board": "station-g3-esp32"
        },
        {
          "id": "sensecap-t1000e",
          "status": "supported",
          "target": "t1000-e",
          "platformio_board": "tracker-t1000-e"
        },
        {
          "id": "tenstar-c3",
          "status": "supported",
          "target": "tenstar_c3",
          "platformio_board": "esp32-c3-devkitm-1"
        },
        {
          "id": "thinknode-m1",
          "status": "supported",
          "target": "thinknode_m1",
          "platformio_board": "thinknode_m1"
        },
        {
          "id": "thinknode-m2",
          "status": "supported",
          "target": "thinknode_m2",
          "platformio_board": "ESP32-S3-WROOM-1-N4"
        },
        {
          "id": "thinknode-m3",
          "status": "supported",
          "target": "thinknode_m3",
          "platformio_board": "thinknode_m3"
        },
        {
          "id": "thinknode-m5",
          "status": "supported",
          "target": "thinknode_m5",
          "platformio_board": "ESP32-S3-WROOM-1-N4"
        },
        {
          "id": "thinknode-m6",
          "status": "supported",
          "target": "thinknode_m6",
          "platformio_board": "thinknode_m6"
        },
        {
          "id": "tiny-relay",
          "status": "supported",
          "target": "tiny_relay",
          "platformio_board": "tiny_relay"
        },
        {
          "id": "uart-solar-node-station",
          "status": "supported",
          "target": "rak4631",
          "platformio_board": "rak4631"
        },
        {
          "id": "waveshare-rp2040-lora",
          "status": "supported",
          "target": "waveshare_rp2040_lora",
          "platformio_board": "pico"
        },
        {
          "id": "wio-e5-dev",
          "status": "supported",
          "target": "wio-e5-dev",
          "platformio_board": "lora_e5_dev_board"
        },
        {
          "id": "wio-e5-mini",
          "status": "supported",
          "target": "wio-e5-mini",
          "platformio_board": "lora_e5_mini"
        },
        {
          "id": "wio-tracker-l1",
          "status": "supported",
          "target": "wio-tracker-l1",
          "platformio_board": "seeed-wio-tracker-l1"
        },
        {
          "id": "wio-tracker-l1-pro",
          "status": "supported",
          "target": "wio-tracker-l1",
          "platformio_board": "seeed-wio-tracker-l1"
        },
        {
          "id": "wio-tracker-l1-eink",
          "status": "supported",
          "target": "wio-tracker-l1-eink",
          "platformio_board": "seeed-wio-tracker-l1"
        },
        {
          "id": "wio-wm1110",
          "status": "supported",
          "target": "wio_wm1110",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "xiao-esp32c3",
          "status": "supported",
          "target": "xiao_c3",
          "platformio_board": "seeed_xiao_esp32c3"
        },
        {
          "id": "xiao-esp32c6",
          "status": "supported",
          "target": "xiao_c6",
          "platformio_board": "esp32-c6-devkitm-1"
        },
        {
          "id": "xiao-nrf52",
          "status": "supported",
          "target": "xiao_nrf52",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "xiao-rp2040",
          "status": "supported",
          "target": "xiao_rp2040",
          "platformio_board": "seeed_xiao_rp2040"
        },
        {
          "id": "xiao-esp32s3-plain",
          "status": "supported",
          "target": "xiao_s3",
          "platformio_board": "seeed_xiao_esp32s3"
        },
        {
          "id": "xiao-esp32s3",
          "status": "supported",
          "target": "xiao_s3_wio",
          "platformio_board": "seeed_xiao_esp32s3"
        },
        {
          "id": "lilygo-tdeck-pro",
          "status": "supported"
        },
        {
          "id": "lilygo-t5-pro",
          "status": "supported"
        },
        {
          "id": "lilygo-tdisplay",
          "status": "supported"
        },
        {
          "id": "lilygo-pager",
          "status": "supported"
        },
        {
          "id": "lilygo-twatch-plus",
          "status": "supported"
        },
        {
          "id": "lilygo-twatch-s3",
          "status": "supported"
        }
      ],
      "latest_version": "1.16.0",
      "released": "2026-06-06",
      "releases": [
        {
          "version": "room-server-v1.16.0",
          "name": "Room Server Firmware v1.16.0",
          "datetime": "2026-06-06T15:54:36Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/room-server-v1.16.0",
          "prerelease": false,
          "notes": "## Download\n\nLatest firmwares are in the [flasher.meshcore.io](https://flasher.meshcore.io/)\n\n## Change Log\n\n### New Features\n\n-   New CLI config var ‘flood.max.unscoped’ [#2661](https://github.com/meshcore-dev/MeshCore/pull/2661)\n-   New CLI config var ‘flood.max.advert’ [#2702](https://github.com/meshcore-dev/MeshCore/pull/2702)\n-   longer preamble now for lower SF. (32 for SF<=8, 16 for SF>8) [#1954](https://github.com/meshcore-dev/MeshCore/pull/1954)\n-   app/companion can now do anon\\_req/response with non-contact nodes [#2672](https://github.com/meshcore-dev/MeshCore/pull/2672)\n-   companion auto-shutdown, disabled when on external power, new UI warning on display [#2663](https://github.com/meshcore-dev/MeshCore/pull/2663)\n-   new ‘region def …’ CLI command [#2540](https://github.com/meshcore-dev/MeshCore/pull/2540)\n-   extended ACK support [#2594](https://github.com/meshcore-dev/MeshCore/pull/2594)\n-   app/companion can now compose and send raw packets [#2543](https://github.com/meshcore-dev/MeshCore/pull/2543)\n-   companion can now override default scope to explicit unscoped [#2492](https://github.com/meshcore-dev/MeshCore/pull/2492)\n\n### Enhancements\n\n-   All ESP repeaters, power saving improvements [#1687](https://github.com/meshcore-dev/MeshCore/pull/1687)\n-   nRF companions, power saving [#2286](https://github.com/meshcore-dev/MeshCore/pull/2286)\n\n### New device support\n\n-   NEW: LilyGo T-Echo Card support [#2517](https://github.com/meshcore-dev/MeshCore/pull/2517)\n-   NEW: LilyGo T-Impulse Plus support [#2522](https://github.com/meshcore-dev/MeshCore/pull/2522)\n-   NEW: Station G3 support [#2515](https://github.com/meshcore-dev/MeshCore/pull/2515)\n-   NEW: Heltec Mesh Node T1 support [#2520](https://github.com/meshcore-dev/MeshCore/pull/2520)\n-   new Xiao S3 variants (repeater, companion, etc) [#2383](https://github.com/meshcore-dev/MeshCore/pull/2383)\n\n### Bug fixes and Other\n\n-   RP2040 target build fixes. [#2684](https://github.com/meshcore-dev/MeshCore/pull/2684)\n-   companion protocol max frame size increase (now 176) [#2022](https://github.com/meshcore-dev/MeshCore/pull/2022)\n-   RAK Wismesh Tag fixes [#2664](https://github.com/meshcore-dev/MeshCore/pull/2664)\n-   Bug fix: repeater neighbor discovery fail when path.hash.mode != 0\n-   RAK4631, now using Bosch driver for BME680 sensor [#2634](https://github.com/meshcore-dev/MeshCore/pull/2634)\n-   enable radio.rxgain CLI command for LR1110 (T1000e) [#2235](https://github.com/meshcore-dev/MeshCore/pull/2235)\n-   default flood advert interval now 47 hours (was 12) [#2608](https://github.com/meshcore-dev/MeshCore/pull/2608)\n-   Client repeat (off-grid) EU freq change (from 869.0 to 869.495) [#2604](https://github.com/meshcore-dev/MeshCore/pull/2604)\n-   CLI validation on rxdelay, txdelay and direct.txdelay [#2443](https://github.com/meshcore-dev/MeshCore/pull/2443)\n-   Heltec T096, sensor node support [#2576](https://github.com/meshcore-dev/MeshCore/pull/2576)\n-   Heltec E290 USB companion fix [#2562](https://github.com/meshcore-dev/MeshCore/pull/2562)\n-   WiFi companion, reconnect logic redesigned for non-blocking [#2493](https://github.com/meshcore-dev/MeshCore/pull/2493)\n-   RAM usage reduced for older boards [#2497](https://github.com/meshcore-dev/MeshCore/pull/2497)\n-   nRF variants, CustomLFS lib upgrade to v2.2 [#2519](https://github.com/meshcore-dev/MeshCore/pull/2519)\n-   T-Echo Lite, fixes to RXEN, TXEN and TCXO [#2511](https://github.com/meshcore-dev/MeshCore/pull/2511)\n-   KISS modem frame timeout fixes [#2490](https://github.com/meshcore-dev/MeshCore/pull/2490)\n-   sensor manager redesign [#2327](https://github.com/meshcore-dev/MeshCore/pull/2327)\n-   startup tune suppressed if sound pref off [#2460](https://github.com/meshcore-dev/MeshCore/pull/2460)\n-   added KISS Modem variants for most boards [#2620](https://github.com/meshcore-dev/MeshCore/pull/2620) [#2432](https://github.com/meshcore-dev/MeshCore/pull/2432)\n-   Adafruit nRF BLE fork, to prevent lockup during rapid connect/disconnect [#2430](https://github.com/meshcore-dev/MeshCore/pull/2430)\n-   RAK3401 companion, analog button support [#2436](https://github.com/meshcore-dev/MeshCore/pull/2436)\n-   Heltec boards, LNA disabled by default [#2439](https://github.com/meshcore-dev/MeshCore/pull/2439)\n-   new splash screens [#2424](https://github.com/meshcore-dev/MeshCore/pull/2424)\n-   Sensecap Solar Tx LED fix [#2157](https://github.com/meshcore-dev/MeshCore/pull/2157)\n-   new repeater variant: Heltec V4 expansion kit [#2326](https://github.com/meshcore-dev/MeshCore/pull/2326)\n-   new T-Echo Lite non-shell companion variants [#2503](https://github.com/meshcore-dev/MeshCore/pull/2503) [#2353](https://github.com/meshcore-dev/MeshCore/pull/2353)\n-   T-Echo Lite, battery measure fix [#2287](https://github.com/meshcore-dev/MeshCore/pull/2287)\n-   RAK4631, sx1262 reset pin fix [#2008](https://github.com/meshcore-dev/MeshCore/pull/2008)\n-   Heltec T096, Wireless Tracker: FEM/LNA enable by default [#2340](https://github.com/meshcore-dev/MeshCore/pull/2340)\n-   R1 Neo, shutdown fix [#2371](https://github.com/meshcore-dev/MeshCore/pull/2371)\n-   Heltec V4, set adc.multiplier support [#2335](https://github.com/meshcore-dev/MeshCore/pull/2335)\n\n## Limiting Unscoped Traffic\n\nThe new `flood.max.unscoped` CLI config variable is specifically for limiting unscoped flood traffic. Like `flood.max`, it drops unscoped flood packets which have already had a given number of hops. By default it is 64, which is essentially _off_.\n\n## Limiting Advert Traffic\n\nThe new `flood.max.advert` CLI config variable is specifically for limiting adverts. Like `flood.max`, it drops advert packets which have already had a given number of hops. By default it is **8**.\n\n## New Preamble\n\nWhen using the lower Spreading Factors, the radio has less time to _lock onto_ an incoming packet, so this change gives the faster SF’s a longer preamble, and thus decreasing the chance of the preamble being missed. For SF <= 8, the preamble is now 32 symbols.\n\n## Improved Region Discovery in Mobile App\n\nThe new companion firmware, and latest app, will be able to do ad-hoc requests to near by repeaters _without_ having to add them to contacts first. This will streamline both repeater discovery, and region discovery.\n\n## New `region def` Command\n\nDefining regions via the CLI is currently quite verbose, and the latest CLI handling introduces a new `region def...` command which has a short-hand notation for defining regions, especially ones which have deep nesting.\n\nSee the [CLI Command Reference](https://docs.meshcore.io/cli_commands/) for more details.\n\n## Extended ACK Support\n\nThe latest firmwares introduce support for ‘extended ACKs’, which are 6 bytes instead of 4. The extra bytes contain an extended attempt number, and additional random byte. This is in preparation for a later app feature which will enable much more than 4 attempts for direct messages. For now, repeaters will have to be updated first.\n\n## Companion Raw Packets\n\nThe latest companion firmwares now enable apps to compose the _full_ packet, ie. headers, path and payload. This can correspond with the existing RxLog ability, so app can do its own raw send and receive of packets.",
          "notesUrl": "https://blog.meshcore.io/2026/06/06/release-1-16-0",
          "notesHtml": "<h2>Download</h2>\n<p>Latest firmwares are in the <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></p>\n<h2>Change Log</h2>\n<h3>New Features</h3>\n<ul>\n<li>New CLI config var ‘flood.max.unscoped’ <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2661\" target=\"_blank\" rel=\"noopener noreferrer\">#2661</a></li>\n<li>New CLI config var ‘flood.max.advert’ <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2702\" target=\"_blank\" rel=\"noopener noreferrer\">#2702</a></li>\n<li>longer preamble now for lower SF. (32 for SF&lt;=8, 16 for SF&gt;8) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1954\" target=\"_blank\" rel=\"noopener noreferrer\">#1954</a></li>\n<li>app/companion can now do anon_req/response with non-contact nodes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2672\" target=\"_blank\" rel=\"noopener noreferrer\">#2672</a></li>\n<li>companion auto-shutdown, disabled when on external power, new UI warning on display <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2663\" target=\"_blank\" rel=\"noopener noreferrer\">#2663</a></li>\n<li>new ‘region def …’ CLI command <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2540\" target=\"_blank\" rel=\"noopener noreferrer\">#2540</a></li>\n<li>extended ACK support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2594\" target=\"_blank\" rel=\"noopener noreferrer\">#2594</a></li>\n<li>app/companion can now compose and send raw packets <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2543\" target=\"_blank\" rel=\"noopener noreferrer\">#2543</a></li>\n<li>companion can now override default scope to explicit unscoped <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2492\" target=\"_blank\" rel=\"noopener noreferrer\">#2492</a></li>\n</ul>\n<h3>Enhancements</h3>\n<ul>\n<li>All ESP repeaters, power saving improvements <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1687\" target=\"_blank\" rel=\"noopener noreferrer\">#1687</a></li>\n<li>nRF companions, power saving <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2286\" target=\"_blank\" rel=\"noopener noreferrer\">#2286</a></li>\n</ul>\n<h3>New device support</h3>\n<ul>\n<li>NEW: LilyGo T-Echo Card support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2517\" target=\"_blank\" rel=\"noopener noreferrer\">#2517</a></li>\n<li>NEW: LilyGo T-Impulse Plus support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2522\" target=\"_blank\" rel=\"noopener noreferrer\">#2522</a></li>\n<li>NEW: Station G3 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2515\" target=\"_blank\" rel=\"noopener noreferrer\">#2515</a></li>\n<li>NEW: Heltec Mesh Node T1 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2520\" target=\"_blank\" rel=\"noopener noreferrer\">#2520</a></li>\n<li>new Xiao S3 variants (repeater, companion, etc) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2383\" target=\"_blank\" rel=\"noopener noreferrer\">#2383</a></li>\n</ul>\n<h3>Bug fixes and Other</h3>\n<ul>\n<li>RP2040 target build fixes. <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2684\" target=\"_blank\" rel=\"noopener noreferrer\">#2684</a></li>\n<li>companion protocol max frame size increase (now 176) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2022\" target=\"_blank\" rel=\"noopener noreferrer\">#2022</a></li>\n<li>RAK Wismesh Tag fixes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2664\" target=\"_blank\" rel=\"noopener noreferrer\">#2664</a></li>\n<li>Bug fix: repeater neighbor discovery fail when path.hash.mode != 0</li>\n<li>RAK4631, now using Bosch driver for BME680 sensor <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2634\" target=\"_blank\" rel=\"noopener noreferrer\">#2634</a></li>\n<li>enable radio.rxgain CLI command for LR1110 (T1000e) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2235\" target=\"_blank\" rel=\"noopener noreferrer\">#2235</a></li>\n<li>default flood advert interval now 47 hours (was 12) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2608\" target=\"_blank\" rel=\"noopener noreferrer\">#2608</a></li>\n<li>Client repeat (off-grid) EU freq change (from 869.0 to 869.495) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2604\" target=\"_blank\" rel=\"noopener noreferrer\">#2604</a></li>\n<li>CLI validation on rxdelay, txdelay and direct.txdelay <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2443\" target=\"_blank\" rel=\"noopener noreferrer\">#2443</a></li>\n<li>Heltec T096, sensor node support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2576\" target=\"_blank\" rel=\"noopener noreferrer\">#2576</a></li>\n<li>Heltec E290 USB companion fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2562\" target=\"_blank\" rel=\"noopener noreferrer\">#2562</a></li>\n<li>WiFi companion, reconnect logic redesigned for non-blocking <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2493\" target=\"_blank\" rel=\"noopener noreferrer\">#2493</a></li>\n<li>RAM usage reduced for older boards <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2497\" target=\"_blank\" rel=\"noopener noreferrer\">#2497</a></li>\n<li>nRF variants, CustomLFS lib upgrade to v2.2 <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2519\" target=\"_blank\" rel=\"noopener noreferrer\">#2519</a></li>\n<li>T-Echo Lite, fixes to RXEN, TXEN and TCXO <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2511\" target=\"_blank\" rel=\"noopener noreferrer\">#2511</a></li>\n<li>KISS modem frame timeout fixes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2490\" target=\"_blank\" rel=\"noopener noreferrer\">#2490</a></li>\n<li>sensor manager redesign <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2327\" target=\"_blank\" rel=\"noopener noreferrer\">#2327</a></li>\n<li>startup tune suppressed if sound pref off <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2460\" target=\"_blank\" rel=\"noopener noreferrer\">#2460</a></li>\n<li>added KISS Modem variants for most boards <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2620\" target=\"_blank\" rel=\"noopener noreferrer\">#2620</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2432\" target=\"_blank\" rel=\"noopener noreferrer\">#2432</a></li>\n<li>Adafruit nRF BLE fork, to prevent lockup during rapid connect/disconnect <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2430\" target=\"_blank\" rel=\"noopener noreferrer\">#2430</a></li>\n<li>RAK3401 companion, analog button support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2436\" target=\"_blank\" rel=\"noopener noreferrer\">#2436</a></li>\n<li>Heltec boards, LNA disabled by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2439\" target=\"_blank\" rel=\"noopener noreferrer\">#2439</a></li>\n<li>new splash screens <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2424\" target=\"_blank\" rel=\"noopener noreferrer\">#2424</a></li>\n<li>Sensecap Solar Tx LED fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2157\" target=\"_blank\" rel=\"noopener noreferrer\">#2157</a></li>\n<li>new repeater variant: Heltec V4 expansion kit <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2326\" target=\"_blank\" rel=\"noopener noreferrer\">#2326</a></li>\n<li>new T-Echo Lite non-shell companion variants <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2503\" target=\"_blank\" rel=\"noopener noreferrer\">#2503</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2353\" target=\"_blank\" rel=\"noopener noreferrer\">#2353</a></li>\n<li>T-Echo Lite, battery measure fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2287\" target=\"_blank\" rel=\"noopener noreferrer\">#2287</a></li>\n<li>RAK4631, sx1262 reset pin fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2008\" target=\"_blank\" rel=\"noopener noreferrer\">#2008</a></li>\n<li>Heltec T096, Wireless Tracker: FEM/LNA enable by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2340\" target=\"_blank\" rel=\"noopener noreferrer\">#2340</a></li>\n<li>R1 Neo, shutdown fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2371\" target=\"_blank\" rel=\"noopener noreferrer\">#2371</a></li>\n<li>Heltec V4, set adc.multiplier support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2335\" target=\"_blank\" rel=\"noopener noreferrer\">#2335</a></li>\n</ul>\n<h2>Limiting Unscoped Traffic</h2>\n<p>The new <code>flood.max.unscoped</code> CLI config variable is specifically for limiting unscoped flood traffic. Like <code>flood.max</code>, it drops unscoped flood packets which have already had a given number of hops. By default it is 64, which is essentially <em>off</em>.</p>\n<h2>Limiting Advert Traffic</h2>\n<p>The new <code>flood.max.advert</code> CLI config variable is specifically for limiting adverts. Like <code>flood.max</code>, it drops advert packets which have already had a given number of hops. By default it is <strong>8</strong>.</p>\n<h2>New Preamble</h2>\n<p>When using the lower Spreading Factors, the radio has less time to <em>lock onto</em> an incoming packet, so this change gives the faster SF’s a longer preamble, and thus decreasing the chance of the preamble being missed. For SF &lt;= 8, the preamble is now 32 symbols.</p>\n<h2>Improved Region Discovery in Mobile App</h2>\n<p>The new companion firmware, and latest app, will be able to do ad-hoc requests to near by repeaters <em>without</em> having to add them to contacts first. This will streamline both repeater discovery, and region discovery.</p>\n<h2>New <code>region def</code> Command</h2>\n<p>Defining regions via the CLI is currently quite verbose, and the latest CLI handling introduces a new <code>region def...</code> command which has a short-hand notation for defining regions, especially ones which have deep nesting.</p>\n<p>See the <a href=\"https://docs.meshcore.io/cli_commands/\" target=\"_blank\" rel=\"noopener noreferrer\">CLI Command Reference</a> for more details.</p>\n<h2>Extended ACK Support</h2>\n<p>The latest firmwares introduce support for ‘extended ACKs’, which are 6 bytes instead of 4. The extra bytes contain an extended attempt number, and additional random byte. This is in preparation for a later app feature which will enable much more than 4 attempts for direct messages. For now, repeaters will have to be updated first.</p>\n<h2>Companion Raw Packets</h2>\n<p>The latest companion firmwares now enable apps to compose the <em>full</em> packet, ie. headers, path and payload. This can correspond with the existing RxLog ability, so app can do its own raw send and receive of packets.</p>\n"
        },
        {
          "version": "repeater-v1.16.0",
          "name": "Repeater Firmware v1.16.0",
          "datetime": "2026-06-06T15:54:59Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/repeater-v1.16.0",
          "prerelease": false,
          "notes": "## Download\n\nLatest firmwares are in the [flasher.meshcore.io](https://flasher.meshcore.io/)\n\n## Change Log\n\n### New Features\n\n-   New CLI config var ‘flood.max.unscoped’ [#2661](https://github.com/meshcore-dev/MeshCore/pull/2661)\n-   New CLI config var ‘flood.max.advert’ [#2702](https://github.com/meshcore-dev/MeshCore/pull/2702)\n-   longer preamble now for lower SF. (32 for SF<=8, 16 for SF>8) [#1954](https://github.com/meshcore-dev/MeshCore/pull/1954)\n-   app/companion can now do anon\\_req/response with non-contact nodes [#2672](https://github.com/meshcore-dev/MeshCore/pull/2672)\n-   companion auto-shutdown, disabled when on external power, new UI warning on display [#2663](https://github.com/meshcore-dev/MeshCore/pull/2663)\n-   new ‘region def …’ CLI command [#2540](https://github.com/meshcore-dev/MeshCore/pull/2540)\n-   extended ACK support [#2594](https://github.com/meshcore-dev/MeshCore/pull/2594)\n-   app/companion can now compose and send raw packets [#2543](https://github.com/meshcore-dev/MeshCore/pull/2543)\n-   companion can now override default scope to explicit unscoped [#2492](https://github.com/meshcore-dev/MeshCore/pull/2492)\n\n### Enhancements\n\n-   All ESP repeaters, power saving improvements [#1687](https://github.com/meshcore-dev/MeshCore/pull/1687)\n-   nRF companions, power saving [#2286](https://github.com/meshcore-dev/MeshCore/pull/2286)\n\n### New device support\n\n-   NEW: LilyGo T-Echo Card support [#2517](https://github.com/meshcore-dev/MeshCore/pull/2517)\n-   NEW: LilyGo T-Impulse Plus support [#2522](https://github.com/meshcore-dev/MeshCore/pull/2522)\n-   NEW: Station G3 support [#2515](https://github.com/meshcore-dev/MeshCore/pull/2515)\n-   NEW: Heltec Mesh Node T1 support [#2520](https://github.com/meshcore-dev/MeshCore/pull/2520)\n-   new Xiao S3 variants (repeater, companion, etc) [#2383](https://github.com/meshcore-dev/MeshCore/pull/2383)\n\n### Bug fixes and Other\n\n-   RP2040 target build fixes. [#2684](https://github.com/meshcore-dev/MeshCore/pull/2684)\n-   companion protocol max frame size increase (now 176) [#2022](https://github.com/meshcore-dev/MeshCore/pull/2022)\n-   RAK Wismesh Tag fixes [#2664](https://github.com/meshcore-dev/MeshCore/pull/2664)\n-   Bug fix: repeater neighbor discovery fail when path.hash.mode != 0\n-   RAK4631, now using Bosch driver for BME680 sensor [#2634](https://github.com/meshcore-dev/MeshCore/pull/2634)\n-   enable radio.rxgain CLI command for LR1110 (T1000e) [#2235](https://github.com/meshcore-dev/MeshCore/pull/2235)\n-   default flood advert interval now 47 hours (was 12) [#2608](https://github.com/meshcore-dev/MeshCore/pull/2608)\n-   Client repeat (off-grid) EU freq change (from 869.0 to 869.495) [#2604](https://github.com/meshcore-dev/MeshCore/pull/2604)\n-   CLI validation on rxdelay, txdelay and direct.txdelay [#2443](https://github.com/meshcore-dev/MeshCore/pull/2443)\n-   Heltec T096, sensor node support [#2576](https://github.com/meshcore-dev/MeshCore/pull/2576)\n-   Heltec E290 USB companion fix [#2562](https://github.com/meshcore-dev/MeshCore/pull/2562)\n-   WiFi companion, reconnect logic redesigned for non-blocking [#2493](https://github.com/meshcore-dev/MeshCore/pull/2493)\n-   RAM usage reduced for older boards [#2497](https://github.com/meshcore-dev/MeshCore/pull/2497)\n-   nRF variants, CustomLFS lib upgrade to v2.2 [#2519](https://github.com/meshcore-dev/MeshCore/pull/2519)\n-   T-Echo Lite, fixes to RXEN, TXEN and TCXO [#2511](https://github.com/meshcore-dev/MeshCore/pull/2511)\n-   KISS modem frame timeout fixes [#2490](https://github.com/meshcore-dev/MeshCore/pull/2490)\n-   sensor manager redesign [#2327](https://github.com/meshcore-dev/MeshCore/pull/2327)\n-   startup tune suppressed if sound pref off [#2460](https://github.com/meshcore-dev/MeshCore/pull/2460)\n-   added KISS Modem variants for most boards [#2620](https://github.com/meshcore-dev/MeshCore/pull/2620) [#2432](https://github.com/meshcore-dev/MeshCore/pull/2432)\n-   Adafruit nRF BLE fork, to prevent lockup during rapid connect/disconnect [#2430](https://github.com/meshcore-dev/MeshCore/pull/2430)\n-   RAK3401 companion, analog button support [#2436](https://github.com/meshcore-dev/MeshCore/pull/2436)\n-   Heltec boards, LNA disabled by default [#2439](https://github.com/meshcore-dev/MeshCore/pull/2439)\n-   new splash screens [#2424](https://github.com/meshcore-dev/MeshCore/pull/2424)\n-   Sensecap Solar Tx LED fix [#2157](https://github.com/meshcore-dev/MeshCore/pull/2157)\n-   new repeater variant: Heltec V4 expansion kit [#2326](https://github.com/meshcore-dev/MeshCore/pull/2326)\n-   new T-Echo Lite non-shell companion variants [#2503](https://github.com/meshcore-dev/MeshCore/pull/2503) [#2353](https://github.com/meshcore-dev/MeshCore/pull/2353)\n-   T-Echo Lite, battery measure fix [#2287](https://github.com/meshcore-dev/MeshCore/pull/2287)\n-   RAK4631, sx1262 reset pin fix [#2008](https://github.com/meshcore-dev/MeshCore/pull/2008)\n-   Heltec T096, Wireless Tracker: FEM/LNA enable by default [#2340](https://github.com/meshcore-dev/MeshCore/pull/2340)\n-   R1 Neo, shutdown fix [#2371](https://github.com/meshcore-dev/MeshCore/pull/2371)\n-   Heltec V4, set adc.multiplier support [#2335](https://github.com/meshcore-dev/MeshCore/pull/2335)\n\n## Limiting Unscoped Traffic\n\nThe new `flood.max.unscoped` CLI config variable is specifically for limiting unscoped flood traffic. Like `flood.max`, it drops unscoped flood packets which have already had a given number of hops. By default it is 64, which is essentially _off_.\n\n## Limiting Advert Traffic\n\nThe new `flood.max.advert` CLI config variable is specifically for limiting adverts. Like `flood.max`, it drops advert packets which have already had a given number of hops. By default it is **8**.\n\n## New Preamble\n\nWhen using the lower Spreading Factors, the radio has less time to _lock onto_ an incoming packet, so this change gives the faster SF’s a longer preamble, and thus decreasing the chance of the preamble being missed. For SF <= 8, the preamble is now 32 symbols.\n\n## Improved Region Discovery in Mobile App\n\nThe new companion firmware, and latest app, will be able to do ad-hoc requests to near by repeaters _without_ having to add them to contacts first. This will streamline both repeater discovery, and region discovery.\n\n## New `region def` Command\n\nDefining regions via the CLI is currently quite verbose, and the latest CLI handling introduces a new `region def...` command which has a short-hand notation for defining regions, especially ones which have deep nesting.\n\nSee the [CLI Command Reference](https://docs.meshcore.io/cli_commands/) for more details.\n\n## Extended ACK Support\n\nThe latest firmwares introduce support for ‘extended ACKs’, which are 6 bytes instead of 4. The extra bytes contain an extended attempt number, and additional random byte. This is in preparation for a later app feature which will enable much more than 4 attempts for direct messages. For now, repeaters will have to be updated first.\n\n## Companion Raw Packets\n\nThe latest companion firmwares now enable apps to compose the _full_ packet, ie. headers, path and payload. This can correspond with the existing RxLog ability, so app can do its own raw send and receive of packets.",
          "notesUrl": "https://blog.meshcore.io/2026/06/06/release-1-16-0",
          "notesHtml": "<h2>Download</h2>\n<p>Latest firmwares are in the <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></p>\n<h2>Change Log</h2>\n<h3>New Features</h3>\n<ul>\n<li>New CLI config var ‘flood.max.unscoped’ <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2661\" target=\"_blank\" rel=\"noopener noreferrer\">#2661</a></li>\n<li>New CLI config var ‘flood.max.advert’ <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2702\" target=\"_blank\" rel=\"noopener noreferrer\">#2702</a></li>\n<li>longer preamble now for lower SF. (32 for SF&lt;=8, 16 for SF&gt;8) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1954\" target=\"_blank\" rel=\"noopener noreferrer\">#1954</a></li>\n<li>app/companion can now do anon_req/response with non-contact nodes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2672\" target=\"_blank\" rel=\"noopener noreferrer\">#2672</a></li>\n<li>companion auto-shutdown, disabled when on external power, new UI warning on display <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2663\" target=\"_blank\" rel=\"noopener noreferrer\">#2663</a></li>\n<li>new ‘region def …’ CLI command <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2540\" target=\"_blank\" rel=\"noopener noreferrer\">#2540</a></li>\n<li>extended ACK support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2594\" target=\"_blank\" rel=\"noopener noreferrer\">#2594</a></li>\n<li>app/companion can now compose and send raw packets <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2543\" target=\"_blank\" rel=\"noopener noreferrer\">#2543</a></li>\n<li>companion can now override default scope to explicit unscoped <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2492\" target=\"_blank\" rel=\"noopener noreferrer\">#2492</a></li>\n</ul>\n<h3>Enhancements</h3>\n<ul>\n<li>All ESP repeaters, power saving improvements <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1687\" target=\"_blank\" rel=\"noopener noreferrer\">#1687</a></li>\n<li>nRF companions, power saving <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2286\" target=\"_blank\" rel=\"noopener noreferrer\">#2286</a></li>\n</ul>\n<h3>New device support</h3>\n<ul>\n<li>NEW: LilyGo T-Echo Card support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2517\" target=\"_blank\" rel=\"noopener noreferrer\">#2517</a></li>\n<li>NEW: LilyGo T-Impulse Plus support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2522\" target=\"_blank\" rel=\"noopener noreferrer\">#2522</a></li>\n<li>NEW: Station G3 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2515\" target=\"_blank\" rel=\"noopener noreferrer\">#2515</a></li>\n<li>NEW: Heltec Mesh Node T1 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2520\" target=\"_blank\" rel=\"noopener noreferrer\">#2520</a></li>\n<li>new Xiao S3 variants (repeater, companion, etc) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2383\" target=\"_blank\" rel=\"noopener noreferrer\">#2383</a></li>\n</ul>\n<h3>Bug fixes and Other</h3>\n<ul>\n<li>RP2040 target build fixes. <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2684\" target=\"_blank\" rel=\"noopener noreferrer\">#2684</a></li>\n<li>companion protocol max frame size increase (now 176) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2022\" target=\"_blank\" rel=\"noopener noreferrer\">#2022</a></li>\n<li>RAK Wismesh Tag fixes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2664\" target=\"_blank\" rel=\"noopener noreferrer\">#2664</a></li>\n<li>Bug fix: repeater neighbor discovery fail when path.hash.mode != 0</li>\n<li>RAK4631, now using Bosch driver for BME680 sensor <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2634\" target=\"_blank\" rel=\"noopener noreferrer\">#2634</a></li>\n<li>enable radio.rxgain CLI command for LR1110 (T1000e) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2235\" target=\"_blank\" rel=\"noopener noreferrer\">#2235</a></li>\n<li>default flood advert interval now 47 hours (was 12) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2608\" target=\"_blank\" rel=\"noopener noreferrer\">#2608</a></li>\n<li>Client repeat (off-grid) EU freq change (from 869.0 to 869.495) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2604\" target=\"_blank\" rel=\"noopener noreferrer\">#2604</a></li>\n<li>CLI validation on rxdelay, txdelay and direct.txdelay <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2443\" target=\"_blank\" rel=\"noopener noreferrer\">#2443</a></li>\n<li>Heltec T096, sensor node support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2576\" target=\"_blank\" rel=\"noopener noreferrer\">#2576</a></li>\n<li>Heltec E290 USB companion fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2562\" target=\"_blank\" rel=\"noopener noreferrer\">#2562</a></li>\n<li>WiFi companion, reconnect logic redesigned for non-blocking <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2493\" target=\"_blank\" rel=\"noopener noreferrer\">#2493</a></li>\n<li>RAM usage reduced for older boards <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2497\" target=\"_blank\" rel=\"noopener noreferrer\">#2497</a></li>\n<li>nRF variants, CustomLFS lib upgrade to v2.2 <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2519\" target=\"_blank\" rel=\"noopener noreferrer\">#2519</a></li>\n<li>T-Echo Lite, fixes to RXEN, TXEN and TCXO <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2511\" target=\"_blank\" rel=\"noopener noreferrer\">#2511</a></li>\n<li>KISS modem frame timeout fixes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2490\" target=\"_blank\" rel=\"noopener noreferrer\">#2490</a></li>\n<li>sensor manager redesign <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2327\" target=\"_blank\" rel=\"noopener noreferrer\">#2327</a></li>\n<li>startup tune suppressed if sound pref off <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2460\" target=\"_blank\" rel=\"noopener noreferrer\">#2460</a></li>\n<li>added KISS Modem variants for most boards <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2620\" target=\"_blank\" rel=\"noopener noreferrer\">#2620</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2432\" target=\"_blank\" rel=\"noopener noreferrer\">#2432</a></li>\n<li>Adafruit nRF BLE fork, to prevent lockup during rapid connect/disconnect <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2430\" target=\"_blank\" rel=\"noopener noreferrer\">#2430</a></li>\n<li>RAK3401 companion, analog button support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2436\" target=\"_blank\" rel=\"noopener noreferrer\">#2436</a></li>\n<li>Heltec boards, LNA disabled by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2439\" target=\"_blank\" rel=\"noopener noreferrer\">#2439</a></li>\n<li>new splash screens <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2424\" target=\"_blank\" rel=\"noopener noreferrer\">#2424</a></li>\n<li>Sensecap Solar Tx LED fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2157\" target=\"_blank\" rel=\"noopener noreferrer\">#2157</a></li>\n<li>new repeater variant: Heltec V4 expansion kit <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2326\" target=\"_blank\" rel=\"noopener noreferrer\">#2326</a></li>\n<li>new T-Echo Lite non-shell companion variants <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2503\" target=\"_blank\" rel=\"noopener noreferrer\">#2503</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2353\" target=\"_blank\" rel=\"noopener noreferrer\">#2353</a></li>\n<li>T-Echo Lite, battery measure fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2287\" target=\"_blank\" rel=\"noopener noreferrer\">#2287</a></li>\n<li>RAK4631, sx1262 reset pin fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2008\" target=\"_blank\" rel=\"noopener noreferrer\">#2008</a></li>\n<li>Heltec T096, Wireless Tracker: FEM/LNA enable by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2340\" target=\"_blank\" rel=\"noopener noreferrer\">#2340</a></li>\n<li>R1 Neo, shutdown fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2371\" target=\"_blank\" rel=\"noopener noreferrer\">#2371</a></li>\n<li>Heltec V4, set adc.multiplier support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2335\" target=\"_blank\" rel=\"noopener noreferrer\">#2335</a></li>\n</ul>\n<h2>Limiting Unscoped Traffic</h2>\n<p>The new <code>flood.max.unscoped</code> CLI config variable is specifically for limiting unscoped flood traffic. Like <code>flood.max</code>, it drops unscoped flood packets which have already had a given number of hops. By default it is 64, which is essentially <em>off</em>.</p>\n<h2>Limiting Advert Traffic</h2>\n<p>The new <code>flood.max.advert</code> CLI config variable is specifically for limiting adverts. Like <code>flood.max</code>, it drops advert packets which have already had a given number of hops. By default it is <strong>8</strong>.</p>\n<h2>New Preamble</h2>\n<p>When using the lower Spreading Factors, the radio has less time to <em>lock onto</em> an incoming packet, so this change gives the faster SF’s a longer preamble, and thus decreasing the chance of the preamble being missed. For SF &lt;= 8, the preamble is now 32 symbols.</p>\n<h2>Improved Region Discovery in Mobile App</h2>\n<p>The new companion firmware, and latest app, will be able to do ad-hoc requests to near by repeaters <em>without</em> having to add them to contacts first. This will streamline both repeater discovery, and region discovery.</p>\n<h2>New <code>region def</code> Command</h2>\n<p>Defining regions via the CLI is currently quite verbose, and the latest CLI handling introduces a new <code>region def...</code> command which has a short-hand notation for defining regions, especially ones which have deep nesting.</p>\n<p>See the <a href=\"https://docs.meshcore.io/cli_commands/\" target=\"_blank\" rel=\"noopener noreferrer\">CLI Command Reference</a> for more details.</p>\n<h2>Extended ACK Support</h2>\n<p>The latest firmwares introduce support for ‘extended ACKs’, which are 6 bytes instead of 4. The extra bytes contain an extended attempt number, and additional random byte. This is in preparation for a later app feature which will enable much more than 4 attempts for direct messages. For now, repeaters will have to be updated first.</p>\n<h2>Companion Raw Packets</h2>\n<p>The latest companion firmwares now enable apps to compose the <em>full</em> packet, ie. headers, path and payload. This can correspond with the existing RxLog ability, so app can do its own raw send and receive of packets.</p>\n"
        },
        {
          "version": "companion-v1.16.0",
          "name": "Companion Firmware v1.16.0",
          "datetime": "2026-06-06T15:55:20Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.16.0",
          "prerelease": false,
          "notes": "## Download\n\nLatest firmwares are in the [flasher.meshcore.io](https://flasher.meshcore.io/)\n\n## Change Log\n\n### New Features\n\n-   New CLI config var ‘flood.max.unscoped’ [#2661](https://github.com/meshcore-dev/MeshCore/pull/2661)\n-   New CLI config var ‘flood.max.advert’ [#2702](https://github.com/meshcore-dev/MeshCore/pull/2702)\n-   longer preamble now for lower SF. (32 for SF<=8, 16 for SF>8) [#1954](https://github.com/meshcore-dev/MeshCore/pull/1954)\n-   app/companion can now do anon\\_req/response with non-contact nodes [#2672](https://github.com/meshcore-dev/MeshCore/pull/2672)\n-   companion auto-shutdown, disabled when on external power, new UI warning on display [#2663](https://github.com/meshcore-dev/MeshCore/pull/2663)\n-   new ‘region def …’ CLI command [#2540](https://github.com/meshcore-dev/MeshCore/pull/2540)\n-   extended ACK support [#2594](https://github.com/meshcore-dev/MeshCore/pull/2594)\n-   app/companion can now compose and send raw packets [#2543](https://github.com/meshcore-dev/MeshCore/pull/2543)\n-   companion can now override default scope to explicit unscoped [#2492](https://github.com/meshcore-dev/MeshCore/pull/2492)\n\n### Enhancements\n\n-   All ESP repeaters, power saving improvements [#1687](https://github.com/meshcore-dev/MeshCore/pull/1687)\n-   nRF companions, power saving [#2286](https://github.com/meshcore-dev/MeshCore/pull/2286)\n\n### New device support\n\n-   NEW: LilyGo T-Echo Card support [#2517](https://github.com/meshcore-dev/MeshCore/pull/2517)\n-   NEW: LilyGo T-Impulse Plus support [#2522](https://github.com/meshcore-dev/MeshCore/pull/2522)\n-   NEW: Station G3 support [#2515](https://github.com/meshcore-dev/MeshCore/pull/2515)\n-   NEW: Heltec Mesh Node T1 support [#2520](https://github.com/meshcore-dev/MeshCore/pull/2520)\n-   new Xiao S3 variants (repeater, companion, etc) [#2383](https://github.com/meshcore-dev/MeshCore/pull/2383)\n\n### Bug fixes and Other\n\n-   RP2040 target build fixes. [#2684](https://github.com/meshcore-dev/MeshCore/pull/2684)\n-   companion protocol max frame size increase (now 176) [#2022](https://github.com/meshcore-dev/MeshCore/pull/2022)\n-   RAK Wismesh Tag fixes [#2664](https://github.com/meshcore-dev/MeshCore/pull/2664)\n-   Bug fix: repeater neighbor discovery fail when path.hash.mode != 0\n-   RAK4631, now using Bosch driver for BME680 sensor [#2634](https://github.com/meshcore-dev/MeshCore/pull/2634)\n-   enable radio.rxgain CLI command for LR1110 (T1000e) [#2235](https://github.com/meshcore-dev/MeshCore/pull/2235)\n-   default flood advert interval now 47 hours (was 12) [#2608](https://github.com/meshcore-dev/MeshCore/pull/2608)\n-   Client repeat (off-grid) EU freq change (from 869.0 to 869.495) [#2604](https://github.com/meshcore-dev/MeshCore/pull/2604)\n-   CLI validation on rxdelay, txdelay and direct.txdelay [#2443](https://github.com/meshcore-dev/MeshCore/pull/2443)\n-   Heltec T096, sensor node support [#2576](https://github.com/meshcore-dev/MeshCore/pull/2576)\n-   Heltec E290 USB companion fix [#2562](https://github.com/meshcore-dev/MeshCore/pull/2562)\n-   WiFi companion, reconnect logic redesigned for non-blocking [#2493](https://github.com/meshcore-dev/MeshCore/pull/2493)\n-   RAM usage reduced for older boards [#2497](https://github.com/meshcore-dev/MeshCore/pull/2497)\n-   nRF variants, CustomLFS lib upgrade to v2.2 [#2519](https://github.com/meshcore-dev/MeshCore/pull/2519)\n-   T-Echo Lite, fixes to RXEN, TXEN and TCXO [#2511](https://github.com/meshcore-dev/MeshCore/pull/2511)\n-   KISS modem frame timeout fixes [#2490](https://github.com/meshcore-dev/MeshCore/pull/2490)\n-   sensor manager redesign [#2327](https://github.com/meshcore-dev/MeshCore/pull/2327)\n-   startup tune suppressed if sound pref off [#2460](https://github.com/meshcore-dev/MeshCore/pull/2460)\n-   added KISS Modem variants for most boards [#2620](https://github.com/meshcore-dev/MeshCore/pull/2620) [#2432](https://github.com/meshcore-dev/MeshCore/pull/2432)\n-   Adafruit nRF BLE fork, to prevent lockup during rapid connect/disconnect [#2430](https://github.com/meshcore-dev/MeshCore/pull/2430)\n-   RAK3401 companion, analog button support [#2436](https://github.com/meshcore-dev/MeshCore/pull/2436)\n-   Heltec boards, LNA disabled by default [#2439](https://github.com/meshcore-dev/MeshCore/pull/2439)\n-   new splash screens [#2424](https://github.com/meshcore-dev/MeshCore/pull/2424)\n-   Sensecap Solar Tx LED fix [#2157](https://github.com/meshcore-dev/MeshCore/pull/2157)\n-   new repeater variant: Heltec V4 expansion kit [#2326](https://github.com/meshcore-dev/MeshCore/pull/2326)\n-   new T-Echo Lite non-shell companion variants [#2503](https://github.com/meshcore-dev/MeshCore/pull/2503) [#2353](https://github.com/meshcore-dev/MeshCore/pull/2353)\n-   T-Echo Lite, battery measure fix [#2287](https://github.com/meshcore-dev/MeshCore/pull/2287)\n-   RAK4631, sx1262 reset pin fix [#2008](https://github.com/meshcore-dev/MeshCore/pull/2008)\n-   Heltec T096, Wireless Tracker: FEM/LNA enable by default [#2340](https://github.com/meshcore-dev/MeshCore/pull/2340)\n-   R1 Neo, shutdown fix [#2371](https://github.com/meshcore-dev/MeshCore/pull/2371)\n-   Heltec V4, set adc.multiplier support [#2335](https://github.com/meshcore-dev/MeshCore/pull/2335)\n\n## Limiting Unscoped Traffic\n\nThe new `flood.max.unscoped` CLI config variable is specifically for limiting unscoped flood traffic. Like `flood.max`, it drops unscoped flood packets which have already had a given number of hops. By default it is 64, which is essentially _off_.\n\n## Limiting Advert Traffic\n\nThe new `flood.max.advert` CLI config variable is specifically for limiting adverts. Like `flood.max`, it drops advert packets which have already had a given number of hops. By default it is **8**.\n\n## New Preamble\n\nWhen using the lower Spreading Factors, the radio has less time to _lock onto_ an incoming packet, so this change gives the faster SF’s a longer preamble, and thus decreasing the chance of the preamble being missed. For SF <= 8, the preamble is now 32 symbols.\n\n## Improved Region Discovery in Mobile App\n\nThe new companion firmware, and latest app, will be able to do ad-hoc requests to near by repeaters _without_ having to add them to contacts first. This will streamline both repeater discovery, and region discovery.\n\n## New `region def` Command\n\nDefining regions via the CLI is currently quite verbose, and the latest CLI handling introduces a new `region def...` command which has a short-hand notation for defining regions, especially ones which have deep nesting.\n\nSee the [CLI Command Reference](https://docs.meshcore.io/cli_commands/) for more details.\n\n## Extended ACK Support\n\nThe latest firmwares introduce support for ‘extended ACKs’, which are 6 bytes instead of 4. The extra bytes contain an extended attempt number, and additional random byte. This is in preparation for a later app feature which will enable much more than 4 attempts for direct messages. For now, repeaters will have to be updated first.\n\n## Companion Raw Packets\n\nThe latest companion firmwares now enable apps to compose the _full_ packet, ie. headers, path and payload. This can correspond with the existing RxLog ability, so app can do its own raw send and receive of packets.",
          "notesUrl": "https://blog.meshcore.io/2026/06/06/release-1-16-0",
          "notesHtml": "<h2>Download</h2>\n<p>Latest firmwares are in the <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></p>\n<h2>Change Log</h2>\n<h3>New Features</h3>\n<ul>\n<li>New CLI config var ‘flood.max.unscoped’ <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2661\" target=\"_blank\" rel=\"noopener noreferrer\">#2661</a></li>\n<li>New CLI config var ‘flood.max.advert’ <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2702\" target=\"_blank\" rel=\"noopener noreferrer\">#2702</a></li>\n<li>longer preamble now for lower SF. (32 for SF&lt;=8, 16 for SF&gt;8) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1954\" target=\"_blank\" rel=\"noopener noreferrer\">#1954</a></li>\n<li>app/companion can now do anon_req/response with non-contact nodes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2672\" target=\"_blank\" rel=\"noopener noreferrer\">#2672</a></li>\n<li>companion auto-shutdown, disabled when on external power, new UI warning on display <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2663\" target=\"_blank\" rel=\"noopener noreferrer\">#2663</a></li>\n<li>new ‘region def …’ CLI command <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2540\" target=\"_blank\" rel=\"noopener noreferrer\">#2540</a></li>\n<li>extended ACK support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2594\" target=\"_blank\" rel=\"noopener noreferrer\">#2594</a></li>\n<li>app/companion can now compose and send raw packets <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2543\" target=\"_blank\" rel=\"noopener noreferrer\">#2543</a></li>\n<li>companion can now override default scope to explicit unscoped <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2492\" target=\"_blank\" rel=\"noopener noreferrer\">#2492</a></li>\n</ul>\n<h3>Enhancements</h3>\n<ul>\n<li>All ESP repeaters, power saving improvements <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1687\" target=\"_blank\" rel=\"noopener noreferrer\">#1687</a></li>\n<li>nRF companions, power saving <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2286\" target=\"_blank\" rel=\"noopener noreferrer\">#2286</a></li>\n</ul>\n<h3>New device support</h3>\n<ul>\n<li>NEW: LilyGo T-Echo Card support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2517\" target=\"_blank\" rel=\"noopener noreferrer\">#2517</a></li>\n<li>NEW: LilyGo T-Impulse Plus support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2522\" target=\"_blank\" rel=\"noopener noreferrer\">#2522</a></li>\n<li>NEW: Station G3 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2515\" target=\"_blank\" rel=\"noopener noreferrer\">#2515</a></li>\n<li>NEW: Heltec Mesh Node T1 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2520\" target=\"_blank\" rel=\"noopener noreferrer\">#2520</a></li>\n<li>new Xiao S3 variants (repeater, companion, etc) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2383\" target=\"_blank\" rel=\"noopener noreferrer\">#2383</a></li>\n</ul>\n<h3>Bug fixes and Other</h3>\n<ul>\n<li>RP2040 target build fixes. <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2684\" target=\"_blank\" rel=\"noopener noreferrer\">#2684</a></li>\n<li>companion protocol max frame size increase (now 176) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2022\" target=\"_blank\" rel=\"noopener noreferrer\">#2022</a></li>\n<li>RAK Wismesh Tag fixes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2664\" target=\"_blank\" rel=\"noopener noreferrer\">#2664</a></li>\n<li>Bug fix: repeater neighbor discovery fail when path.hash.mode != 0</li>\n<li>RAK4631, now using Bosch driver for BME680 sensor <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2634\" target=\"_blank\" rel=\"noopener noreferrer\">#2634</a></li>\n<li>enable radio.rxgain CLI command for LR1110 (T1000e) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2235\" target=\"_blank\" rel=\"noopener noreferrer\">#2235</a></li>\n<li>default flood advert interval now 47 hours (was 12) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2608\" target=\"_blank\" rel=\"noopener noreferrer\">#2608</a></li>\n<li>Client repeat (off-grid) EU freq change (from 869.0 to 869.495) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2604\" target=\"_blank\" rel=\"noopener noreferrer\">#2604</a></li>\n<li>CLI validation on rxdelay, txdelay and direct.txdelay <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2443\" target=\"_blank\" rel=\"noopener noreferrer\">#2443</a></li>\n<li>Heltec T096, sensor node support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2576\" target=\"_blank\" rel=\"noopener noreferrer\">#2576</a></li>\n<li>Heltec E290 USB companion fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2562\" target=\"_blank\" rel=\"noopener noreferrer\">#2562</a></li>\n<li>WiFi companion, reconnect logic redesigned for non-blocking <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2493\" target=\"_blank\" rel=\"noopener noreferrer\">#2493</a></li>\n<li>RAM usage reduced for older boards <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2497\" target=\"_blank\" rel=\"noopener noreferrer\">#2497</a></li>\n<li>nRF variants, CustomLFS lib upgrade to v2.2 <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2519\" target=\"_blank\" rel=\"noopener noreferrer\">#2519</a></li>\n<li>T-Echo Lite, fixes to RXEN, TXEN and TCXO <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2511\" target=\"_blank\" rel=\"noopener noreferrer\">#2511</a></li>\n<li>KISS modem frame timeout fixes <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2490\" target=\"_blank\" rel=\"noopener noreferrer\">#2490</a></li>\n<li>sensor manager redesign <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2327\" target=\"_blank\" rel=\"noopener noreferrer\">#2327</a></li>\n<li>startup tune suppressed if sound pref off <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2460\" target=\"_blank\" rel=\"noopener noreferrer\">#2460</a></li>\n<li>added KISS Modem variants for most boards <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2620\" target=\"_blank\" rel=\"noopener noreferrer\">#2620</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2432\" target=\"_blank\" rel=\"noopener noreferrer\">#2432</a></li>\n<li>Adafruit nRF BLE fork, to prevent lockup during rapid connect/disconnect <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2430\" target=\"_blank\" rel=\"noopener noreferrer\">#2430</a></li>\n<li>RAK3401 companion, analog button support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2436\" target=\"_blank\" rel=\"noopener noreferrer\">#2436</a></li>\n<li>Heltec boards, LNA disabled by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2439\" target=\"_blank\" rel=\"noopener noreferrer\">#2439</a></li>\n<li>new splash screens <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2424\" target=\"_blank\" rel=\"noopener noreferrer\">#2424</a></li>\n<li>Sensecap Solar Tx LED fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2157\" target=\"_blank\" rel=\"noopener noreferrer\">#2157</a></li>\n<li>new repeater variant: Heltec V4 expansion kit <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2326\" target=\"_blank\" rel=\"noopener noreferrer\">#2326</a></li>\n<li>new T-Echo Lite non-shell companion variants <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2503\" target=\"_blank\" rel=\"noopener noreferrer\">#2503</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2353\" target=\"_blank\" rel=\"noopener noreferrer\">#2353</a></li>\n<li>T-Echo Lite, battery measure fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2287\" target=\"_blank\" rel=\"noopener noreferrer\">#2287</a></li>\n<li>RAK4631, sx1262 reset pin fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2008\" target=\"_blank\" rel=\"noopener noreferrer\">#2008</a></li>\n<li>Heltec T096, Wireless Tracker: FEM/LNA enable by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2340\" target=\"_blank\" rel=\"noopener noreferrer\">#2340</a></li>\n<li>R1 Neo, shutdown fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2371\" target=\"_blank\" rel=\"noopener noreferrer\">#2371</a></li>\n<li>Heltec V4, set adc.multiplier support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2335\" target=\"_blank\" rel=\"noopener noreferrer\">#2335</a></li>\n</ul>\n<h2>Limiting Unscoped Traffic</h2>\n<p>The new <code>flood.max.unscoped</code> CLI config variable is specifically for limiting unscoped flood traffic. Like <code>flood.max</code>, it drops unscoped flood packets which have already had a given number of hops. By default it is 64, which is essentially <em>off</em>.</p>\n<h2>Limiting Advert Traffic</h2>\n<p>The new <code>flood.max.advert</code> CLI config variable is specifically for limiting adverts. Like <code>flood.max</code>, it drops advert packets which have already had a given number of hops. By default it is <strong>8</strong>.</p>\n<h2>New Preamble</h2>\n<p>When using the lower Spreading Factors, the radio has less time to <em>lock onto</em> an incoming packet, so this change gives the faster SF’s a longer preamble, and thus decreasing the chance of the preamble being missed. For SF &lt;= 8, the preamble is now 32 symbols.</p>\n<h2>Improved Region Discovery in Mobile App</h2>\n<p>The new companion firmware, and latest app, will be able to do ad-hoc requests to near by repeaters <em>without</em> having to add them to contacts first. This will streamline both repeater discovery, and region discovery.</p>\n<h2>New <code>region def</code> Command</h2>\n<p>Defining regions via the CLI is currently quite verbose, and the latest CLI handling introduces a new <code>region def...</code> command which has a short-hand notation for defining regions, especially ones which have deep nesting.</p>\n<p>See the <a href=\"https://docs.meshcore.io/cli_commands/\" target=\"_blank\" rel=\"noopener noreferrer\">CLI Command Reference</a> for more details.</p>\n<h2>Extended ACK Support</h2>\n<p>The latest firmwares introduce support for ‘extended ACKs’, which are 6 bytes instead of 4. The extra bytes contain an extended attempt number, and additional random byte. This is in preparation for a later app feature which will enable much more than 4 attempts for direct messages. For now, repeaters will have to be updated first.</p>\n<h2>Companion Raw Packets</h2>\n<p>The latest companion firmwares now enable apps to compose the <em>full</em> packet, ie. headers, path and payload. This can correspond with the existing RxLog ability, so app can do its own raw send and receive of packets.</p>\n"
        },
        {
          "version": "room-server-v1.15.0",
          "name": "Room Server Firmware v1.15.0",
          "datetime": "2026-04-19T03:07:54Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/room-server-v1.15.0",
          "prerelease": false,
          "notes": "**Download**\n\nLatest firmwares are in the [flasher.meshcore.io](https://flasher.meshcore.io/)\n\n**Change Log**\n\n-   Default Scope support\n-   Support for New GROUP\\_DATA (binary) packets [#1928](https://github.com/meshcore-dev/MeshCore/pull/1928) [#2130](https://github.com/meshcore-dev/MeshCore/pull/2130)\n-   Heltec V4.3 support [#1867](https://github.com/meshcore-dev/MeshCore/pull/1867)\n-   Heltec nRF Tracker (T096) support [#2097](https://github.com/meshcore-dev/MeshCore/pull/2097)\n-   GAT562 Mesh EVB Pro repeater and room server support [#2042](https://github.com/meshcore-dev/MeshCore/pull/2042)\n-   Radio rxgain now ON by default [#2124](https://github.com/meshcore-dev/MeshCore/pull/2124)\n-   Radio freq range now supported down to 150Mhz [#2126](https://github.com/meshcore-dev/MeshCore/pull/2126)\n-   GPS pref peristence fix [#2018](https://github.com/meshcore-dev/MeshCore/pull/2018)\n-   New `get|set dutycycle` CLI command [#1961](https://github.com/meshcore-dev/MeshCore/pull/1961)\n-   Muzi Works R1 Neo support [#2007](https://github.com/meshcore-dev/MeshCore/pull/2007)\n-   GAT562 Watch support [#2138](https://github.com/meshcore-dev/MeshCore/pull/2138) [#2228](https://github.com/meshcore-dev/MeshCore/pull/2228)\n-   BME680 sensor init fix [#2227](https://github.com/meshcore-dev/MeshCore/pull/2227)\n-   Heltec Wireless Paper battery read fix [#2164](https://github.com/meshcore-dev/MeshCore/pull/2164)\n-   WiFi companion fixes for Heltec V4,TBeam 1W [#1833](https://github.com/meshcore-dev/MeshCore/pull/1833)\n-   Waveshare RP2040: RXEN fix [#2298](https://github.com/meshcore-dev/MeshCore/pull/2298)\n-   nRF companion, support for OTA updates [#2323](https://github.com/meshcore-dev/MeshCore/pull/2323)\n-   Added companion for Heltec Wireless Paper [#2315](https://github.com/meshcore-dev/MeshCore/pull/2315)\n-   Misc [#2134](https://github.com/meshcore-dev/MeshCore/pull/2134) [#2190](https://github.com/meshcore-dev/MeshCore/pull/2190) [#1425](https://github.com/meshcore-dev/MeshCore/pull/1425) [#2075](https://github.com/meshcore-dev/MeshCore/pull/2075) [#2302](https://github.com/meshcore-dev/MeshCore/pull/2302) [#2306](https://github.com/meshcore-dev/MeshCore/pull/2306)\n-   Xiao C3 bootloop fix [#2328](https://github.com/meshcore-dev/MeshCore/pull/2328)\n\n**Documentation Links**\n\nFor info on the new Default Scope feature, please see [this article](https://blog.meshcore.io/2026/04/17/default-scope).\n\nFor low level format of the GROUP\\_DATA packets, please see [this docs link](https://docs.meshcore.io/payloads/?h=group+datagram#group-datagram).",
          "notesUrl": "https://blog.meshcore.io/2026/04/19/release-1-15-0",
          "notesHtml": "<p><strong>Download</strong></p>\n<p>Latest firmwares are in the <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></p>\n<p><strong>Change Log</strong></p>\n<ul>\n<li>Default Scope support</li>\n<li>Support for New GROUP_DATA (binary) packets <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1928\" target=\"_blank\" rel=\"noopener noreferrer\">#1928</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2130\" target=\"_blank\" rel=\"noopener noreferrer\">#2130</a></li>\n<li>Heltec V4.3 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1867\" target=\"_blank\" rel=\"noopener noreferrer\">#1867</a></li>\n<li>Heltec nRF Tracker (T096) support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2097\" target=\"_blank\" rel=\"noopener noreferrer\">#2097</a></li>\n<li>GAT562 Mesh EVB Pro repeater and room server support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2042\" target=\"_blank\" rel=\"noopener noreferrer\">#2042</a></li>\n<li>Radio rxgain now ON by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2124\" target=\"_blank\" rel=\"noopener noreferrer\">#2124</a></li>\n<li>Radio freq range now supported down to 150Mhz <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2126\" target=\"_blank\" rel=\"noopener noreferrer\">#2126</a></li>\n<li>GPS pref peristence fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2018\" target=\"_blank\" rel=\"noopener noreferrer\">#2018</a></li>\n<li>New <code>get|set dutycycle</code> CLI command <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1961\" target=\"_blank\" rel=\"noopener noreferrer\">#1961</a></li>\n<li>Muzi Works R1 Neo support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2007\" target=\"_blank\" rel=\"noopener noreferrer\">#2007</a></li>\n<li>GAT562 Watch support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2138\" target=\"_blank\" rel=\"noopener noreferrer\">#2138</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2228\" target=\"_blank\" rel=\"noopener noreferrer\">#2228</a></li>\n<li>BME680 sensor init fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2227\" target=\"_blank\" rel=\"noopener noreferrer\">#2227</a></li>\n<li>Heltec Wireless Paper battery read fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2164\" target=\"_blank\" rel=\"noopener noreferrer\">#2164</a></li>\n<li>WiFi companion fixes for Heltec V4,TBeam 1W <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1833\" target=\"_blank\" rel=\"noopener noreferrer\">#1833</a></li>\n<li>Waveshare RP2040: RXEN fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2298\" target=\"_blank\" rel=\"noopener noreferrer\">#2298</a></li>\n<li>nRF companion, support for OTA updates <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2323\" target=\"_blank\" rel=\"noopener noreferrer\">#2323</a></li>\n<li>Added companion for Heltec Wireless Paper <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2315\" target=\"_blank\" rel=\"noopener noreferrer\">#2315</a></li>\n<li>Misc <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2134\" target=\"_blank\" rel=\"noopener noreferrer\">#2134</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2190\" target=\"_blank\" rel=\"noopener noreferrer\">#2190</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1425\" target=\"_blank\" rel=\"noopener noreferrer\">#1425</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2075\" target=\"_blank\" rel=\"noopener noreferrer\">#2075</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2302\" target=\"_blank\" rel=\"noopener noreferrer\">#2302</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2306\" target=\"_blank\" rel=\"noopener noreferrer\">#2306</a></li>\n<li>Xiao C3 bootloop fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2328\" target=\"_blank\" rel=\"noopener noreferrer\">#2328</a></li>\n</ul>\n<p><strong>Documentation Links</strong></p>\n<p>For info on the new Default Scope feature, please see <a href=\"https://blog.meshcore.io/2026/04/17/default-scope\" target=\"_blank\" rel=\"noopener noreferrer\">this article</a>.</p>\n<p>For low level format of the GROUP_DATA packets, please see <a href=\"https://docs.meshcore.io/payloads/?h=group+datagram#group-datagram\" target=\"_blank\" rel=\"noopener noreferrer\">this docs link</a>.</p>\n"
        },
        {
          "version": "repeater-v1.15.0",
          "name": "Repeater Firmware v1.15.0",
          "datetime": "2026-04-19T03:08:26Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/repeater-v1.15.0",
          "prerelease": false,
          "notes": "**Download**\n\nLatest firmwares are in the [flasher.meshcore.io](https://flasher.meshcore.io/)\n\n**Change Log**\n\n-   Default Scope support\n-   Support for New GROUP\\_DATA (binary) packets [#1928](https://github.com/meshcore-dev/MeshCore/pull/1928) [#2130](https://github.com/meshcore-dev/MeshCore/pull/2130)\n-   Heltec V4.3 support [#1867](https://github.com/meshcore-dev/MeshCore/pull/1867)\n-   Heltec nRF Tracker (T096) support [#2097](https://github.com/meshcore-dev/MeshCore/pull/2097)\n-   GAT562 Mesh EVB Pro repeater and room server support [#2042](https://github.com/meshcore-dev/MeshCore/pull/2042)\n-   Radio rxgain now ON by default [#2124](https://github.com/meshcore-dev/MeshCore/pull/2124)\n-   Radio freq range now supported down to 150Mhz [#2126](https://github.com/meshcore-dev/MeshCore/pull/2126)\n-   GPS pref peristence fix [#2018](https://github.com/meshcore-dev/MeshCore/pull/2018)\n-   New `get|set dutycycle` CLI command [#1961](https://github.com/meshcore-dev/MeshCore/pull/1961)\n-   Muzi Works R1 Neo support [#2007](https://github.com/meshcore-dev/MeshCore/pull/2007)\n-   GAT562 Watch support [#2138](https://github.com/meshcore-dev/MeshCore/pull/2138) [#2228](https://github.com/meshcore-dev/MeshCore/pull/2228)\n-   BME680 sensor init fix [#2227](https://github.com/meshcore-dev/MeshCore/pull/2227)\n-   Heltec Wireless Paper battery read fix [#2164](https://github.com/meshcore-dev/MeshCore/pull/2164)\n-   WiFi companion fixes for Heltec V4,TBeam 1W [#1833](https://github.com/meshcore-dev/MeshCore/pull/1833)\n-   Waveshare RP2040: RXEN fix [#2298](https://github.com/meshcore-dev/MeshCore/pull/2298)\n-   nRF companion, support for OTA updates [#2323](https://github.com/meshcore-dev/MeshCore/pull/2323)\n-   Added companion for Heltec Wireless Paper [#2315](https://github.com/meshcore-dev/MeshCore/pull/2315)\n-   Misc [#2134](https://github.com/meshcore-dev/MeshCore/pull/2134) [#2190](https://github.com/meshcore-dev/MeshCore/pull/2190) [#1425](https://github.com/meshcore-dev/MeshCore/pull/1425) [#2075](https://github.com/meshcore-dev/MeshCore/pull/2075) [#2302](https://github.com/meshcore-dev/MeshCore/pull/2302) [#2306](https://github.com/meshcore-dev/MeshCore/pull/2306)\n-   Xiao C3 bootloop fix [#2328](https://github.com/meshcore-dev/MeshCore/pull/2328)\n\n**Documentation Links**\n\nFor info on the new Default Scope feature, please see [this article](https://blog.meshcore.io/2026/04/17/default-scope).\n\nFor low level format of the GROUP\\_DATA packets, please see [this docs link](https://docs.meshcore.io/payloads/?h=group+datagram#group-datagram).",
          "notesUrl": "https://blog.meshcore.io/2026/04/19/release-1-15-0",
          "notesHtml": "<p><strong>Download</strong></p>\n<p>Latest firmwares are in the <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></p>\n<p><strong>Change Log</strong></p>\n<ul>\n<li>Default Scope support</li>\n<li>Support for New GROUP_DATA (binary) packets <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1928\" target=\"_blank\" rel=\"noopener noreferrer\">#1928</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2130\" target=\"_blank\" rel=\"noopener noreferrer\">#2130</a></li>\n<li>Heltec V4.3 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1867\" target=\"_blank\" rel=\"noopener noreferrer\">#1867</a></li>\n<li>Heltec nRF Tracker (T096) support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2097\" target=\"_blank\" rel=\"noopener noreferrer\">#2097</a></li>\n<li>GAT562 Mesh EVB Pro repeater and room server support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2042\" target=\"_blank\" rel=\"noopener noreferrer\">#2042</a></li>\n<li>Radio rxgain now ON by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2124\" target=\"_blank\" rel=\"noopener noreferrer\">#2124</a></li>\n<li>Radio freq range now supported down to 150Mhz <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2126\" target=\"_blank\" rel=\"noopener noreferrer\">#2126</a></li>\n<li>GPS pref peristence fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2018\" target=\"_blank\" rel=\"noopener noreferrer\">#2018</a></li>\n<li>New <code>get|set dutycycle</code> CLI command <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1961\" target=\"_blank\" rel=\"noopener noreferrer\">#1961</a></li>\n<li>Muzi Works R1 Neo support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2007\" target=\"_blank\" rel=\"noopener noreferrer\">#2007</a></li>\n<li>GAT562 Watch support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2138\" target=\"_blank\" rel=\"noopener noreferrer\">#2138</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2228\" target=\"_blank\" rel=\"noopener noreferrer\">#2228</a></li>\n<li>BME680 sensor init fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2227\" target=\"_blank\" rel=\"noopener noreferrer\">#2227</a></li>\n<li>Heltec Wireless Paper battery read fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2164\" target=\"_blank\" rel=\"noopener noreferrer\">#2164</a></li>\n<li>WiFi companion fixes for Heltec V4,TBeam 1W <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1833\" target=\"_blank\" rel=\"noopener noreferrer\">#1833</a></li>\n<li>Waveshare RP2040: RXEN fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2298\" target=\"_blank\" rel=\"noopener noreferrer\">#2298</a></li>\n<li>nRF companion, support for OTA updates <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2323\" target=\"_blank\" rel=\"noopener noreferrer\">#2323</a></li>\n<li>Added companion for Heltec Wireless Paper <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2315\" target=\"_blank\" rel=\"noopener noreferrer\">#2315</a></li>\n<li>Misc <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2134\" target=\"_blank\" rel=\"noopener noreferrer\">#2134</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2190\" target=\"_blank\" rel=\"noopener noreferrer\">#2190</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1425\" target=\"_blank\" rel=\"noopener noreferrer\">#1425</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2075\" target=\"_blank\" rel=\"noopener noreferrer\">#2075</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2302\" target=\"_blank\" rel=\"noopener noreferrer\">#2302</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2306\" target=\"_blank\" rel=\"noopener noreferrer\">#2306</a></li>\n<li>Xiao C3 bootloop fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2328\" target=\"_blank\" rel=\"noopener noreferrer\">#2328</a></li>\n</ul>\n<p><strong>Documentation Links</strong></p>\n<p>For info on the new Default Scope feature, please see <a href=\"https://blog.meshcore.io/2026/04/17/default-scope\" target=\"_blank\" rel=\"noopener noreferrer\">this article</a>.</p>\n<p>For low level format of the GROUP_DATA packets, please see <a href=\"https://docs.meshcore.io/payloads/?h=group+datagram#group-datagram\" target=\"_blank\" rel=\"noopener noreferrer\">this docs link</a>.</p>\n"
        },
        {
          "version": "companion-v1.15.0",
          "name": "Companion Firmware v1.15.0",
          "datetime": "2026-04-19T06:48:14Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.15.0",
          "prerelease": false,
          "notes": "**Download**\n\nLatest firmwares are in the [flasher.meshcore.io](https://flasher.meshcore.io/)\n\n**Change Log**\n\n-   Default Scope support\n-   Support for New GROUP\\_DATA (binary) packets [#1928](https://github.com/meshcore-dev/MeshCore/pull/1928) [#2130](https://github.com/meshcore-dev/MeshCore/pull/2130)\n-   Heltec V4.3 support [#1867](https://github.com/meshcore-dev/MeshCore/pull/1867)\n-   Heltec nRF Tracker (T096) support [#2097](https://github.com/meshcore-dev/MeshCore/pull/2097)\n-   GAT562 Mesh EVB Pro repeater and room server support [#2042](https://github.com/meshcore-dev/MeshCore/pull/2042)\n-   Radio rxgain now ON by default [#2124](https://github.com/meshcore-dev/MeshCore/pull/2124)\n-   Radio freq range now supported down to 150Mhz [#2126](https://github.com/meshcore-dev/MeshCore/pull/2126)\n-   GPS pref peristence fix [#2018](https://github.com/meshcore-dev/MeshCore/pull/2018)\n-   New `get|set dutycycle` CLI command [#1961](https://github.com/meshcore-dev/MeshCore/pull/1961)\n-   Muzi Works R1 Neo support [#2007](https://github.com/meshcore-dev/MeshCore/pull/2007)\n-   GAT562 Watch support [#2138](https://github.com/meshcore-dev/MeshCore/pull/2138) [#2228](https://github.com/meshcore-dev/MeshCore/pull/2228)\n-   BME680 sensor init fix [#2227](https://github.com/meshcore-dev/MeshCore/pull/2227)\n-   Heltec Wireless Paper battery read fix [#2164](https://github.com/meshcore-dev/MeshCore/pull/2164)\n-   WiFi companion fixes for Heltec V4,TBeam 1W [#1833](https://github.com/meshcore-dev/MeshCore/pull/1833)\n-   Waveshare RP2040: RXEN fix [#2298](https://github.com/meshcore-dev/MeshCore/pull/2298)\n-   nRF companion, support for OTA updates [#2323](https://github.com/meshcore-dev/MeshCore/pull/2323)\n-   Added companion for Heltec Wireless Paper [#2315](https://github.com/meshcore-dev/MeshCore/pull/2315)\n-   Misc [#2134](https://github.com/meshcore-dev/MeshCore/pull/2134) [#2190](https://github.com/meshcore-dev/MeshCore/pull/2190) [#1425](https://github.com/meshcore-dev/MeshCore/pull/1425) [#2075](https://github.com/meshcore-dev/MeshCore/pull/2075) [#2302](https://github.com/meshcore-dev/MeshCore/pull/2302) [#2306](https://github.com/meshcore-dev/MeshCore/pull/2306)\n-   Xiao C3 bootloop fix [#2328](https://github.com/meshcore-dev/MeshCore/pull/2328)\n\n**Documentation Links**\n\nFor info on the new Default Scope feature, please see [this article](https://blog.meshcore.io/2026/04/17/default-scope).\n\nFor low level format of the GROUP\\_DATA packets, please see [this docs link](https://docs.meshcore.io/payloads/?h=group+datagram#group-datagram).",
          "notesUrl": "https://blog.meshcore.io/2026/04/19/release-1-15-0",
          "notesHtml": "<p><strong>Download</strong></p>\n<p>Latest firmwares are in the <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></p>\n<p><strong>Change Log</strong></p>\n<ul>\n<li>Default Scope support</li>\n<li>Support for New GROUP_DATA (binary) packets <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1928\" target=\"_blank\" rel=\"noopener noreferrer\">#1928</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2130\" target=\"_blank\" rel=\"noopener noreferrer\">#2130</a></li>\n<li>Heltec V4.3 support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1867\" target=\"_blank\" rel=\"noopener noreferrer\">#1867</a></li>\n<li>Heltec nRF Tracker (T096) support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2097\" target=\"_blank\" rel=\"noopener noreferrer\">#2097</a></li>\n<li>GAT562 Mesh EVB Pro repeater and room server support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2042\" target=\"_blank\" rel=\"noopener noreferrer\">#2042</a></li>\n<li>Radio rxgain now ON by default <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2124\" target=\"_blank\" rel=\"noopener noreferrer\">#2124</a></li>\n<li>Radio freq range now supported down to 150Mhz <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2126\" target=\"_blank\" rel=\"noopener noreferrer\">#2126</a></li>\n<li>GPS pref peristence fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2018\" target=\"_blank\" rel=\"noopener noreferrer\">#2018</a></li>\n<li>New <code>get|set dutycycle</code> CLI command <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1961\" target=\"_blank\" rel=\"noopener noreferrer\">#1961</a></li>\n<li>Muzi Works R1 Neo support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2007\" target=\"_blank\" rel=\"noopener noreferrer\">#2007</a></li>\n<li>GAT562 Watch support <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2138\" target=\"_blank\" rel=\"noopener noreferrer\">#2138</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2228\" target=\"_blank\" rel=\"noopener noreferrer\">#2228</a></li>\n<li>BME680 sensor init fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2227\" target=\"_blank\" rel=\"noopener noreferrer\">#2227</a></li>\n<li>Heltec Wireless Paper battery read fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2164\" target=\"_blank\" rel=\"noopener noreferrer\">#2164</a></li>\n<li>WiFi companion fixes for Heltec V4,TBeam 1W <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1833\" target=\"_blank\" rel=\"noopener noreferrer\">#1833</a></li>\n<li>Waveshare RP2040: RXEN fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2298\" target=\"_blank\" rel=\"noopener noreferrer\">#2298</a></li>\n<li>nRF companion, support for OTA updates <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2323\" target=\"_blank\" rel=\"noopener noreferrer\">#2323</a></li>\n<li>Added companion for Heltec Wireless Paper <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2315\" target=\"_blank\" rel=\"noopener noreferrer\">#2315</a></li>\n<li>Misc <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2134\" target=\"_blank\" rel=\"noopener noreferrer\">#2134</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2190\" target=\"_blank\" rel=\"noopener noreferrer\">#2190</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1425\" target=\"_blank\" rel=\"noopener noreferrer\">#1425</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2075\" target=\"_blank\" rel=\"noopener noreferrer\">#2075</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2302\" target=\"_blank\" rel=\"noopener noreferrer\">#2302</a> <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2306\" target=\"_blank\" rel=\"noopener noreferrer\">#2306</a></li>\n<li>Xiao C3 bootloop fix <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2328\" target=\"_blank\" rel=\"noopener noreferrer\">#2328</a></li>\n</ul>\n<p><strong>Documentation Links</strong></p>\n<p>For info on the new Default Scope feature, please see <a href=\"https://blog.meshcore.io/2026/04/17/default-scope\" target=\"_blank\" rel=\"noopener noreferrer\">this article</a>.</p>\n<p>For low level format of the GROUP_DATA packets, please see <a href=\"https://docs.meshcore.io/payloads/?h=group+datagram#group-datagram\" target=\"_blank\" rel=\"noopener noreferrer\">this docs link</a>.</p>\n"
        },
        {
          "version": "room-server-v1.14.1",
          "name": "Room Server Firmware v1.14.1",
          "datetime": "2026-03-20T02:54:49Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/room-server-v1.14.1",
          "prerelease": false,
          "notes": "change log:\r\nAdded GPS support for SenseCAP Solar P1 in #1589\r\nPower off switch long press support for SenseCAP Solar P1 #1871\r\nAdded nRF52 power management for RAK3401 in #1984\r\nAdded token bucket based duty cycle enforcement in #1297\r\nAdded support for new GAT562 30S Mesh Kit device in #2009\r\nAdded support for new GAT562 Mesh Tracker Pro device in #1980\r\nAdded LNA toggle CLI commands radio.rxgain on and radio.rxgain off in #1653\r\nAdded MCU temperature to telemetry responses from room servers in #2052\r\nMigrated Heltec Tracker v2 to KCT8103L in #1936\r\nNodes with GPS enabled will now auto sync time every 30 minutes in #1350\r\nFixed bug where some queued packets would not get transmit in #1877\r\nFixed bug where automatic adverts were not using the configured multibyte path setting in fcfdc5f",
          "notesHtml": "<p>change log:\nAdded GPS support for SenseCAP Solar P1 in #1589\nPower off switch long press support for SenseCAP Solar P1 #1871\nAdded nRF52 power management for RAK3401 in #1984\nAdded token bucket based duty cycle enforcement in #1297\nAdded support for new GAT562 30S Mesh Kit device in #2009\nAdded support for new GAT562 Mesh Tracker Pro device in #1980\nAdded LNA toggle CLI commands radio.rxgain on and radio.rxgain off in #1653\nAdded MCU temperature to telemetry responses from room servers in #2052\nMigrated Heltec Tracker v2 to KCT8103L in #1936\nNodes with GPS enabled will now auto sync time every 30 minutes in #1350\nFixed bug where some queued packets would not get transmit in #1877\nFixed bug where automatic adverts were not using the configured multibyte path setting in fcfdc5f</p>\n"
        },
        {
          "version": "repeater-v1.14.1",
          "name": "Repeater Firmware v1.14.1",
          "datetime": "2026-03-20T02:55:43Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/repeater-v1.14.1",
          "prerelease": false,
          "notes": "change log:\r\nAdded GPS support for SenseCAP Solar P1 in #1589\r\nPower off switch long press support for SenseCAP Solar P1 #1871\r\nAdded nRF52 power management for RAK3401 in #1984\r\nAdded token bucket based duty cycle enforcement in #1297\r\nAdded support for new GAT562 30S Mesh Kit device in #2009\r\nAdded support for new GAT562 Mesh Tracker Pro device in #1980\r\nAdded LNA toggle CLI commands radio.rxgain on and radio.rxgain off in #1653\r\nAdded MCU temperature to telemetry responses from room servers in #2052\r\nMigrated Heltec Tracker v2 to KCT8103L in #1936\r\nNodes with GPS enabled will now auto sync time every 30 minutes in #1350\r\nFixed bug where some queued packets would not get transmit in #1877\r\nFixed bug where automatic adverts were not using the configured multibyte path setting in https://github.com/meshcore-dev/MeshCore/commit/fcfdc5fc5b1e0cf81b4ca2dfbc51d714f3eb1ead",
          "notesHtml": "<p>change log:\nAdded GPS support for SenseCAP Solar P1 in #1589\nPower off switch long press support for SenseCAP Solar P1 #1871\nAdded nRF52 power management for RAK3401 in #1984\nAdded token bucket based duty cycle enforcement in #1297\nAdded support for new GAT562 30S Mesh Kit device in #2009\nAdded support for new GAT562 Mesh Tracker Pro device in #1980\nAdded LNA toggle CLI commands radio.rxgain on and radio.rxgain off in #1653\nAdded MCU temperature to telemetry responses from room servers in #2052\nMigrated Heltec Tracker v2 to KCT8103L in #1936\nNodes with GPS enabled will now auto sync time every 30 minutes in #1350\nFixed bug where some queued packets would not get transmit in #1877\nFixed bug where automatic adverts were not using the configured multibyte path setting in <a href=\"https://github.com/meshcore-dev/MeshCore/commit/fcfdc5fc5b1e0cf81b4ca2dfbc51d714f3eb1ead\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/commit/fcfdc5fc5b1e0cf81b4ca2dfbc51d714f3eb1ead</a></p>\n"
        },
        {
          "version": "companion-v1.14.1",
          "name": "Companion Firmware v1.14.1",
          "datetime": "2026-03-20T03:53:00Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.14.1",
          "prerelease": false,
          "notes": "change log:\r\nAdded GPS support for SenseCAP Solar P1 in #1589\r\nAdded nRF52 power management for RAK3401 in #1984\r\nAdded token bucket based duty cycle enforcement in #1297\r\nAdded support for new GAT562 30S Mesh Kit device in #2009\r\nAdded support for new GAT562 Mesh Tracker Pro device in #1980\r\nAdded LNA toggle CLI commands radio.rxgain on and radio.rxgain off in #1653\r\nAdded MCU temperature to telemetry responses from room servers in #2052\r\nMigrated Heltec Tracker v2 to KCT8103L in #1936\r\nFixed bug where some queued packets would not get transmit in #1877\r\nFixed bug where BLE would stay on if turned off from companion screen when already connected in #1991",
          "notesHtml": "<p>change log:\nAdded GPS support for SenseCAP Solar P1 in #1589\nAdded nRF52 power management for RAK3401 in #1984\nAdded token bucket based duty cycle enforcement in #1297\nAdded support for new GAT562 30S Mesh Kit device in #2009\nAdded support for new GAT562 Mesh Tracker Pro device in #1980\nAdded LNA toggle CLI commands radio.rxgain on and radio.rxgain off in #1653\nAdded MCU temperature to telemetry responses from room servers in #2052\nMigrated Heltec Tracker v2 to KCT8103L in #1936\nFixed bug where some queued packets would not get transmit in #1877\nFixed bug where BLE would stay on if turned off from companion screen when already connected in #1991</p>\n"
        },
        {
          "version": "room-server-v1.14.0",
          "name": "Room Server Firmware v1.14.0",
          "datetime": "2026-03-06T02:37:59Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/room-server-v1.14.0",
          "prerelease": false,
          "notes": "Change log:\r\n* multibyte path hash support\r\n* new radio AGC reset implementation\r\n* HeltecV4 power fixes\r\n* RAK3401 power optimisations\r\n* Heltec Tracker V2 power fixes",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>multibyte path hash support</li>\n<li>new radio AGC reset implementation</li>\n<li>HeltecV4 power fixes</li>\n<li>RAK3401 power optimisations</li>\n<li>Heltec Tracker V2 power fixes</li>\n</ul>\n"
        },
        {
          "version": "repeater-v1.14.0",
          "name": "Repeater Firmware v1.14.0",
          "datetime": "2026-03-06T02:37:28Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/repeater-v1.14.0",
          "prerelease": false,
          "notes": "Change log:\r\n* multibyte path hash support\r\n* new CLI command: “get/set loop.detect …”\r\n* new CLI command: “get/set path.hash.mode …”\r\n* new CLI command: “get bootloader.ver”\r\n* new CLI command: “discover.neighbors”\r\n* new radio AGC reset implementation\r\n* HeltecV4 power fixes\r\n* RAK3401 power optimisations\r\n* Heltec Tracker V2 power fixes",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>multibyte path hash support</li>\n<li>new CLI command: “get/set loop.detect …”</li>\n<li>new CLI command: “get/set path.hash.mode …”</li>\n<li>new CLI command: “get bootloader.ver”</li>\n<li>new CLI command: “discover.neighbors”</li>\n<li>new radio AGC reset implementation</li>\n<li>HeltecV4 power fixes</li>\n<li>RAK3401 power optimisations</li>\n<li>Heltec Tracker V2 power fixes</li>\n</ul>\n"
        },
        {
          "version": "companion-v1.14.0",
          "name": "Companion Firmware v1.14.0",
          "datetime": "2026-03-06T03:52:31Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.14.0",
          "prerelease": false,
          "notes": "Change log:\r\n* multibyte path hash support\r\n* new ‘auto add max hops’ preference\r\n* new radio AGC reset implementation\r\n* HeltecV4 power fixes\r\n* RAK3401 power optimisations\r\n* Heltec Tracker V2 power fixes",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>multibyte path hash support</li>\n<li>new ‘auto add max hops’ preference</li>\n<li>new radio AGC reset implementation</li>\n<li>HeltecV4 power fixes</li>\n<li>RAK3401 power optimisations</li>\n<li>Heltec Tracker V2 power fixes</li>\n</ul>\n"
        },
        {
          "version": "room-server-v1.13.0",
          "name": "Room Server Firmware v1.13.0",
          "datetime": "2026-02-15T07:48:23Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/room-server-v1.13.0",
          "prerelease": false,
          "notes": "Change log:\r\n* Thinknode M3 fixes\r\n* new boards: T-Beam 1W, M5 Stack C6\r\n* nRF board sleep optimisations\r\n* Heltec V4: improved RX sensitivity, low power fixes\r\n* WIO Tracker L1 Grove sensor support",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>Thinknode M3 fixes</li>\n<li>new boards: T-Beam 1W, M5 Stack C6</li>\n<li>nRF board sleep optimisations</li>\n<li>Heltec V4: improved RX sensitivity, low power fixes</li>\n<li>WIO Tracker L1 Grove sensor support</li>\n</ul>\n"
        },
        {
          "version": "repeater-v1.13.0",
          "name": "Repeater Firmware v1.13.0",
          "datetime": "2026-02-15T07:47:04Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/repeater-v1.13.0",
          "prerelease": false,
          "notes": "Change log:\r\n* Thinknode M3 fixes\r\n* new boards: T-Beam 1W, M5 Stack C6\r\n* new stats field: receive errors\r\n* nRF board sleep optimisations\r\n* Heltec V4: improved RX sensitivity, low power fixes\r\n* WIO Tracker L1 Grove sensor support",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>Thinknode M3 fixes</li>\n<li>new boards: T-Beam 1W, M5 Stack C6</li>\n<li>new stats field: receive errors</li>\n<li>nRF board sleep optimisations</li>\n<li>Heltec V4: improved RX sensitivity, low power fixes</li>\n<li>WIO Tracker L1 Grove sensor support</li>\n</ul>\n"
        },
        {
          "version": "companion-v1.13.0",
          "name": "Companion Firmware v1.13.0",
          "datetime": "2026-02-15T08:49:34Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.13.0",
          "prerelease": false,
          "notes": "Change log:\r\n* off-grid (client repeat) mode support\r\n* buzzer sound logic reverted\r\n* new boards: T-Beam 1W, M5 Stack C6\r\n* some UI fixes, mute icon\r\n* blob file cleanup added\r\n* Heltec V4: improved RX sensitivity, low power fixes\r\n* WIO Tracker L1 Grove sensor support",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>off-grid (client repeat) mode support</li>\n<li>buzzer sound logic reverted</li>\n<li>new boards: T-Beam 1W, M5 Stack C6</li>\n<li>some UI fixes, mute icon</li>\n<li>blob file cleanup added</li>\n<li>Heltec V4: improved RX sensitivity, low power fixes</li>\n<li>WIO Tracker L1 Grove sensor support</li>\n</ul>\n"
        },
        {
          "version": "room-server-v1.12.0",
          "name": "Room Server Firmware v1.12.0",
          "datetime": "2026-01-29T11:18:49Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/room-server-v1.12.0",
          "prerelease": false,
          "notes": "Change log:\r\n* new boards: Thinknode M6, M3, RAK3401, RAK11310, Meshtiny\r\n* nRF low power recovery manager\r\n* sensor fixes: BMP280, LPS22HB, SHTC3\r\n* new “clkreboot” CLI\r\n* on-boot adverts now zero-hop\r\n* remote “set prv.key” CLI \r\n* new “get/set owner.info” CLI\r\n* flood.advert.interval range now 3..168 hours\r\n* MCU temperature now in telemetry responses",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>new boards: Thinknode M6, M3, RAK3401, RAK11310, Meshtiny</li>\n<li>nRF low power recovery manager</li>\n<li>sensor fixes: BMP280, LPS22HB, SHTC3</li>\n<li>new “clkreboot” CLI</li>\n<li>on-boot adverts now zero-hop</li>\n<li>remote “set prv.key” CLI </li>\n<li>new “get/set owner.info” CLI</li>\n<li>flood.advert.interval range now 3..168 hours</li>\n<li>MCU temperature now in telemetry responses</li>\n</ul>\n"
        },
        {
          "version": "repeater-v1.12.0",
          "name": "Repeater Firmware v1.12.0",
          "datetime": "2026-01-29T11:26:04Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/repeater-v1.12.0",
          "prerelease": false,
          "notes": "Change log:\r\n* new boards: Thinknode M6, M3, RAK3401, RAK11310, Meshtiny\r\n* nRF low power recovery manager (CLI ‘pwrmgt’)\r\n* Stats: new recv errors counter\r\n* region names now without ‘#’, new ‘region list’ CLI\r\n* ESP32: new “powersaving on/off” CLI\r\n* new “clkreboot” CLI\r\n* on-boot adverts now zero-hop\r\n* new “get/set owner.info” CLI\r\n* flood.advert.interval range now 3..168 hours\r\n* remote “set prv.key” CLI \r\n* new zero-hop anonReq types (Region discovery, owner info, clock sync)\r\n* MCU temperature now in telemetry responses",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>new boards: Thinknode M6, M3, RAK3401, RAK11310, Meshtiny</li>\n<li>nRF low power recovery manager (CLI ‘pwrmgt’)</li>\n<li>Stats: new recv errors counter</li>\n<li>region names now without ‘#’, new ‘region list’ CLI</li>\n<li>ESP32: new “powersaving on/off” CLI</li>\n<li>new “clkreboot” CLI</li>\n<li>on-boot adverts now zero-hop</li>\n<li>new “get/set owner.info” CLI</li>\n<li>flood.advert.interval range now 3..168 hours</li>\n<li>remote “set prv.key” CLI </li>\n<li>new zero-hop anonReq types (Region discovery, owner info, clock sync)</li>\n<li>MCU temperature now in telemetry responses</li>\n</ul>\n"
        },
        {
          "version": "companion-v1.12.0",
          "name": "Companion Firmware v1.12.0",
          "datetime": "2026-01-29T12:10:45Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.12.0",
          "prerelease": false,
          "notes": "Change log:\r\n* new boards: Thinknode M6, M3, RAK3401, RAK11310, Meshtiny\r\n* nRF low power recovery manager\r\n* BLE code rewritten\r\n* WiFi serial fixes\r\n* contacts db can now overwrite old entries\r\n* new prefs: buzzer quiet, gps enabled, gps interval",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>new boards: Thinknode M6, M3, RAK3401, RAK11310, Meshtiny</li>\n<li>nRF low power recovery manager</li>\n<li>BLE code rewritten</li>\n<li>WiFi serial fixes</li>\n<li>contacts db can now overwrite old entries</li>\n<li>new prefs: buzzer quiet, gps enabled, gps interval</li>\n</ul>\n"
        },
        {
          "version": "room-server-v1.11.0",
          "name": "Room Server Firmware v1.11.0",
          "datetime": "2025-11-30T08:34:45Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/room-server-v1.11.0",
          "prerelease": false,
          "notes": "Change log:\r\n* remote login bug fix (no responses after login)\r\n* Extended Trace support\r\n* get/set adc,multiplier support\r\n* New boards: Ikoka handheld, Keepteen LT1",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>remote login bug fix (no responses after login)</li>\n<li>Extended Trace support</li>\n<li>get/set adc,multiplier support</li>\n<li>New boards: Ikoka handheld, Keepteen LT1</li>\n</ul>\n"
        },
        {
          "version": "repeater-v1.11.0",
          "name": "Repeater Firmware v1.11.0",
          "datetime": "2025-11-30T08:33:44Z",
          "url": "https://github.com/meshcore-dev/MeshCore/releases/tag/repeater-v1.11.0",
          "prerelease": false,
          "notes": "Change log:\r\n* remote login bug fix (no responses after login)\r\n* Extended Trace support\r\n* get/set adc,multiplier support\r\n* RAK4631: Uart bridge support\r\n* New boards: Ikoka handheld, Keepteen LT1",
          "notesHtml": "<p>Change log:</p>\n<ul>\n<li>remote login bug fix (no responses after login)</li>\n<li>Extended Trace support</li>\n<li>get/set adc,multiplier support</li>\n<li>RAK4631: Uart bridge support</li>\n<li>New boards: Ikoka handheld, Keepteen LT1</li>\n</ul>\n"
        }
      ],
      "changelogSource": "script",
      "changelogUpdatedAt": "2026-06-21T09:55:37.699Z"
    },
    {
      "id": "cubecell-meshcore",
      "name": "CubeCell MeshCore",
      "type": "fork",
      "maintainer": "atomozero",
      "description": "A minimal MeshCore-compatible repeater firmware for Heltec CubeCell boards (HTCC-AB01, AB02, AC01). Extends mesh coverage with flood routing, supports authenticated remote management via companion app, and includes automatic daily health reports. Optimized for solar-powered deployments.\n",
      "repository": "https://github.com/atomozero/CubeCellMeshCore",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "repeater"
      ],
      "features": [
        "Flood routing repeater",
        "Authenticated remote management via companion app",
        "Automatic daily health reports",
        "Solar-powered optimization",
        "CubeCell board support (HTCC-AB01, AB02, AC01)"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": false,
          "usbSerial": true,
          "nativeTcp": false,
          "wifiAp": false
        },
        "operations": {
          "ota": false,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": false,
          "display": false,
          "sensors": false,
          "lowPowerRx": true
        }
      },
      "devices": [
        {
          "id": "cubecell-htcc-ab01",
          "status": "supported"
        }
      ],
      "popularity": {
        "githubStars": 13,
        "githubForks": 1,
        "githubWatchers": 3,
        "githubOpenIssues": 5,
        "githubContributors": 2,
        "releaseDownloads": 79,
        "latestReleaseDownloads": 49,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": false,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "0.5.0",
      "released": "2026-02-14",
      "releases": [
        {
          "version": "v0.5.0",
          "name": "v0.5.0 San Valentino Release",
          "datetime": "2026-02-14T16:53:46Z",
          "url": "https://github.com/atomozero/CubeCellMeshCore/releases/tag/v0.5.0",
          "prerelease": false,
          "notes": "Quiet Hours + Circuit Breaker + Adaptive TX Power\r\n\r\n  Three new features leveraging the existing SNR/RSSI infrastructure to improve reliability, power savings, and mesh network resilience.\r\n\r\n- Quiet Hours — Configurable night-time rate limiting (e.g. 22:00-06:00) reduces forwarding from 100 to 30 packets/min. Saves battery during low-traffic periods. Requires TimeSync.\r\n\r\n- Circuit Breaker — Automatically blocks DIRECT forwarding to neighbours with degraded links (SNR < -10dB). Transitions to half-open after 5 minutes for a test packet. Good SNR closes the breaker. FLOOD traffic is never blocked.\r\n\r\n- Adaptive TX Power — Dynamically adjusts transmit power (5-14 dBm EU) based on average neighbour SNR. Reduces power when signal is strong, increases when weak.",
          "notesHtml": "<p>Quiet Hours + Circuit Breaker + Adaptive TX Power</p>\n<p>  Three new features leveraging the existing SNR/RSSI infrastructure to improve reliability, power savings, and mesh network resilience.</p>\n<ul>\n<li><p>Quiet Hours — Configurable night-time rate limiting (e.g. 22:00-06:00) reduces forwarding from 100 to 30 packets/min. Saves battery during low-traffic periods. Requires TimeSync.</p>\n</li>\n<li><p>Circuit Breaker — Automatically blocks DIRECT forwarding to neighbours with degraded links (SNR &lt; -10dB). Transitions to half-open after 5 minutes for a test packet. Good SNR closes the breaker. FLOOD traffic is never blocked.</p>\n</li>\n<li><p>Adaptive TX Power — Dynamically adjusts transmit power (5-14 dBm EU) based on average neighbour SNR. Reduces power when signal is strong, increases when weak.</p>\n</li>\n</ul>\n"
        },
        {
          "version": "v0.4.0",
          "name": "v0.4.0 - Battery Fix, Remote CLI & Flash Optimization",
          "datetime": "2026-02-09T22:23:34Z",
          "url": "https://github.com/atomozero/CubeCellMeshCore/releases/tag/v0.4.0",
          "prerelease": false,
          "notes": "## What's New in v0.4.0\r\n\r\n   ### Bug Fixes\r\n   - **Battery ADC fixed** - Resolved 0V battery reading caused by\r\n   CubeCell framework 1.6.0 bug (ch3 SAR calibration not initialized).\r\n   New workaround uses `analogRead()` + ch0 calibration + `VBAT_ADC_CTL`\r\n    circuit control\r\n   - **Airtime tracking** - RX/TX airtime now properly calculated\r\n   per-packet using LoRa formula\r\n   - **Noise floor estimation** - EMA-smoothed noise floor from\r\n   RSSI-SNR, no longer stuck at 0dB\r\n   - **Remote CLI commands** - Fixed \"Err:Unknown\" for commands only\r\n   available on local serial\r\n\r\n   ### New Features\r\n   - **`radiostats` command** - Noise floor, last RSSI/SNR, airtime\r\n   TX/RX (serial + remote)\r\n   - **`packetstats` command** - Packet breakdown: flood/direct RX/TX\r\n   (serial + remote)\r\n   - **`lifetime` command** - Now available via remote CLI (was\r\n   serial-only)\r\n   - **`tempradio` command** - Temporary radio parameter changes without\r\n    saving to EEPROM\r\n\r\n   ### Optimizations\r\n   - **Flash savings: 2,904 bytes** - String abbreviation in LOG/LOG_RAW\r\n    macros (98.3% → 96.0%)\r\n   - Startup banner simplified (removed unicode box-drawing characters)\r\n\r\n   ### Documentation\r\n   - Complete command reference tables in README\r\n   - Corrected radio parameters (frequency, TX power, sync word)\r\n\r\n   ### Build Info\r\n   - Flash: 96.5% (126,492 / 131,072 bytes)\r\n   - RAM: 51.3% (8,408 / 16,384 bytes)\r\n   - Board: Heltec CubeCell HTCC-AB01\r\n   - Region: EU868",
          "notesHtml": "<h2>What's New in v0.4.0</h2>\n<h3>Bug Fixes</h3>\n<ul>\n<li><strong>Battery ADC fixed</strong> - Resolved 0V battery reading caused by\n   CubeCell framework 1.6.0 bug (ch3 SAR calibration not initialized).\n   New workaround uses <code>analogRead()</code> + ch0 calibration + <code>VBAT_ADC_CTL</code>\ncircuit control</li>\n<li><strong>Airtime tracking</strong> - RX/TX airtime now properly calculated\n   per-packet using LoRa formula</li>\n<li><strong>Noise floor estimation</strong> - EMA-smoothed noise floor from\n   RSSI-SNR, no longer stuck at 0dB</li>\n<li><strong>Remote CLI commands</strong> - Fixed \"Err:Unknown\" for commands only\n   available on local serial</li>\n</ul>\n<h3>New Features</h3>\n<ul>\n<li><strong><code>radiostats</code> command</strong> - Noise floor, last RSSI/SNR, airtime\n   TX/RX (serial + remote)</li>\n<li><strong><code>packetstats</code> command</strong> - Packet breakdown: flood/direct RX/TX\n   (serial + remote)</li>\n<li><strong><code>lifetime</code> command</strong> - Now available via remote CLI (was\n   serial-only)</li>\n<li><strong><code>tempradio</code> command</strong> - Temporary radio parameter changes without\nsaving to EEPROM</li>\n</ul>\n<h3>Optimizations</h3>\n<ul>\n<li><strong>Flash savings: 2,904 bytes</strong> - String abbreviation in LOG/LOG_RAW\nmacros (98.3% → 96.0%)</li>\n<li>Startup banner simplified (removed unicode box-drawing characters)</li>\n</ul>\n<h3>Documentation</h3>\n<ul>\n<li>Complete command reference tables in README</li>\n<li>Corrected radio parameters (frequency, TX power, sync word)</li>\n</ul>\n<h3>Build Info</h3>\n<ul>\n<li>Flash: 96.5% (126,492 / 131,072 bytes)</li>\n<li>RAM: 51.3% (8,408 / 16,384 bytes)</li>\n<li>Board: Heltec CubeCell HTCC-AB01</li>\n<li>Region: EU868</li>\n</ul>\n"
        },
        {
          "version": "v0.3.3",
          "name": "CubeCellMeshCore v0.3.3",
          "datetime": "2026-01-23T21:37:34Z",
          "url": "https://github.com/atomozero/CubeCellMeshCore/releases/tag/v0.3.3",
          "prerelease": false,
          "notes": "## Features\r\n\r\n  - **MeshCore Protocol Compatible** - Works with MeshCore Android/iOS apps\r\n  - **Ed25519 Authentication** - Secure login with encrypted sessions\r\n  - **Rate Limiting** - Protection against brute-force and flood attacks\r\n  - **Persistent Statistics** - Lifetime stats survive reboots (EEPROM)\r\n  - **Neighbour Tracking** - Direct repeater discovery via 0-hop ADVERTs\r\n  - **Remote CLI** - Encrypted command access via mesh network\r\n  - **Deep Sleep** - Low power mode support\r\n\r\n  ## What's New in v0.3.3\r\n\r\n  - Added persistent statistics stored in EEPROM\r\n  - Tracks lifetime: RX/TX/FWD packets, unique nodes, logins, uptime\r\n  - Auto-save every 5 minutes with CRC16 integrity\r\n  - New commands: `lifetime`, `savestats`\r\n  - Boot counter for reliability monitoring\r\n\r\n  ## Installation\r\n\r\n  Download `CubeCellMeshCore-v0.3.3.zip` and flash using CubeCellTool or PlatformIO.\r\n\r\n  See `INSTALL.md` for detailed instructions.\r\n\r\n  ## Hardware\r\n\r\n  - Heltec CubeCell HTCC-AB01\r\n  - Flash: 95.8% used\r\n  - RAM: 51.1% used",
          "notesHtml": "<h2>Features</h2>\n<ul>\n<li><strong>MeshCore Protocol Compatible</strong> - Works with MeshCore Android/iOS apps</li>\n<li><strong>Ed25519 Authentication</strong> - Secure login with encrypted sessions</li>\n<li><strong>Rate Limiting</strong> - Protection against brute-force and flood attacks</li>\n<li><strong>Persistent Statistics</strong> - Lifetime stats survive reboots (EEPROM)</li>\n<li><strong>Neighbour Tracking</strong> - Direct repeater discovery via 0-hop ADVERTs</li>\n<li><strong>Remote CLI</strong> - Encrypted command access via mesh network</li>\n<li><strong>Deep Sleep</strong> - Low power mode support</li>\n</ul>\n<h2>What's New in v0.3.3</h2>\n<ul>\n<li>Added persistent statistics stored in EEPROM</li>\n<li>Tracks lifetime: RX/TX/FWD packets, unique nodes, logins, uptime</li>\n<li>Auto-save every 5 minutes with CRC16 integrity</li>\n<li>New commands: <code>lifetime</code>, <code>savestats</code></li>\n<li>Boot counter for reliability monitoring</li>\n</ul>\n<h2>Installation</h2>\n<p>  Download <code>CubeCellMeshCore-v0.3.3.zip</code> and flash using CubeCellTool or PlatformIO.</p>\n<p>  See <code>INSTALL.md</code> for detailed instructions.</p>\n<h2>Hardware</h2>\n<ul>\n<li>Heltec CubeCell HTCC-AB01</li>\n<li>Flash: 95.8% used</li>\n<li>RAM: 51.1% used</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:27.762Z"
    },
    {
      "id": "eastmesh",
      "name": "EastMesh",
      "type": "fork",
      "maintainer": "xJARiD",
      "description": "EastMesh firmware builds for MeshCore, with MQTT repeaters, WiFi companions, and simple release downloads for supported boards. Features an optional local HTTPS config panel on supported ESP32 targets, JWT auth using device identity, and battery reporting.\n",
      "repository": "https://github.com/xJARiD/MeshCore-EastMesh",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "observer"
      ],
      "features": [
        "MQTT repeater builds",
        "WiFi companion builds",
        "Optional local HTTPS config panel (ESP32)",
        "JWT auth using device identity",
        "Battery reporting on supported targets",
        "Observer role support"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": false,
          "observer": true,
          "mqtt": true,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "heltec-v4",
          "status": "supported"
        }
      ],
      "popularity": {
        "githubStars": 18,
        "githubForks": 6,
        "githubWatchers": 2,
        "githubOpenIssues": 0,
        "githubContributors": 172,
        "releaseDownloads": 3317,
        "latestReleaseDownloads": 108,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": true,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "2026.6.3",
      "released": "2026-06-09",
      "releases": [
        {
          "version": "observer-eastmesh-v2026.6.3",
          "name": "Observer EastMesh Firmware v1.16.0-eastmesh-v2026.6.3",
          "datetime": "2026-06-09T10:19:45Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-v2026.6.3",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer\r\n\r\nEastMesh `observer-eastmesh` firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware `v1.16.0`.\r\n\r\nThis release adds secure WebSocket transport support for custom MQTT brokers from the Observer web panel and CLI.\r\n\r\n### What's Changed\r\n\r\n- Added TCP/WSS transport selection for custom MQTT brokers.\r\n- Added web-panel Custom MQTT transport control for switching between TCP and WSS.\r\n- Added CLI support for viewing and setting the custom MQTT transport.\r\n- Kept custom MQTT authentication to username and password only; no JWT/web auth is used for custom brokers.\r\n- Verified custom MQTT WSS connections with the ESP-IDF x509 root CA bundle.\r\n- Fixed custom MQTT WSS to use the `/mqtt` WebSocket path.\r\n- Configured custom MQTT WSS using a full `wss://host:port/mqtt` URI so ESP-MQTT handles the WebSocket connection consistently.\r\n- Updated `get mqtt.status` to show the custom MQTT transport and state, for example `custom:wss:up`.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- `eastmesh-au` remains the recommended MQTT endpoint once `mqtt.iata` is configured.\r\n- Custom MQTT is available for private broker deployments.\r\n- For TCP custom MQTT, use the broker host and port as before.\r\n- For WSS custom MQTT, set the host and port, select WSS transport, and the firmware will connect using `wss://host:port/mqtt`.\r\n- WSS uses TLS encryption and validates against the ESP-IDF x509 root CA bundle.\r\n- For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with `set web off`.\r\n- Browsers may still require accepting the self-signed certificate warning on first HTTPS access.\r\n- `flood.max.unscoped` defaults to `64`; lower it only if you want to limit how far unscoped flood traffic repeats.\r\n- `flood.max.advert` controls the hop limit for flooded advert packets.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer</h2>\n<p>EastMesh <code>observer-eastmesh</code> firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware <code>v1.16.0</code>.</p>\n<p>This release adds secure WebSocket transport support for custom MQTT brokers from the Observer web panel and CLI.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Added TCP/WSS transport selection for custom MQTT brokers.</li>\n<li>Added web-panel Custom MQTT transport control for switching between TCP and WSS.</li>\n<li>Added CLI support for viewing and setting the custom MQTT transport.</li>\n<li>Kept custom MQTT authentication to username and password only; no JWT/web auth is used for custom brokers.</li>\n<li>Verified custom MQTT WSS connections with the ESP-IDF x509 root CA bundle.</li>\n<li>Fixed custom MQTT WSS to use the <code>/mqtt</code> WebSocket path.</li>\n<li>Configured custom MQTT WSS using a full <code>wss://host:port/mqtt</code> URI so ESP-MQTT handles the WebSocket connection consistently.</li>\n<li>Updated <code>get mqtt.status</code> to show the custom MQTT transport and state, for example <code>custom:wss:up</code>.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li><code>eastmesh-au</code> remains the recommended MQTT endpoint once <code>mqtt.iata</code> is configured.</li>\n<li>Custom MQTT is available for private broker deployments.</li>\n<li>For TCP custom MQTT, use the broker host and port as before.</li>\n<li>For WSS custom MQTT, set the host and port, select WSS transport, and the firmware will connect using <code>wss://host:port/mqtt</code>.</li>\n<li>WSS uses TLS encryption and validates against the ESP-IDF x509 root CA bundle.</li>\n<li>For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with <code>set web off</code>.</li>\n<li>Browsers may still require accepting the self-signed certificate warning on first HTTPS access.</li>\n<li><code>flood.max.unscoped</code> defaults to <code>64</code>; lower it only if you want to limit how far unscoped flood traffic repeats.</li>\n<li><code>flood.max.advert</code> controls the hop limit for flooded advert packets.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-bridge-espnow-v2026.6.3",
          "name": "Observer EastMesh Firmware with ESP-NOW Bridge v1.16.0-eastmesh-v2026.6.3",
          "datetime": "2026-06-09T10:18:22Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-bridge-espnow-v2026.6.3",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer with ESP-NOW Bridge\r\n\r\nEastMesh `observer-eastmesh-bridge-espnow` firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware `v1.16.0`.\r\n\r\nThis release includes the same Observer updates as `observer-eastmesh-v2026.6.3`, with ESP-NOW bridge support included.\r\n\r\n### What's Changed\r\n\r\n- Same changes as `observer-eastmesh-v2026.6.3`.\r\n- Includes ESP-NOW bridge firmware targets using the `*_repeater_observer_espnow` PlatformIO environment suffix.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- This track is separate from `observer-eastmesh`.\r\n- Use `get wifi.status` to confirm the active 2.4 GHz Wi-Fi channel before setting `bridge.channel`.\r\n- `bridge.channel` should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.\r\n- For maximum heap headroom after setup, disable the web panel with `set web off`.\r\n- `flood.max.advert` controls the hop limit for flooded advert packets.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer with ESP-NOW Bridge</h2>\n<p>EastMesh <code>observer-eastmesh-bridge-espnow</code> firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware <code>v1.16.0</code>.</p>\n<p>This release includes the same Observer updates as <code>observer-eastmesh-v2026.6.3</code>, with ESP-NOW bridge support included.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Same changes as <code>observer-eastmesh-v2026.6.3</code>.</li>\n<li>Includes ESP-NOW bridge firmware targets using the <code>*_repeater_observer_espnow</code> PlatformIO environment suffix.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li>This track is separate from <code>observer-eastmesh</code>.</li>\n<li>Use <code>get wifi.status</code> to confirm the active 2.4 GHz Wi-Fi channel before setting <code>bridge.channel</code>.</li>\n<li><code>bridge.channel</code> should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.</li>\n<li>For maximum heap headroom after setup, disable the web panel with <code>set web off</code>.</li>\n<li><code>flood.max.advert</code> controls the hop limit for flooded advert packets.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-v2026.6.2",
          "name": "Observer EastMesh Firmware v1.16.0-eastmesh-v2026.6.2",
          "datetime": "2026-06-07T05:03:35Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-v2026.6.2",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer\r\n\r\nEastMesh `observer-eastmesh` firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware `v1.16.0`.\r\n\r\nThis release improves Observer boot reliability, T-Beam S3 Supreme telemetry, Wi-Fi/OTA persistence, and web-panel archive maintenance.\r\n\r\n### What's Changed\r\n\r\n- Fixed LilyGo T-Beam S3 Supreme BME280 detection and live telemetry.\r\n- Added board-specific I2C recovery for T-Beam S3 Supreme BME280 reads.\r\n- Changed live `/stats` sensor values to use the main-loop sensor snapshot.\r\n- Improved boot-time Wi-Fi startup on T-Beam S3 Supreme.\r\n- Added last-connected Wi-Fi channel learning with fallback to full scan.\r\n- Added NVS-backed Wi-Fi preference recovery so SSID and password survive OTA updates even if filesystem prefs are lost.\r\n- Hardened Wi-Fi retry handling so scan-mode connects are not interrupted early.\r\n- Fixed `set wifi.powersaving none` when power saving was already disabled.\r\n- Bounded archive neighbour restore and history reads to avoid slow boots from large SD-card archive files.\r\n- Added web-panel and CLI SD purge actions for supported SD-card targets.\r\n- Hardened OTA startup by binding before reporting success and falling back to alternate ports if port 80 is still busy.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- `eastmesh-au` remains the recommended MQTT endpoint once `mqtt.iata` is configured.\r\n- Custom MQTT is available for private broker deployments.\r\n- For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with `set web off`.\r\n- Browsers may still require accepting the self-signed certificate warning on first HTTPS access.\r\n- `flood.max.unscoped` defaults to `64`; lower it only if you want to limit how far unscoped flood traffic repeats.\r\n- `flood.max.advert` controls the hop limit for flooded advert packets.\r\n- Wi-Fi credentials are now mirrored into ESP32 NVS for OTA-safe recovery.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer</h2>\n<p>EastMesh <code>observer-eastmesh</code> firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware <code>v1.16.0</code>.</p>\n<p>This release improves Observer boot reliability, T-Beam S3 Supreme telemetry, Wi-Fi/OTA persistence, and web-panel archive maintenance.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Fixed LilyGo T-Beam S3 Supreme BME280 detection and live telemetry.</li>\n<li>Added board-specific I2C recovery for T-Beam S3 Supreme BME280 reads.</li>\n<li>Changed live <code>/stats</code> sensor values to use the main-loop sensor snapshot.</li>\n<li>Improved boot-time Wi-Fi startup on T-Beam S3 Supreme.</li>\n<li>Added last-connected Wi-Fi channel learning with fallback to full scan.</li>\n<li>Added NVS-backed Wi-Fi preference recovery so SSID and password survive OTA updates even if filesystem prefs are lost.</li>\n<li>Hardened Wi-Fi retry handling so scan-mode connects are not interrupted early.</li>\n<li>Fixed <code>set wifi.powersaving none</code> when power saving was already disabled.</li>\n<li>Bounded archive neighbour restore and history reads to avoid slow boots from large SD-card archive files.</li>\n<li>Added web-panel and CLI SD purge actions for supported SD-card targets.</li>\n<li>Hardened OTA startup by binding before reporting success and falling back to alternate ports if port 80 is still busy.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li><code>eastmesh-au</code> remains the recommended MQTT endpoint once <code>mqtt.iata</code> is configured.</li>\n<li>Custom MQTT is available for private broker deployments.</li>\n<li>For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with <code>set web off</code>.</li>\n<li>Browsers may still require accepting the self-signed certificate warning on first HTTPS access.</li>\n<li><code>flood.max.unscoped</code> defaults to <code>64</code>; lower it only if you want to limit how far unscoped flood traffic repeats.</li>\n<li><code>flood.max.advert</code> controls the hop limit for flooded advert packets.</li>\n<li>Wi-Fi credentials are now mirrored into ESP32 NVS for OTA-safe recovery.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-bridge-espnow-v2026.6.2",
          "name": "Observer EastMesh Firmware with ESP-NOW Bridge v1.16.0-eastmesh-v2026.6.2",
          "datetime": "2026-06-07T05:03:22Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-bridge-espnow-v2026.6.2",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer with ESP-NOW Bridge\r\n\r\nEastMesh `observer-eastmesh-bridge-espnow` firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware `v1.16.0`.\r\n\r\nThis release includes the same Observer updates as `observer-eastmesh-v2026.6.2`, with ESP-NOW bridge support included.\r\n\r\n### What's Changed\r\n\r\n- Same changes as `observer-eastmesh-v2026.6.2`.\r\n- Includes ESP-NOW bridge firmware targets using the `*_repeater_observer_espnow` PlatformIO environment suffix.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- This track is separate from `observer-eastmesh`.\r\n- Use `get wifi.status` to confirm the active 2.4 GHz Wi-Fi channel before setting `bridge.channel`.\r\n- `bridge.channel` should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.\r\n- For maximum heap headroom after setup, disable the web panel with `set web off`.\r\n- `flood.max.advert` controls the hop limit for flooded advert packets.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer with ESP-NOW Bridge</h2>\n<p>EastMesh <code>observer-eastmesh-bridge-espnow</code> firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware <code>v1.16.0</code>.</p>\n<p>This release includes the same Observer updates as <code>observer-eastmesh-v2026.6.2</code>, with ESP-NOW bridge support included.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Same changes as <code>observer-eastmesh-v2026.6.2</code>.</li>\n<li>Includes ESP-NOW bridge firmware targets using the <code>*_repeater_observer_espnow</code> PlatformIO environment suffix.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li>This track is separate from <code>observer-eastmesh</code>.</li>\n<li>Use <code>get wifi.status</code> to confirm the active 2.4 GHz Wi-Fi channel before setting <code>bridge.channel</code>.</li>\n<li><code>bridge.channel</code> should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.</li>\n<li>For maximum heap headroom after setup, disable the web panel with <code>set web off</code>.</li>\n<li><code>flood.max.advert</code> controls the hop limit for flooded advert packets.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "repeater-bridge-espnow-v1.16.0",
          "name": "Repeater ESP-NOW Bridge Firmware v1.16.0",
          "datetime": "2026-06-06T23:20:49Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/repeater-bridge-espnow-v1.16.0",
          "prerelease": false,
          "notes": "## MeshCore Repeater ESP-NOW Bridge\r\n\r\nRepeater ESP-NOW bridge firmware built from the upstream `meshcore-dev/MeshCore` firmware base.\r\n\r\nThis release packages the existing upstream bridge functionality as EastMesh release assets.\r\n\r\n### What's Changed\r\n\r\n- Added release builds for `repeater-bridge-espnow-v*` firmware artifacts.\r\n- Kept the version aligned with upstream MeshCore `v1.16.0`.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Flashing\r\n\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore Repeater ESP-NOW Bridge</h2>\n<p>Repeater ESP-NOW bridge firmware built from the upstream <code>meshcore-dev/MeshCore</code> firmware base.</p>\n<p>This release packages the existing upstream bridge functionality as EastMesh release assets.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Added release builds for <code>repeater-bridge-espnow-v*</code> firmware artifacts.</li>\n<li>Kept the version aligned with upstream MeshCore <code>v1.16.0</code>.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-v2026.6.1",
          "name": "Observer EastMesh Firmware v1.16.0-eastmesh-v2026.6.1",
          "datetime": "2026-06-06T23:40:32Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-v2026.6.1",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer\r\n\r\nEastMesh `observer-eastmesh` firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware `v1.16.0`.\r\n\r\nThis release updates Observer firmware to upstream MeshCore `v1.16.0` with flood-advert controls, web panel refinements, and board/platform fixes.\r\n\r\n### What's Changed\r\n\r\n- Added `flood.max.advert` so flooded advert packets can use their own hop limit.\r\n- Added web panel controls for scoped and unscoped flood max values.\r\n- Improved web panel login recovery and favicon handling.\r\n- Hardened OTA startup from the local web panel by waiting for the OTA HTTP listener before redirecting.\r\n- Merged upstream MeshCore `v1.16.0` dev updates, including companion UI, board, radio, power-saving, documentation, and platform fixes.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- `eastmesh-au` remains the recommended MQTT endpoint once `mqtt.iata` is configured.\r\n- Custom MQTT is available for private broker deployments.\r\n- For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with `set web off`.\r\n- Browsers may still require accepting the self-signed certificate warning on first HTTPS access.\r\n- `flood.max.unscoped` defaults to `64`; lower it only if you want to limit how far unscoped flood traffic repeats.\r\n- `flood.max.advert` controls the hop limit for flooded advert packets.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer</h2>\n<p>EastMesh <code>observer-eastmesh</code> firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware <code>v1.16.0</code>.</p>\n<p>This release updates Observer firmware to upstream MeshCore <code>v1.16.0</code> with flood-advert controls, web panel refinements, and board/platform fixes.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Added <code>flood.max.advert</code> so flooded advert packets can use their own hop limit.</li>\n<li>Added web panel controls for scoped and unscoped flood max values.</li>\n<li>Improved web panel login recovery and favicon handling.</li>\n<li>Hardened OTA startup from the local web panel by waiting for the OTA HTTP listener before redirecting.</li>\n<li>Merged upstream MeshCore <code>v1.16.0</code> dev updates, including companion UI, board, radio, power-saving, documentation, and platform fixes.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li><code>eastmesh-au</code> remains the recommended MQTT endpoint once <code>mqtt.iata</code> is configured.</li>\n<li>Custom MQTT is available for private broker deployments.</li>\n<li>For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with <code>set web off</code>.</li>\n<li>Browsers may still require accepting the self-signed certificate warning on first HTTPS access.</li>\n<li><code>flood.max.unscoped</code> defaults to <code>64</code>; lower it only if you want to limit how far unscoped flood traffic repeats.</li>\n<li><code>flood.max.advert</code> controls the hop limit for flooded advert packets.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-bridge-espnow-v2026.6.1",
          "name": "Observer EastMesh Firmware with ESP-NOW Bridge v1.16.0-eastmesh-v2026.6.1",
          "datetime": "2026-06-06T23:40:20Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-bridge-espnow-v2026.6.1",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer with ESP-NOW Bridge\r\n\r\nEastMesh `observer-eastmesh-bridge-espnow` firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware `v1.16.0`.\r\n\r\nThis release includes the same Observer updates as `observer-eastmesh-v2026.6.1`, with ESP-NOW bridge support included.\r\n\r\n### What's Changed\r\n\r\n- Same changes as `observer-eastmesh-v2026.6.1`.\r\n- Includes ESP-NOW bridge firmware targets using the `*_repeater_observer_espnow` PlatformIO environment suffix.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- This track is separate from `observer-eastmesh`.\r\n- Use `get wifi.status` to confirm the active 2.4 GHz Wi-Fi channel before setting `bridge.channel`.\r\n- `bridge.channel` should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.\r\n- For maximum heap headroom after setup, disable the web panel with `set web off`.\r\n- `flood.max.advert` controls the hop limit for flooded advert packets.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer with ESP-NOW Bridge</h2>\n<p>EastMesh <code>observer-eastmesh-bridge-espnow</code> firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware <code>v1.16.0</code>.</p>\n<p>This release includes the same Observer updates as <code>observer-eastmesh-v2026.6.1</code>, with ESP-NOW bridge support included.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Same changes as <code>observer-eastmesh-v2026.6.1</code>.</li>\n<li>Includes ESP-NOW bridge firmware targets using the <code>*_repeater_observer_espnow</code> PlatformIO environment suffix.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li>This track is separate from <code>observer-eastmesh</code>.</li>\n<li>Use <code>get wifi.status</code> to confirm the active 2.4 GHz Wi-Fi channel before setting <code>bridge.channel</code>.</li>\n<li><code>bridge.channel</code> should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.</li>\n<li>For maximum heap headroom after setup, disable the web panel with <code>set web off</code>.</li>\n<li><code>flood.max.advert</code> controls the hop limit for flooded advert packets.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "companion-wifi-v1.16.0",
          "name": "Companion WiFi Firmware v1.16.0",
          "datetime": "2026-06-06T23:20:08Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/companion-wifi-v1.16.0",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Companion WiFi\r\n\r\nThis is standard MeshCore companion WiFi firmware based on MeshCore `v1.16.0`, with a few extra Wi-Fi setup commands added for EastMesh.\r\n\r\n### What’s Different\r\n\r\nThe only EastMesh-specific addition is a small set of Wi-Fi CLI commands that let you view and save Wi-Fi settings:\r\n\r\n- `get wifi.status`\r\n- `get wifi.ssid`\r\n- `get wifi.powersaving`\r\n- `set wifi.ssid <ssid>`\r\n- `set wifi.pwd <password>`\r\n- `set wifi.powersaving none|min|max`\r\n\r\n### Notes\r\n\r\n- Everything else behaves like the normal MeshCore companion WiFi firmware\r\n- Use the file that matches your board exactly\r\n- Companion WiFi releases use the upstream MeshCore version number\r\n\r\n### Documentation\r\n\r\nhttps://xjarid.github.io/MeshCore-EastMesh/\r\n\r\n### Flashing\r\n\r\n- https://flasher.eastmesh.au/\r\n- https://flasher.meshcore.io/\r\n\r\n### Assets\r\n\r\n- `.bin` – standard update\r\n- `-merged.bin` – full image (after erase, ESP32)",
          "notesHtml": "<h2>MeshCore EastMesh Companion WiFi</h2>\n<p>This is standard MeshCore companion WiFi firmware based on MeshCore <code>v1.16.0</code>, with a few extra Wi-Fi setup commands added for EastMesh.</p>\n<h3>What’s Different</h3>\n<p>The only EastMesh-specific addition is a small set of Wi-Fi CLI commands that let you view and save Wi-Fi settings:</p>\n<ul>\n<li><code>get wifi.status</code></li>\n<li><code>get wifi.ssid</code></li>\n<li><code>get wifi.powersaving</code></li>\n<li><code>set wifi.ssid &lt;ssid&gt;</code></li>\n<li><code>set wifi.pwd &lt;password&gt;</code></li>\n<li><code>set wifi.powersaving none|min|max</code></li>\n</ul>\n<h3>Notes</h3>\n<ul>\n<li>Everything else behaves like the normal MeshCore companion WiFi firmware</li>\n<li>Use the file that matches your board exactly</li>\n<li>Companion WiFi releases use the upstream MeshCore version number</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">https://xjarid.github.io/MeshCore-EastMesh/</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.eastmesh.au/</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> – standard update</li>\n<li><code>-merged.bin</code> – full image (after erase, ESP32)</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-v2026.6.0",
          "name": "Observer EastMesh Firmware v1.15.0-eastmesh-v2026.6.0",
          "datetime": "2026-06-03T02:49:43Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-v2026.6.0",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer\r\n\r\nEastMesh `observer-eastmesh` firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware `v1.15.0`.\r\n\r\nThis release updates Observer firmware with the latest upstream MeshCore dev changes plus EastMesh web panel, MQTT, radio, and board support fixes.\r\n\r\n### What's Changed\r\n\r\n- Added configurable custom MQTT broker support alongside the curated EastMesh and LetsMesh endpoints.\r\n- Added Station G3 ESP32 Observer firmware targets.\r\n- Added `flood.max.unscoped` so unscoped flood packets can use a separate hop limit from scoped flood traffic.\r\n- Preserved web panel sessions across Wi-Fi reconnects.\r\n- Hardened OTA startup from the local web panel and existing Wi-Fi connections.\r\n- Hardened LilyGo T-Beam 1W radio setup.\r\n- Restored the missing SX126x register patch.\r\n- Merged upstream MeshCore dev updates, including sensor handling, RAK4631 BME680/BSEC support, documentation refreshes, and board/platform fixes.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- `eastmesh-au` remains the recommended MQTT endpoint once `mqtt.iata` is configured.\r\n- Custom MQTT is available for private broker deployments.\r\n- For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with `set web off`.\r\n- Browsers may still require accepting the self-signed certificate warning on first HTTPS access.\r\n- `flood.max.unscoped` defaults to `64`; lower it only if you want to limit how far unscoped flood traffic repeats.\r\n- If using LilyGo T-Beam 1W fan controls after upgrading, re-save your preferred fan settings if needed.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer</h2>\n<p>EastMesh <code>observer-eastmesh</code> firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware <code>v1.15.0</code>.</p>\n<p>This release updates Observer firmware with the latest upstream MeshCore dev changes plus EastMesh web panel, MQTT, radio, and board support fixes.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Added configurable custom MQTT broker support alongside the curated EastMesh and LetsMesh endpoints.</li>\n<li>Added Station G3 ESP32 Observer firmware targets.</li>\n<li>Added <code>flood.max.unscoped</code> so unscoped flood packets can use a separate hop limit from scoped flood traffic.</li>\n<li>Preserved web panel sessions across Wi-Fi reconnects.</li>\n<li>Hardened OTA startup from the local web panel and existing Wi-Fi connections.</li>\n<li>Hardened LilyGo T-Beam 1W radio setup.</li>\n<li>Restored the missing SX126x register patch.</li>\n<li>Merged upstream MeshCore dev updates, including sensor handling, RAK4631 BME680/BSEC support, documentation refreshes, and board/platform fixes.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li><code>eastmesh-au</code> remains the recommended MQTT endpoint once <code>mqtt.iata</code> is configured.</li>\n<li>Custom MQTT is available for private broker deployments.</li>\n<li>For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with <code>set web off</code>.</li>\n<li>Browsers may still require accepting the self-signed certificate warning on first HTTPS access.</li>\n<li><code>flood.max.unscoped</code> defaults to <code>64</code>; lower it only if you want to limit how far unscoped flood traffic repeats.</li>\n<li>If using LilyGo T-Beam 1W fan controls after upgrading, re-save your preferred fan settings if needed.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-bridge-espnow-v2026.6.0",
          "name": "Observer EastMesh Firmware with ESP-NOW Bridge v1.15.0-eastmesh-v2026.6.0",
          "datetime": "2026-06-03T02:49:29Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-bridge-espnow-v2026.6.0",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer with ESP-NOW Bridge\r\n\r\nEastMesh `observer-eastmesh-bridge-espnow` firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware `v1.15.0`.\r\n\r\nThis release includes the same Observer updates as `observer-eastmesh-v2026.6.0`, with ESP-NOW bridge support included.\r\n\r\n### What's Changed\r\n\r\n- Same changes as `observer-eastmesh-v2026.6.0`.\r\n- Includes ESP-NOW bridge firmware targets using the `*_repeater_observer_espnow` PlatformIO environment suffix.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Notes\r\n\r\n- This track is separate from `observer-eastmesh`.\r\n- Use `get wifi.status` to confirm the active 2.4 GHz Wi-Fi channel before setting `bridge.channel`.\r\n- `bridge.channel` should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.\r\n- For maximum heap headroom after setup, disable the web panel with `set web off`.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer with ESP-NOW Bridge</h2>\n<p>EastMesh <code>observer-eastmesh-bridge-espnow</code> firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware <code>v1.15.0</code>.</p>\n<p>This release includes the same Observer updates as <code>observer-eastmesh-v2026.6.0</code>, with ESP-NOW bridge support included.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Same changes as <code>observer-eastmesh-v2026.6.0</code>.</li>\n<li>Includes ESP-NOW bridge firmware targets using the <code>*_repeater_observer_espnow</code> PlatformIO environment suffix.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Notes</h3>\n<ul>\n<li>This track is separate from <code>observer-eastmesh</code>.</li>\n<li>Use <code>get wifi.status</code> to confirm the active 2.4 GHz Wi-Fi channel before setting <code>bridge.channel</code>.</li>\n<li><code>bridge.channel</code> should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.</li>\n<li>For maximum heap headroom after setup, disable the web panel with <code>set web off</code>.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-v2026.5.1",
          "name": "Observer EastMesh Firmware v1.15.0-eastmesh-v2026.5.1",
          "datetime": "2026-05-23T11:39:54Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-v2026.5.1",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer\r\n\r\nEastMesh `observer-eastmesh` firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware `v1.15.0`.\r\n\r\nThis release renames the EastMesh MQTT observer firmware and release track, aligning release tags and PlatformIO target names with the new Observer naming.\r\n\r\n### What's Changed\r\n\r\n- Renamed the EastMesh MQTT release tag format from `repeater-mqtt-eastmesh-v*` to `observer-eastmesh-v*`.\r\n- Renamed `*_repeater_mqtt` PlatformIO environments and release artifact prefixes to `*_repeater_observer`.\r\n- Updated EastMesh release, local build, board, web panel, API, and CLI documentation to use Observer naming.\r\n\r\n### Breaking Changes\r\n\r\n- The EastMesh MQTT release tag format and PlatformIO target suffix changed to Observer naming.\r\n\r\n### Notes\r\n\r\n- `eastmesh-au` remains the recommended MQTT endpoint once `mqtt.iata` is configured.\r\n- For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with `set web off`.\r\n- Browsers may still require accepting the self-signed certificate warning on first HTTPS access.\r\n- If upgrading from a build older than `observer-eastmesh-v1.3.11`, use the web `Start OTA` button if `start ota` sends you through an odd redirect.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer</h2>\n<p>EastMesh <code>observer-eastmesh</code> firmware for MeshCore boards with secure MQTT uplink and optional local web management, based on MeshCore firmware <code>v1.15.0</code>.</p>\n<p>This release renames the EastMesh MQTT observer firmware and release track, aligning release tags and PlatformIO target names with the new Observer naming.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Renamed the EastMesh MQTT release tag format from <code>repeater-mqtt-eastmesh-v*</code> to <code>observer-eastmesh-v*</code>.</li>\n<li>Renamed <code>*_repeater_mqtt</code> PlatformIO environments and release artifact prefixes to <code>*_repeater_observer</code>.</li>\n<li>Updated EastMesh release, local build, board, web panel, API, and CLI documentation to use Observer naming.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<ul>\n<li>The EastMesh MQTT release tag format and PlatformIO target suffix changed to Observer naming.</li>\n</ul>\n<h3>Notes</h3>\n<ul>\n<li><code>eastmesh-au</code> remains the recommended MQTT endpoint once <code>mqtt.iata</code> is configured.</li>\n<li>For maximum heap headroom on busy observers, use the web panel for setup and troubleshooting, then disable it with <code>set web off</code>.</li>\n<li>Browsers may still require accepting the self-signed certificate warning on first HTTPS access.</li>\n<li>If upgrading from a build older than <code>observer-eastmesh-v1.3.11</code>, use the web <code>Start OTA</code> button if <code>start ota</code> sends you through an odd redirect.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "observer-eastmesh-bridge-espnow-v2026.5.1",
          "name": "Observer EastMesh Firmware with ESP-NOW Bridge v1.15.0-eastmesh-v2026.5.1",
          "datetime": "2026-05-23T11:39:36Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/observer-eastmesh-bridge-espnow-v2026.5.1",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Observer with ESP-NOW Bridge\r\n\r\nEastMesh `observer-eastmesh-bridge-espnow` firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware `v1.15.0`.\r\n\r\nThis release renames the EastMesh MQTT bridge observer firmware and release track, aligning release tags and PlatformIO target names with the new Observer naming.\r\n\r\n### What's Changed\r\n\r\n- Renamed the EastMesh MQTT bridge release tag format from `repeater-mqtt-bridge-eastmesh-v*` to `observer-eastmesh-bridge-espnow-v*`.\r\n- Renamed `*_repeater_mqtt_bridge` PlatformIO environments and release artifact prefixes to `*_repeater_observer_espnow`.\r\n- Updated EastMesh release, local build, board, and CLI documentation to use Observer ESP-NOW naming.\r\n\r\n### Breaking Changes\r\n\r\n- The EastMesh MQTT bridge release tag format and PlatformIO target suffix changed to Observer ESP-NOW naming.\r\n\r\n### Notes\r\n\r\n- This track is separate from `observer-eastmesh`.\r\n- Use `get wifi.status` to confirm the active 2.4 GHz Wi-Fi channel before setting `bridge.channel`.\r\n- `bridge.channel` should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.\r\n- For maximum heap headroom after setup, disable the web panel with `set web off`.\r\n\r\n### Documentation\r\n\r\n[xjarid.github.io/MeshCore-EastMesh](https://xjarid.github.io/MeshCore-EastMesh/)\r\n\r\n### Flashing\r\n\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore EastMesh Observer with ESP-NOW Bridge</h2>\n<p>EastMesh <code>observer-eastmesh-bridge-espnow</code> firmware for MeshCore boards that combine secure MQTT uplink with ESP-NOW bridge support, based on MeshCore firmware <code>v1.15.0</code>.</p>\n<p>This release renames the EastMesh MQTT bridge observer firmware and release track, aligning release tags and PlatformIO target names with the new Observer naming.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Renamed the EastMesh MQTT bridge release tag format from <code>repeater-mqtt-bridge-eastmesh-v*</code> to <code>observer-eastmesh-bridge-espnow-v*</code>.</li>\n<li>Renamed <code>*_repeater_mqtt_bridge</code> PlatformIO environments and release artifact prefixes to <code>*_repeater_observer_espnow</code>.</li>\n<li>Updated EastMesh release, local build, board, and CLI documentation to use Observer ESP-NOW naming.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<ul>\n<li>The EastMesh MQTT bridge release tag format and PlatformIO target suffix changed to Observer ESP-NOW naming.</li>\n</ul>\n<h3>Notes</h3>\n<ul>\n<li>This track is separate from <code>observer-eastmesh</code>.</li>\n<li>Use <code>get wifi.status</code> to confirm the active 2.4 GHz Wi-Fi channel before setting <code>bridge.channel</code>.</li>\n<li><code>bridge.channel</code> should match the connected Wi-Fi channel for reliable ESP-NOW bridge operation.</li>\n<li>For maximum heap headroom after setup, disable the web panel with <code>set web off</code>.</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">xjarid.github.io/MeshCore-EastMesh</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "repeater-bridge-espnow-v1.15.0",
          "name": "Repeater ESP-NOW Bridge Firmware v1.15.0",
          "datetime": "2026-05-05T23:41:38Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/repeater-bridge-espnow-v1.15.0",
          "prerelease": false,
          "notes": "## MeshCore Repeater ESP-NOW Bridge\r\n\r\nRepeater ESP-NOW bridge firmware built from the upstream `meshcore-dev/MeshCore` firmware base.\r\n\r\nThis release packages the existing upstream bridge functionality as EastMesh release assets.\r\n\r\n### What's Changed\r\n\r\n- Added release builds for `repeater-bridge-espnow-v*` firmware artifacts.\r\n- Kept the version aligned with upstream MeshCore `v1.15.0`.\r\n\r\n### Breaking Changes\r\n\r\nNone.\r\n\r\n### Flashing\r\n\r\n- [flasher.meshcore.io](https://flasher.meshcore.io/)\r\n- [flasher.eastmesh.au](https://flasher.eastmesh.au/)\r\n\r\n### Assets\r\n\r\n- `.bin` - standard update image\r\n- `-merged.bin` - full ESP32 image for flashing after erase",
          "notesHtml": "<h2>MeshCore Repeater ESP-NOW Bridge</h2>\n<p>Repeater ESP-NOW bridge firmware built from the upstream <code>meshcore-dev/MeshCore</code> firmware base.</p>\n<p>This release packages the existing upstream bridge functionality as EastMesh release assets.</p>\n<h3>What's Changed</h3>\n<ul>\n<li>Added release builds for <code>repeater-bridge-espnow-v*</code> firmware artifacts.</li>\n<li>Kept the version aligned with upstream MeshCore <code>v1.15.0</code>.</li>\n</ul>\n<h3>Breaking Changes</h3>\n<p>None.</p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.meshcore.io</a></li>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.eastmesh.au</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> - standard update image</li>\n<li><code>-merged.bin</code> - full ESP32 image for flashing after erase</li>\n</ul>\n"
        },
        {
          "version": "companion-wifi-v1.15.0",
          "name": "Companion WiFi Firmware v1.15.0",
          "datetime": "2026-04-19T02:53:50Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/companion-wifi-v1.15.0",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Companion WiFi\r\n\r\nThis is standard MeshCore companion WiFi firmware based on MeshCore `v1.15.0`, with a few extra Wi-Fi setup commands added for EastMesh.\r\n\r\n### What’s Different\r\n\r\nThe only EastMesh-specific addition is a small set of Wi-Fi CLI commands that let you view and save Wi-Fi settings:\r\n\r\n- `get wifi.status`\r\n- `get wifi.ssid`\r\n- `get wifi.powersaving`\r\n- `set wifi.ssid <ssid>`\r\n- `set wifi.pwd <password>`\r\n- `set wifi.powersaving none|min|max`\r\n\r\n### Notes\r\n\r\n- Everything else behaves like the normal MeshCore companion WiFi firmware\r\n- Use the file that matches your board exactly\r\n- Companion WiFi releases use the upstream MeshCore version number\r\n\r\n### Documentation\r\n\r\nhttps://xjarid.github.io/MeshCore-EastMesh/\r\n\r\n### Flashing\r\n\r\n- https://flasher.eastmesh.au/\r\n- https://flasher.meshcore.io/\r\n\r\n### Assets\r\n\r\n- `.bin` – standard update\r\n- `-merged.bin` – full image (after erase, ESP32)",
          "notesHtml": "<h2>MeshCore EastMesh Companion WiFi</h2>\n<p>This is standard MeshCore companion WiFi firmware based on MeshCore <code>v1.15.0</code>, with a few extra Wi-Fi setup commands added for EastMesh.</p>\n<h3>What’s Different</h3>\n<p>The only EastMesh-specific addition is a small set of Wi-Fi CLI commands that let you view and save Wi-Fi settings:</p>\n<ul>\n<li><code>get wifi.status</code></li>\n<li><code>get wifi.ssid</code></li>\n<li><code>get wifi.powersaving</code></li>\n<li><code>set wifi.ssid &lt;ssid&gt;</code></li>\n<li><code>set wifi.pwd &lt;password&gt;</code></li>\n<li><code>set wifi.powersaving none|min|max</code></li>\n</ul>\n<h3>Notes</h3>\n<ul>\n<li>Everything else behaves like the normal MeshCore companion WiFi firmware</li>\n<li>Use the file that matches your board exactly</li>\n<li>Companion WiFi releases use the upstream MeshCore version number</li>\n</ul>\n<h3>Documentation</h3>\n<p><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">https://xjarid.github.io/MeshCore-EastMesh/</a></p>\n<h3>Flashing</h3>\n<ul>\n<li><a href=\"https://flasher.eastmesh.au/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.eastmesh.au/</a></li>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> – standard update</li>\n<li><code>-merged.bin</code> – full image (after erase, ESP32)</li>\n</ul>\n"
        },
        {
          "version": "companion-wifi-v1.14.1",
          "name": "Companion WiFi Firmware v1.14.1",
          "datetime": "2026-04-09T07:16:35Z",
          "url": "https://github.com/xJARiD/MeshCore-EastMesh/releases/tag/companion-wifi-v1.14.1",
          "prerelease": false,
          "notes": "## MeshCore EastMesh Companion WiFi\r\n\r\nThis release publishes the EastMesh `companion_radio_wifi` builds for supported boards.\r\n\r\n### Highlights\r\n\r\n- WiFi-enabled companion firmware builds for EastMesh-supported MeshCore boards\r\n- Local build and release flow now standardized through `uv`\r\n- Persisted companion WiFi rescue commands added:\r\n  - `get wifi.status`\r\n  - `get wifi.ssid`\r\n  - `get wifi.powersaving`\r\n  - `set wifi.ssid <ssid>`\r\n  - `set wifi.pwd <password>`\r\n  - `set wifi.powersaving none|min|max`\r\n- EastMesh release automation and docs flow now in place\r\n\r\n### Notes\r\n\r\n- This release uses the upstream MeshCore firmware version for `FIRMWARE_VERSION`\r\n- Use the asset that matches your board exactly\r\n- For flashing custom firmware, use:\r\n  - https://flasher.meshcore.io/\r\n\r\n### Documentation\r\n\r\nTemporary docs home:\r\n- https://xjarid.github.io/MeshCore-EastMesh/\r\n\r\n### Assets\r\n\r\n- `.bin` = normal update / incremental flash\r\n- `-merged.bin` = clean flash after erase on supported ESP32 targets",
          "notesHtml": "<h2>MeshCore EastMesh Companion WiFi</h2>\n<p>This release publishes the EastMesh <code>companion_radio_wifi</code> builds for supported boards.</p>\n<h3>Highlights</h3>\n<ul>\n<li>WiFi-enabled companion firmware builds for EastMesh-supported MeshCore boards</li>\n<li>Local build and release flow now standardized through <code>uv</code></li>\n<li>Persisted companion WiFi rescue commands added:<ul>\n<li><code>get wifi.status</code></li>\n<li><code>get wifi.ssid</code></li>\n<li><code>get wifi.powersaving</code></li>\n<li><code>set wifi.ssid &lt;ssid&gt;</code></li>\n<li><code>set wifi.pwd &lt;password&gt;</code></li>\n<li><code>set wifi.powersaving none|min|max</code></li>\n</ul>\n</li>\n<li>EastMesh release automation and docs flow now in place</li>\n</ul>\n<h3>Notes</h3>\n<ul>\n<li>This release uses the upstream MeshCore firmware version for <code>FIRMWARE_VERSION</code></li>\n<li>Use the asset that matches your board exactly</li>\n<li>For flashing custom firmware, use:<ul>\n<li><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n</ul>\n</li>\n</ul>\n<h3>Documentation</h3>\n<p>Temporary docs home:</p>\n<ul>\n<li><a href=\"https://xjarid.github.io/MeshCore-EastMesh/\" target=\"_blank\" rel=\"noopener noreferrer\">https://xjarid.github.io/MeshCore-EastMesh/</a></li>\n</ul>\n<h3>Assets</h3>\n<ul>\n<li><code>.bin</code> = normal update / incremental flash</li>\n<li><code>-merged.bin</code> = clean flash after erase on supported ESP32 targets</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:28.646Z"
    },
    {
      "id": "easyskymesh",
      "name": "EasySkyMesh",
      "type": "fork",
      "maintainer": "IoTThinks",
      "description": "A power-saving oriented MeshCore firmware with experimental, advanced features and bug fixes aimed at ultra-low-power repeater and sensor deployments. Targets extended battery life (e.g. ~16µA power-off) with the intent of upstreaming improvements into MeshCore.\n",
      "repository": "https://github.com/IoTThinks/EasySkyMesh",
      "website": "https://iotthinks.com",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "repeater",
        "sensor"
      ],
      "features": [
        "Ultra-low-power operation (~16µA power-off)",
        "Sensor integration",
        "Auto-reboot / watchdog",
        "Long-range mesh messaging"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": false,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": true,
          "lowPowerRx": true
        }
      },
      "devices": [
        {
          "id": "heltec-v3",
          "status": "supported"
        },
        {
          "id": "heltec-wsl3",
          "status": "supported"
        },
        {
          "id": "heltec-v4",
          "status": "supported"
        },
        {
          "id": "heltec-v4-exp",
          "status": "supported"
        },
        {
          "id": "heltec-t096",
          "status": "supported"
        },
        {
          "id": "heltec-t114",
          "status": "supported"
        },
        {
          "id": "rak-4631",
          "status": "supported"
        },
        {
          "id": "uart-solar-node-station",
          "status": "supported"
        },
        {
          "id": "xiao-esp32s3",
          "status": "partial",
          "notes": "Power-saving figures vary by board revision."
        },
        {
          "id": "xiao-esp32c3",
          "status": "supported"
        },
        {
          "id": "xiao-nrf52",
          "status": "supported"
        }
      ],
      "popularity": {
        "githubStars": 162,
        "githubForks": 6,
        "githubWatchers": 9,
        "githubOpenIssues": 2,
        "githubContributors": 1,
        "releaseDownloads": 8018,
        "latestReleaseDownloads": 1073,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": false,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "PowerSaving16",
      "released": "2026-06-08",
      "releases": [
        {
          "version": "PowerSaving16",
          "name": "Power Saving 16: Poweroff at 16uA, T096 at 8.7mA and auto reboot",
          "datetime": "2026-06-08T14:58:49Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving16",
          "prerelease": false,
          "notes": "## Keep making 1-2W solar repeaters and 5-day BLE companions possible:\r\n- Developed by IoTThinks and tested by our supportive MeshCore friends.\r\n- Contribution to MeshCore: [By IoTThinks](https://github.com/meshcore-dev/MeshCore/issues?q=(state%3Aopen%20OR%20state%3Amerged)%20is%3Apr%20author%3A%40IoTThinks).\r\n- Source code: https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v16\r\n\r\nThe power consumption of common boards is measured at battery cable. Ping us if your boards are not low power as expected.\r\n| Board | Repeaters / Room Servers | BLE Companions | Power Off for BLE Companions |\r\n| ------------- | ------------- | ------------- | ------------- |\r\n| Heltec v3 | 9mA | 19.6mA | ~16uA |\r\n| Heltec v4.2 and v4.3 (FEM ON) | 16mA | 28.6mA | ~16uA |\r\n| Heltec v4.3 (FEM Off) | 13mA | 24.9 mA | ~16uA |\r\n| Xiao S3, C3 | 7mA | 15 mA | ~16uA |\r\n| Xiao C6 | 7mA | C6 is not supported yet | ~16uA |\r\n| RAK 4631, Heltec T114, Xiao NRF52 | 5.8mA | 5.8mA | ~16uA |\r\n| Heltec T096 (FEM Off) | 8.7mA | 8.6 mA | ~16uA |\r\n| Heltec T096 (FEM On) | 16mA | 16 mA | ~16uA |\r\n\r\n## Support Us\r\n* Enjoying our work? \r\n* Support us via [![Sponsor](https://img.shields.io/badge/Paypal-IoTThinks-0070ba?style=flat&logo=paypal&logoColor=white&labelColor=0070ba&color=555555)](https://www.paypal.com/ncp/payment/6FGWJJVC572VL) or [![Sponsor](https://img.shields.io/badge/GitHub%20Sponsors-IoTThinks-ea4aaa?style=flat&logo=github-sponsors&logoColor=white&labelColor=ea4aaa&color=555555)](https://github.com/sponsors/IoTThinks).\r\n\r\n### Known issues and Patches:\r\n- For repeaters / room servers, after upgrade to PowerSaving 16, you need to check and set the default values again `set flood.max 64` (default value) ,  `set flood.max.unscoped 64` (default value) and `set radio.fem.rxgain on/off` (Heltec v4.3 and T096 only, if you set \"off\" before) https://github.com/meshcore-dev/MeshCore/pull/2140#issuecomment-4677295983\r\n- [Fixed in v16.0.1] Wio Tracker L1 BLE companion has high power consumption is at 35mA in PowerSaving 16 instead of 7.5mA as in PowerSaving 15. This issue might affect a few NRF52 boards with GPS modules attached.\r\n\r\n### Instruction:\r\n- Scroll down to bottom to download uf2 / upgrade.bin to upgrade or freshInstall-merged.bin for new devices. \r\n- Heltec v4 bin files is for both Heltec v4.2 and v4.3. Heltec v4.3 bin files is for Heltec v4.3 only\r\n- Heltec v4.3 and T096 have two options FEM RXgain on and FEM Rxgain off.\r\n- Flash Custom Firmware as in [INSTRUCTION](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md).\r\n- If your board is not at the bottom section, please request us at [GITHUB](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas)\r\n- Fast support: [Discord](https://discord.com/channels/1472633259799220224/1472634841077121144)\r\n\r\n## Features: \r\nBased on [MeshCore 1.16](https://blog.meshcore.io/2026/06/06/release-1-16-0), plus PowerSaving features and more:\r\n- Repeaters and room servers for both ESP32 and NRF52: CLI `powersaving on`, `powersaving off `and `powersaving`\r\n- BLE companions for  both ESP32 and NRF52: Enabled by default\r\n- [NEW] Hibernate mode for ESP32 BLE Companions now work properly and at 16uA\r\n- [NEW] Optimize Heltec T096 from 12mA down to 8.7mA\r\n- [NEW] Repeaters for both ESP32 and NRF52: CLI `set reboot.interval <hours>` and `get reboot.interval`. hours is 0-255. 0 is default and disabled. This helps to recover repeaters due to unknown hang.\r\n- [NEW] Set return path for repeaters: https://github.com/meshcore-dev/MeshCore/pull/2586\r\n- [NEW] Add time keeping for NRF52 across resets: https://github.com/meshcore-dev/MeshCore/pull/2704\r\n- FEM LNA for Heltec v4.3, Heltec T096, Heltec TrackerV2: CLI `set radio.fem.rxgain on/off`  and `get radio.fem.rxgain`. https://github.com/meshcore-dev/MeshCore/pull/2140\r\n- Automatically select I2C address (0x76 or 0x77) for BME280, BME680 and BMP680.\r\n- Fixed boot loop for Xiao C6: https://github.com/meshcore-dev/MeshCore/pull/2570\r\n- Ch\n…",
          "notesHtml": "<h2>Keep making 1-2W solar repeaters and 5-day BLE companions possible:</h2>\n<ul>\n<li>Developed by IoTThinks and tested by our supportive MeshCore friends.</li>\n<li>Contribution to MeshCore: <a href=\"https://github.com/meshcore-dev/MeshCore/issues?q=(state%3Aopen%20OR%20state%3Amerged)%20is%3Apr%20author%3A%40IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\">By IoTThinks</a>.</li>\n<li>Source code: <a href=\"https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v16\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v16</a></li>\n</ul>\n<p>The power consumption of common boards is measured at battery cable. Ping us if your boards are not low power as expected.</p>\n<table>\n<thead>\n<tr>\n<th>Board</th>\n<th>Repeaters / Room Servers</th>\n<th>BLE Companions</th>\n<th>Power Off for BLE Companions</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Heltec v3</td>\n<td>9mA</td>\n<td>19.6mA</td>\n<td>~16uA</td>\n</tr>\n<tr>\n<td>Heltec v4.2 and v4.3 (FEM ON)</td>\n<td>16mA</td>\n<td>28.6mA</td>\n<td>~16uA</td>\n</tr>\n<tr>\n<td>Heltec v4.3 (FEM Off)</td>\n<td>13mA</td>\n<td>24.9 mA</td>\n<td>~16uA</td>\n</tr>\n<tr>\n<td>Xiao S3, C3</td>\n<td>7mA</td>\n<td>15 mA</td>\n<td>~16uA</td>\n</tr>\n<tr>\n<td>Xiao C6</td>\n<td>7mA</td>\n<td>C6 is not supported yet</td>\n<td>~16uA</td>\n</tr>\n<tr>\n<td>RAK 4631, Heltec T114, Xiao NRF52</td>\n<td>5.8mA</td>\n<td>5.8mA</td>\n<td>~16uA</td>\n</tr>\n<tr>\n<td>Heltec T096 (FEM Off)</td>\n<td>8.7mA</td>\n<td>8.6 mA</td>\n<td>~16uA</td>\n</tr>\n<tr>\n<td>Heltec T096 (FEM On)</td>\n<td>16mA</td>\n<td>16 mA</td>\n<td>~16uA</td>\n</tr>\n</tbody></table>\n<h2>Support Us</h2>\n<ul>\n<li>Enjoying our work? </li>\n<li>Support us via <a href=\"https://www.paypal.com/ncp/payment/6FGWJJVC572VL\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/Paypal-IoTThinks-0070ba?style=flat&amp;logo=paypal&amp;logoColor=white&amp;labelColor=0070ba&amp;color=555555\" alt=\"Sponsor\" /></a> or <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/GitHub%20Sponsors-IoTThinks-ea4aaa?style=flat&amp;logo=github-sponsors&amp;logoColor=white&amp;labelColor=ea4aaa&amp;color=555555\" alt=\"Sponsor\" /></a>.</li>\n</ul>\n<h3>Known issues and Patches:</h3>\n<ul>\n<li>For repeaters / room servers, after upgrade to PowerSaving 16, you need to check and set the default values again <code>set flood.max 64</code> (default value) ,  <code>set flood.max.unscoped 64</code> (default value) and <code>set radio.fem.rxgain on/off</code> (Heltec v4.3 and T096 only, if you set \"off\" before) <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2140#issuecomment-4677295983\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2140#issuecomment-4677295983</a></li>\n<li>[Fixed in v16.0.1] Wio Tracker L1 BLE companion has high power consumption is at 35mA in PowerSaving 16 instead of 7.5mA as in PowerSaving 15. This issue might affect a few NRF52 boards with GPS modules attached.</li>\n</ul>\n<h3>Instruction:</h3>\n<ul>\n<li>Scroll down to bottom to download uf2 / upgrade.bin to upgrade or freshInstall-merged.bin for new devices. </li>\n<li>Heltec v4 bin files is for both Heltec v4.2 and v4.3. Heltec v4.3 bin files is for Heltec v4.3 only</li>\n<li>Heltec v4.3 and T096 have two options FEM RXgain on and FEM Rxgain off.</li>\n<li>Flash Custom Firmware as in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">INSTRUCTION</a>.</li>\n<li>If your board is not at the bottom section, please request us at <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">GITHUB</a></li>\n<li>Fast support: <a href=\"https://discord.com/channels/1472633259799220224/1472634841077121144\" target=\"_blank\" rel=\"noopener noreferrer\">Discord</a></li>\n</ul>\n<h2>Features:</h2>\n<p>Based on <a href=\"https://blog.meshcore.io/2026/06/06/release-1-16-0\" target=\"_blank\" rel=\"noopener noreferrer\">MeshCore 1.16</a>, plus PowerSaving features and more:</p>\n<ul>\n<li>Repeaters and room servers for both ESP32 and NRF52: CLI <code>powersaving on</code>, <code>powersaving off </code>and <code>powersaving</code></li>\n<li>BLE companions for  both ESP32 and NRF52: Enabled by default</li>\n<li>[NEW] Hibernate mode for ESP32 BLE Companions now work properly and at 16uA</li>\n<li>[NEW] Optimize Heltec T096 from 12mA down to 8.7mA</li>\n<li>[NEW] Repeaters for both ESP32 and NRF52: CLI <code>set reboot.interval &lt;hours&gt;</code> and <code>get reboot.interval</code>. hours is 0-255. 0 is default and disabled. This helps to recover repeaters due to unknown hang.</li>\n<li>[NEW] Set return path for repeaters: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2586\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2586</a></li>\n<li>[NEW] Add time keeping for NRF52 across resets: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2704\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2704</a></li>\n<li>FEM LNA for Heltec v4.3, Heltec T096, Heltec TrackerV2: CLI <code>set radio.fem.rxgain on/off</code>  and <code>get radio.fem.rxgain</code>. <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2140\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2140</a></li>\n<li>Automatically select I2C address (0x76 or 0x77) for BME280, BME680 and BMP680.</li>\n<li>Fixed boot loop for Xiao C6: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2570\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2570</a></li>\n<li>Ch\n…</li>\n</ul>\n"
        },
        {
          "version": "PowerSaving15",
          "name": "Power Saving 15: 15mA for ESP32 BLE Companions and no time-drift for repeaters",
          "datetime": "2026-04-24T23:58:53Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving15",
          "prerelease": false,
          "notes": "## Based on MeshCore v1.15 plus the below features:\r\n* Developed by IoTThinks and tested by our supportive friends and MeshCore community.\r\n* Current Contribution to Meshcore: [By IoTThinks](https://github.com/meshcore-dev/MeshCore/issues?q=(state%3Aopen%20OR%20state%3Amerged)%20is%3Apr%20author%3A%40IoTThinks). You may feedback there to get them merged faster to MeshCore main stream.\r\n* If you want us to compile for your boards or have question, please comment in [GITHUB](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas) or [DISCORD](https://discord.com/channels/1472633259799220224/1472634841077121144)\r\n\r\nUpdates:\r\n* 15 May 2026: PS v15.0.2: Fixed boot loop due to flash mode for Xiao C6\r\n* 10 May 2026: PS v15.0.2: Fixed FEM Off version for T096 BLE companions. The external LNA was fixed to off properly to reach -115 dbm noise floor.\r\n* 04 May 2026: [BLE Companions for ESP32] PS v15.0.1: Skipped sleep when BLE read is busy and reduced sleep period from 50ms to 10ms.\r\n* 27 April 2026: [Heltec v4 repeaters and room servers] PS v15.0.1: Applied latest changes in https://github.com/meshcore-dev/MeshCore/pull/2140. Fixed missing `get radio.fem.rxgrain` and not persisted `radio.fem.rxgrain` accross reboots.\r\n\r\n## Support Us\r\n* Enjoying our work? \r\n* Support us via [![Sponsor](https://img.shields.io/badge/Paypal-IoTThinks-0070ba?style=flat&logo=paypal&logoColor=white&labelColor=0070ba&color=555555)](https://www.paypal.com/ncp/payment/6FGWJJVC572VL) or [![Sponsor](https://img.shields.io/badge/GitHub%20Sponsors-IoTThinks-ea4aaa?style=flat&logo=github-sponsors&logoColor=white&labelColor=ea4aaa&color=555555)](https://github.com/sponsors/IoTThinks).\r\n\r\n### STAR Features:\r\n- **ESP32 BLE Companions**: Officially support PowerSaving for **ALL ESP32/S3/C3** BLE Companions. Fast loading of channels and contacts. Fixed hibernation mode for Heltec v3 and v4.  ESP32C6 (including Xiao C6) is not supported yet.\r\n\r\n| Board | Power Consumption |\r\n| ------------- | ------------- |\r\n| Heltec v3 | 100 mA => 19.6 mA |\r\n| Heltec v4.2 and v4.3 (FEM ON) | 120mA => 24.9mA |\r\n| Heltec v4.3 (FEM Off) | 120mA => 18mA |\r\n| Xiao S3 | 7x mA => 16.3 mA |\r\n| Xiao C3 | 7xmA => 15.1mA |\r\n\r\n- [BETA] Repeater and room servers: **No time drift** by applying a time adjustment offset during \"`powersaving on`\"\r\n\r\n### Power Saving:\r\n* Latest Power Saving to Repeater, Room Server and BLE Companion.\r\n* One 3000mAh battery can last an ESP32 repeaters, room servers and BLE companions for a week.\r\n\r\n| Role  | NRF52 | ESP32 | CLI Commands |\r\n| ------------- | ------------- | ------------- | ------------- |\r\n| Repeater / Room Server  | 8mA => 5.8mA | 50+mA => 10-13mA  | powersaving on, powersaving off, powersaving |\r\n| BLE Companion |  12mA => 5.8mA | 120mA => 15-20mA  | Enabled by default  |\r\n\r\n### Extra Features:\r\n* Merged to add CLI control to LoRa's FEM LNA: https://github.com/meshcore-dev/MeshCore/pull/2140. CLI: `set radio.fem.rxgrain on/off` and `get radio.fem.rxgrain`\r\n* Added CLI \"**powerlog**\" to list the last reset reason, last shutdown reason (NRF52 only) and last boot voltage (NRF52 only). This is to help debugging why the boards were reset due to software fault or low voltage (brownout).\r\n* Included sensor CLI to list I2C and UART GPIOs: sensor\r\n* Merged to keep date after crash/watchdog/brownout reset on ESP32: https://github.com/meshcore-dev/MeshCore/pull/1896\r\n* Automatically selected I2C address 0x76 and 0x77 for BME280/BME680/BMP280\r\n* Added i2c probe for sensors to start only in-use sensors.\r\n* Added variant Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7 https://github.com/meshcore-dev/MeshCore/pull/2383\r\n\r\n## Instruction:\r\nPlease upgrade your **easy to access devices** first.\r\n* Download: Download **upgrade.bin** to upgrade existing devices or **freshInstall-merged.bin** for new devices.\r\n* Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\n…",
          "notesHtml": "<h2>Based on MeshCore v1.15 plus the below features:</h2>\n<ul>\n<li>Developed by IoTThinks and tested by our supportive friends and MeshCore community.</li>\n<li>Current Contribution to Meshcore: <a href=\"https://github.com/meshcore-dev/MeshCore/issues?q=(state%3Aopen%20OR%20state%3Amerged)%20is%3Apr%20author%3A%40IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\">By IoTThinks</a>. You may feedback there to get them merged faster to MeshCore main stream.</li>\n<li>If you want us to compile for your boards or have question, please comment in <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">GITHUB</a> or <a href=\"https://discord.com/channels/1472633259799220224/1472634841077121144\" target=\"_blank\" rel=\"noopener noreferrer\">DISCORD</a></li>\n</ul>\n<p>Updates:</p>\n<ul>\n<li>15 May 2026: PS v15.0.2: Fixed boot loop due to flash mode for Xiao C6</li>\n<li>10 May 2026: PS v15.0.2: Fixed FEM Off version for T096 BLE companions. The external LNA was fixed to off properly to reach -115 dbm noise floor.</li>\n<li>04 May 2026: [BLE Companions for ESP32] PS v15.0.1: Skipped sleep when BLE read is busy and reduced sleep period from 50ms to 10ms.</li>\n<li>27 April 2026: [Heltec v4 repeaters and room servers] PS v15.0.1: Applied latest changes in <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2140\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2140</a>. Fixed missing <code>get radio.fem.rxgrain</code> and not persisted <code>radio.fem.rxgrain</code> accross reboots.</li>\n</ul>\n<h2>Support Us</h2>\n<ul>\n<li>Enjoying our work? </li>\n<li>Support us via <a href=\"https://www.paypal.com/ncp/payment/6FGWJJVC572VL\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/Paypal-IoTThinks-0070ba?style=flat&amp;logo=paypal&amp;logoColor=white&amp;labelColor=0070ba&amp;color=555555\" alt=\"Sponsor\" /></a> or <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/GitHub%20Sponsors-IoTThinks-ea4aaa?style=flat&amp;logo=github-sponsors&amp;logoColor=white&amp;labelColor=ea4aaa&amp;color=555555\" alt=\"Sponsor\" /></a>.</li>\n</ul>\n<h3>STAR Features:</h3>\n<ul>\n<li><strong>ESP32 BLE Companions</strong>: Officially support PowerSaving for <strong>ALL ESP32/S3/C3</strong> BLE Companions. Fast loading of channels and contacts. Fixed hibernation mode for Heltec v3 and v4.  ESP32C6 (including Xiao C6) is not supported yet.</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Board</th>\n<th>Power Consumption</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Heltec v3</td>\n<td>100 mA =&gt; 19.6 mA</td>\n</tr>\n<tr>\n<td>Heltec v4.2 and v4.3 (FEM ON)</td>\n<td>120mA =&gt; 24.9mA</td>\n</tr>\n<tr>\n<td>Heltec v4.3 (FEM Off)</td>\n<td>120mA =&gt; 18mA</td>\n</tr>\n<tr>\n<td>Xiao S3</td>\n<td>7x mA =&gt; 16.3 mA</td>\n</tr>\n<tr>\n<td>Xiao C3</td>\n<td>7xmA =&gt; 15.1mA</td>\n</tr>\n</tbody></table>\n<ul>\n<li>[BETA] Repeater and room servers: <strong>No time drift</strong> by applying a time adjustment offset during \"<code>powersaving on</code>\"</li>\n</ul>\n<h3>Power Saving:</h3>\n<ul>\n<li>Latest Power Saving to Repeater, Room Server and BLE Companion.</li>\n<li>One 3000mAh battery can last an ESP32 repeaters, room servers and BLE companions for a week.</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Role</th>\n<th>NRF52</th>\n<th>ESP32</th>\n<th>CLI Commands</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Repeater / Room Server</td>\n<td>8mA =&gt; 5.8mA</td>\n<td>50+mA =&gt; 10-13mA</td>\n<td>powersaving on, powersaving off, powersaving</td>\n</tr>\n<tr>\n<td>BLE Companion</td>\n<td>12mA =&gt; 5.8mA</td>\n<td>120mA =&gt; 15-20mA</td>\n<td>Enabled by default</td>\n</tr>\n</tbody></table>\n<h3>Extra Features:</h3>\n<ul>\n<li>Merged to add CLI control to LoRa's FEM LNA: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2140\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2140</a>. CLI: <code>set radio.fem.rxgrain on/off</code> and <code>get radio.fem.rxgrain</code></li>\n<li>Added CLI \"<strong>powerlog</strong>\" to list the last reset reason, last shutdown reason (NRF52 only) and last boot voltage (NRF52 only). This is to help debugging why the boards were reset due to software fault or low voltage (brownout).</li>\n<li>Included sensor CLI to list I2C and UART GPIOs: sensor</li>\n<li>Merged to keep date after crash/watchdog/brownout reset on ESP32: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1896\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1896</a></li>\n<li>Automatically selected I2C address 0x76 and 0x77 for BME280/BME680/BMP280</li>\n<li>Added i2c probe for sensors to start only in-use sensors.</li>\n<li>Added variant Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7 <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2383\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2383</a></li>\n</ul>\n<h2>Instruction:</h2>\n<p>Please upgrade your <strong>easy to access devices</strong> first.</p>\n<ul>\n<li>Download: Download <strong>upgrade.bin</strong> to upgrade existing devices or <strong>freshInstall-merged.bin</strong> for new devices.</li>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a>\n…</li>\n</ul>\n"
        },
        {
          "version": "PowerSaving14.1",
          "name": "Power Saving 14.1: Heltec v4.3 at 5.5mA, FEM LNA control and powerlog",
          "datetime": "2026-03-27T12:38:20Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving14.1",
          "prerelease": false,
          "notes": "### Based on MeshCore v1.14.1 plus the below features:\r\n* 16 April 2026 -v14.1.1: Disabled NRF52_POWER_MANAGEMENT for RAK4631, RAK3401, Heltec T114, Xiao NRF52, Senscap Solar and Ga562_30s meshkit and Ga562_30s mesh tracker pro.\r\n* 10 Arpril 2026 - v14.1.1: **[BETA]** Added Power saving for Heltec v3, v4.2 and v4.3 companion BLE. Reduced from 120mA down to 32mA for Heltec v3 and 39mA for Heltec v4. LNA and FEM LNA use default settings (E.g On).\r\n* 09 April 2026 - v14.1.1: Fixed reset issue in high traffic locations for ESP32-based repeaters and room servers.\r\n\r\n#### NEW FEATURES:\r\n* Added Heltec v4.3 support: https://github.com/meshcore-dev/MeshCore/pull/1867. The PR will automatically detect Heltec v4.2 and v4.3.\r\n* Added CLI control to LoRa's FEM LNA: https://github.com/meshcore-dev/MeshCore/pull/2140. Heltec T090 is not included. The details are below.\r\n* Added CLI \"**powerlog**\" to list the last reset reason, last shutdown reason (NRF52 only) and last boot voltage (NRF52 only). This is to help debugging why the boards were reset due to software fault or low voltage (brownout).\r\n\r\nFEM LNA vs. Chip LNA:\r\n* FEM LNA is external LNA from the 1W boards (such as Heltec v4.3). You can on / off this FEM LNA: **set/get radio.fem.rxgain on/off.** This will impact the RX gain and power consumption (up to 7.8mA). When this is off, Heltec v4.3 can reach 5.8mA. For Heltec v4.2, this CLI will return \"Not supported\" as it does not support FEM control.\r\n* Chip LNA inside SX1262: This is available to all boards including 1W boards. You can on/off this LNA : **set/get radio.rxgain on/off**. This will impact the RX gain and power consumption (up to 0.5mA)\r\n \r\n#### Repeaters and Room Servers:\r\n* Included latest PowerSaving and PowerSaving CLI (powersaving, **powersaving on** and powersaving off): **5.0mA** for NRF52, 10mA for Heltec v3, 13mA for Heltec v4.2 and **5.5 mA for Heltec v4.3** (with FEM off). https://github.com/meshcore-dev/MeshCore/pull/1687\r\n\r\n #### Companions:\r\n* [NRF52] PowerSaving by default. Reduced from 9mA down to **5.8mA**. https://github.com/meshcore-dev/MeshCore/pull/2286\r\n* **[BETA]** [ESP32] PowerSaving by default for Heltec v3 and v4. Reduced from 120mA down to 32mA for Heltec v3 and 39mA for Heltec v4.2 and 4.3.\r\n\r\n#### Common features\r\n* Included sensor CLI to list I2C and UART GPIOs: sensor\r\n* Kept date after crash/watchdog/brownout reset on ESP32: https://github.com/meshcore-dev/MeshCore/pull/1896\r\n* Automatically selected I2C address 0x76 and 0x77 for BME280/BME680/BMP280\r\n* Added i2c probe for sensors to start only in-use sensors: https://github.com/meshcore-dev/MeshCore/pull/1282\r\n* Added variant Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7\r\n\r\n## Instruction:\r\nPlease upgrade your **easy to access devices** first.\r\n* Download: Download **upgrade.bin** to upgrade existing devices or **freshInstall-merged.bin** for new devices.\r\n* Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md).\r\n* Please read the instruction in [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n* Source code for [PowerSaving 14](https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v14.1)\r\n\r\n## Demo\r\n#### Power Saving\r\n* Enter powersaving mode (CLI > powersaving on),\r\n* 5.5mA for Heltec v4.3 with FEM and rxgain off, 5.8mA if FEM off and rxgain on. Thanks **Wireless Rocks** for your testing, .\r\n* 13mA for Heltec v4.2 or Heltec V4.3 with FEM and rxgain on.\r\n* 5.0mA for RAK4631\r\n\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/be6e298d-4931-4e83-8220-0d072f8aeefd\" />\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/924aa3a5-64d0-4112-aa66-6ff72178d3ac\" />\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/903d899d-66c4-4d88-bf61-e9601797009f\" />\r\n\r\n* Default PowerSaving for Heltec v3, v4.2 and\n…",
          "notesHtml": "<h3>Based on MeshCore v1.14.1 plus the below features:</h3>\n<ul>\n<li>16 April 2026 -v14.1.1: Disabled NRF52_POWER_MANAGEMENT for RAK4631, RAK3401, Heltec T114, Xiao NRF52, Senscap Solar and Ga562_30s meshkit and Ga562_30s mesh tracker pro.</li>\n<li>10 Arpril 2026 - v14.1.1: <strong>[BETA]</strong> Added Power saving for Heltec v3, v4.2 and v4.3 companion BLE. Reduced from 120mA down to 32mA for Heltec v3 and 39mA for Heltec v4. LNA and FEM LNA use default settings (E.g On).</li>\n<li>09 April 2026 - v14.1.1: Fixed reset issue in high traffic locations for ESP32-based repeaters and room servers.</li>\n</ul>\n<h4>NEW FEATURES:</h4>\n<ul>\n<li>Added Heltec v4.3 support: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1867\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1867</a>. The PR will automatically detect Heltec v4.2 and v4.3.</li>\n<li>Added CLI control to LoRa's FEM LNA: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2140\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2140</a>. Heltec T090 is not included. The details are below.</li>\n<li>Added CLI \"<strong>powerlog</strong>\" to list the last reset reason, last shutdown reason (NRF52 only) and last boot voltage (NRF52 only). This is to help debugging why the boards were reset due to software fault or low voltage (brownout).</li>\n</ul>\n<p>FEM LNA vs. Chip LNA:</p>\n<ul>\n<li>FEM LNA is external LNA from the 1W boards (such as Heltec v4.3). You can on / off this FEM LNA: <strong>set/get radio.fem.rxgain on/off.</strong> This will impact the RX gain and power consumption (up to 7.8mA). When this is off, Heltec v4.3 can reach 5.8mA. For Heltec v4.2, this CLI will return \"Not supported\" as it does not support FEM control.</li>\n<li>Chip LNA inside SX1262: This is available to all boards including 1W boards. You can on/off this LNA : <strong>set/get radio.rxgain on/off</strong>. This will impact the RX gain and power consumption (up to 0.5mA)</li>\n</ul>\n<h4>Repeaters and Room Servers:</h4>\n<ul>\n<li>Included latest PowerSaving and PowerSaving CLI (powersaving, <strong>powersaving on</strong> and powersaving off): <strong>5.0mA</strong> for NRF52, 10mA for Heltec v3, 13mA for Heltec v4.2 and <strong>5.5 mA for Heltec v4.3</strong> (with FEM off). <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1687\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1687</a></li>\n</ul>\n<h4>Companions:</h4>\n<ul>\n<li>[NRF52] PowerSaving by default. Reduced from 9mA down to <strong>5.8mA</strong>. <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2286\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/2286</a></li>\n<li><strong>[BETA]</strong> [ESP32] PowerSaving by default for Heltec v3 and v4. Reduced from 120mA down to 32mA for Heltec v3 and 39mA for Heltec v4.2 and 4.3.</li>\n</ul>\n<h4>Common features</h4>\n<ul>\n<li>Included sensor CLI to list I2C and UART GPIOs: sensor</li>\n<li>Kept date after crash/watchdog/brownout reset on ESP32: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1896\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1896</a></li>\n<li>Automatically selected I2C address 0x76 and 0x77 for BME280/BME680/BMP280</li>\n<li>Added i2c probe for sensors to start only in-use sensors: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1282\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1282</a></li>\n<li>Added variant Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7</li>\n</ul>\n<h2>Instruction:</h2>\n<p>Please upgrade your <strong>easy to access devices</strong> first.</p>\n<ul>\n<li>Download: Download <strong>upgrade.bin</strong> to upgrade existing devices or <strong>freshInstall-merged.bin</strong> for new devices.</li>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a>.</li>\n<li>Please read the instruction in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n<li>Source code for <a href=\"https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v14.1\" target=\"_blank\" rel=\"noopener noreferrer\">PowerSaving 14</a></li>\n</ul>\n<h2>Demo</h2>\n<h4>Power Saving</h4>\n<ul>\n<li>Enter powersaving mode (CLI &gt; powersaving on),</li>\n<li>5.5mA for Heltec v4.3 with FEM and rxgain off, 5.8mA if FEM off and rxgain on. Thanks <strong>Wireless Rocks</strong> for your testing, .</li>\n<li>13mA for Heltec v4.2 or Heltec V4.3 with FEM and rxgain on.</li>\n<li>5.0mA for RAK4631</li>\n</ul>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/be6e298d-4931-4e83-8220-0d072f8aeefd\" />\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/924aa3a5-64d0-4112-aa66-6ff72178d3ac\" />\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/903d899d-66c4-4d88-bf61-e9601797009f\" /><ul>\n<li>Default PowerSaving for Heltec v3, v4.2 and\n…</li>\n</ul>\n"
        },
        {
          "version": "PowerSaving14",
          "name": "Power Saving 14: Bringing PowerSaving to Room Servers and Companions",
          "datetime": "2026-03-13T09:01:28Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving14",
          "prerelease": false,
          "notes": "## Based on MeshCore v1.14 plus the below features and bug fixes:\r\n\r\n## Repeater:\r\n+ Included latest PowerSaving and PowerSaving CLI (powersaving, powersaving on and powersaving off): 5.8mA for NRF52, 10mA for Heltec v3 and 13mA for Heltec v4. https://github.com/meshcore-dev/MeshCore/pull/1687\r\n+ [COMING SOON] Modbus RS485 support is coming soon...\r\n\r\n## Room server:\r\n+ Added latest PowerSaving and PowerSaving CLI (powersaving, powersaving on and powersaving off): 5.8mA for NRF52, 10mA for Heltec v3 and 13mA for Heltec v4.\r\n+ Added MCU temperature\r\n\r\n## Companion:\r\n+ [NRF52] Added PowerSaving. Reduced from 9mA down to 5.8mA.\r\n+ [ESP32] PowerSaving is coming soon...\r\n\r\n## Common:\r\n+ Included sensor CLI to list I2C and UART GPIOs: sensor\r\n+ Kept date after crash/watchdog/brownout reset on ESP32: https://github.com/meshcore-dev/MeshCore/pull/1896\r\n+ Fixed hasPendingWork for TX queue: https://github.com/meshcore-dev/MeshCore/pull/1877\r\n+ Automatically selected I2C address 0x76 and 0x77 for BME280/BME680/BMP280\r\n+ Added i2c probe for sensors to start only in-use sensors: https://github.com/meshcore-dev/MeshCore/pull/1282\r\n+ Added variant Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7\r\n\r\n## Instruction:\r\nPlease upgrade your **easy to access repeaters / room servers** first.\r\n* Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\r\n* Please read the instruction in [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n* Source code for [PowerSaving 14](https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v14)\r\n\r\n## Support and Discussion\r\n* If you want us to compile for your boards or have question, please comment in [GITHUB](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas) or [DISCORD](https://discord.com/channels/1472633259799220224/1472634841077121144)\r\n\r\n## Love the build?\r\n* You may buy us a cofee ☕ for good work via Paypal [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-iotthinks-0070ba?style=flat&logo=paypal&logoColor=white&labelColor=0070ba&color=555555)](https://www.paypal.com/paypalme/iotthinks/9usd) or Github [![Sponsor](https://img.shields.io/badge/Sponsor-iotthinks-ea4aaa?style=flat&logo=github-sponsors&logoColor=white&labelColor=ea4aaa&color=555555)](https://github.com/sponsors/IoTThinks).\r\nWe can buy more test boards and test sensors for development.\r\n\r\n## Demo\r\n* Enter powersaving mode (CLI > powersaving on), 5.8mA for RAK4631 / Xiao NRF52, 6mA for Xiao S6/C3/C6, 10mA for Heltec v3, 13mA for Heltec v4...\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/81b6e215-046b-4349-a372-0f2da4c61cf9\" />\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/89e811fd-cc87-46e2-8b8b-c239363b3fb5\" />\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/45624e7e-0a30-4e1b-ba58-5484f0532ace\" />\r\n\r\n* Enter CLI \"powersaving\", \"powersaving on\" and \"powersaving off\" with detailed responses\r\n* Enter CLI \"sensor\" to check I2C and GPS Serial pins\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/060dd847-5984-4dc2-a5fe-cfe81180dc6c\" /> \r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/49f25de7-a122-480f-a54a-a7176ec25f26\" />",
          "notesHtml": "<h2>Based on MeshCore v1.14 plus the below features and bug fixes:</h2>\n<h2>Repeater:</h2>\n<ul>\n<li>Included latest PowerSaving and PowerSaving CLI (powersaving, powersaving on and powersaving off): 5.8mA for NRF52, 10mA for Heltec v3 and 13mA for Heltec v4. <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1687\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1687</a></li>\n<li>[COMING SOON] Modbus RS485 support is coming soon...</li>\n</ul>\n<h2>Room server:</h2>\n<ul>\n<li>Added latest PowerSaving and PowerSaving CLI (powersaving, powersaving on and powersaving off): 5.8mA for NRF52, 10mA for Heltec v3 and 13mA for Heltec v4.</li>\n<li>Added MCU temperature</li>\n</ul>\n<h2>Companion:</h2>\n<ul>\n<li>[NRF52] Added PowerSaving. Reduced from 9mA down to 5.8mA.</li>\n<li>[ESP32] PowerSaving is coming soon...</li>\n</ul>\n<h2>Common:</h2>\n<ul>\n<li>Included sensor CLI to list I2C and UART GPIOs: sensor</li>\n<li>Kept date after crash/watchdog/brownout reset on ESP32: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1896\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1896</a></li>\n<li>Fixed hasPendingWork for TX queue: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1877\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1877</a></li>\n<li>Automatically selected I2C address 0x76 and 0x77 for BME280/BME680/BMP280</li>\n<li>Added i2c probe for sensors to start only in-use sensors: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1282\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1282</a></li>\n<li>Added variant Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7</li>\n</ul>\n<h2>Instruction:</h2>\n<p>Please upgrade your <strong>easy to access repeaters / room servers</strong> first.</p>\n<ul>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a></li>\n<li>Please read the instruction in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n<li>Source code for <a href=\"https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v14\" target=\"_blank\" rel=\"noopener noreferrer\">PowerSaving 14</a></li>\n</ul>\n<h2>Support and Discussion</h2>\n<ul>\n<li>If you want us to compile for your boards or have question, please comment in <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">GITHUB</a> or <a href=\"https://discord.com/channels/1472633259799220224/1472634841077121144\" target=\"_blank\" rel=\"noopener noreferrer\">DISCORD</a></li>\n</ul>\n<h2>Love the build?</h2>\n<ul>\n<li>You may buy us a cofee ☕ for good work via Paypal <a href=\"https://www.paypal.com/paypalme/iotthinks/9usd\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/Buy%20me%20a%20coffee-iotthinks-0070ba?style=flat&amp;logo=paypal&amp;logoColor=white&amp;labelColor=0070ba&amp;color=555555\" alt=\"Buy me a coffee\" /></a> or Github <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/Sponsor-iotthinks-ea4aaa?style=flat&amp;logo=github-sponsors&amp;logoColor=white&amp;labelColor=ea4aaa&amp;color=555555\" alt=\"Sponsor\" /></a>.\nWe can buy more test boards and test sensors for development.</li>\n</ul>\n<h2>Demo</h2>\n<ul>\n<li>Enter powersaving mode (CLI &gt; powersaving on), 5.8mA for RAK4631 / Xiao NRF52, 6mA for Xiao S6/C3/C6, 10mA for Heltec v3, 13mA for Heltec v4...</li>\n</ul>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/81b6e215-046b-4349-a372-0f2da4c61cf9\" />\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/89e811fd-cc87-46e2-8b8b-c239363b3fb5\" />\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/45624e7e-0a30-4e1b-ba58-5484f0532ace\" /><ul>\n<li>Enter CLI \"powersaving\", \"powersaving on\" and \"powersaving off\" with detailed responses</li>\n<li>Enter CLI \"sensor\" to check I2C and GPS Serial pins</li>\n</ul>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/060dd847-5984-4dc2-a5fe-cfe81180dc6c\" /> \n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/49f25de7-a122-480f-a54a-a7176ec25f26\" />"
        },
        {
          "version": "PowerSaving13.1",
          "name": "[BETA] Power Saving 13.1: More experiemental features",
          "datetime": "2026-02-28T04:17:35Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving13.1",
          "prerelease": true,
          "notes": "## Power Saving 13 plus the below features:\r\nBased on stable main MeshCore v1.13:\r\n* 28 Feb 2026 - Added \"fix agc reset on SX126x, SX1276 & LR11x0 chips\": [PR 1743](https://github.com/meshcore-dev/MeshCore/pull/1743) by [weebl2000](https://github.com/weebl2000). This is to fix stuck noise floor at -120 dBm.\r\n* 04 Mar 2026 - Added \"Fix 1970 date after crash/watchdog/brownout reset on ESP32\":  [PR 1896](https://github.com/meshcore-dev/MeshCore/pull/1896) by  [weebl2000](https://github.com/weebl2000). This is to keep the time after crash/watchdog/brownout reset on ESP32-based repeaters.\r\n\r\nSource code:\r\n* https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v13.1",
          "notesHtml": "<h2>Power Saving 13 plus the below features:</h2>\n<p>Based on stable main MeshCore v1.13:</p>\n<ul>\n<li>28 Feb 2026 - Added \"fix agc reset on SX126x, SX1276 &amp; LR11x0 chips\": <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1743\" target=\"_blank\" rel=\"noopener noreferrer\">PR 1743</a> by <a href=\"https://github.com/weebl2000\" target=\"_blank\" rel=\"noopener noreferrer\">weebl2000</a>. This is to fix stuck noise floor at -120 dBm.</li>\n<li>04 Mar 2026 - Added \"Fix 1970 date after crash/watchdog/brownout reset on ESP32\":  <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1896\" target=\"_blank\" rel=\"noopener noreferrer\">PR 1896</a> by  <a href=\"https://github.com/weebl2000\" target=\"_blank\" rel=\"noopener noreferrer\">weebl2000</a>. This is to keep the time after crash/watchdog/brownout reset on ESP32-based repeaters.</li>\n</ul>\n<p>Source code:</p>\n<ul>\n<li><a href=\"https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v13.1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v13.1</a></li>\n</ul>\n"
        },
        {
          "version": "PowerSaving13",
          "name": "Power Saving 13 - More power saving support, sensor support, hot fixes and variant support",
          "datetime": "2026-02-21T05:39:09Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving13",
          "prerelease": false,
          "notes": "## MeshCore v1.13 plus latest PowerSaving and more features:\r\n#### 1. More Power Saving support [Repeater] :\r\n* CLI: powersaving, powersaving on and powersaving off with detailed messages: https://github.com/meshcore-dev/MeshCore/pull/1687\r\n* PowerSaving for ALL ESP32-based (ESP32S3/C3/C6 and SX1276/sx1262) repeaters: Sleep after 2 minutes from boot. Wakeup on LoRa messages and sleep IMMEDIATELY. Reduced time drift (5 minutes/day to 1 minute/day) for ALL ESP32 repeaters. \r\n* Power Saving for NRF52 at 5.5mA in MeshCore v1.13 is from another contributor: Wakeup on LoRa messages and sleep immediately.\r\n\r\n#### 2. More sensor support [Repeater]:\r\n* [Heltec v4] Fixed broken I2C sensors (BME, INA sensors...) for Heltec v4: https://github.com/meshcore-dev/MeshCore/pull/1569\r\n* Automatically selected I2C addresses 0x76 or 0x77 for BME280, BMP280 and BME680. Just plug the sensors to the VCC, GND, SDA and SCL.\r\n* Added i2c probe for sensors to start only in-use sensors: https://github.com/meshcore-dev/MeshCore/pull/1282\r\n\r\n#### 3. Hot fixes [Repeater/Companion]:\r\n* [RAK4631 / Heltec T114 / Xiao NRF52] Reduced voltage boot lock from 3.3v to 1.8v in NRF52 power management. This is useful for devices with non-Lipo batteries: https://github.com/meshcore-dev/MeshCore/issues/1629\r\n* Automatically restart after flash for Heltec v4 (CDC support): https://github.com/meshcore-dev/MeshCore/pull/1335\r\n\r\n#### 4. More variant support [Repeater/Companion]\r\n* Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7\r\n* Xiao C3 (Latest support): SDA=D6, SCL=D7\r\n* Xiao C6 (Latest support): SDA=D6, SCL=D7\r\n\r\n## Instruction:\r\nPlease upgrade your easy to access repeaters first.\r\n* Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\r\n* Please read the instruction in [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n* Source code for [PowerSaving 13](https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v13)\r\n\r\n## Support\r\n* You may buy us a cofee ☕ for good work via Paypal [![Buy me a coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-iotthinks-0070ba?style=flat&logo=paypal&logoColor=white&labelColor=0070ba&color=555555)](https://www.paypal.com/paypalme/iotthinks/9usd) or Github [![Sponsor](https://img.shields.io/badge/Sponsor-iotthinks-ea4aaa?style=flat&logo=github-sponsors&logoColor=white&labelColor=ea4aaa&color=555555)](https://github.com/sponsors/IoTThinks)\r\n* If you want us to compile for your boards or have question, please comment in [IDEAS](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas)\r\n\r\n## Demo\r\n* Enter powersaving mode (CLI > powersaving on), 5.8mA for RAK4631 / Xiao NRF52, 6mA for Xiao S6/C3/C6, 10mA for Heltec v3, 13mA for Heltec v4...\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/81b6e215-046b-4349-a372-0f2da4c61cf9\" />\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/89e811fd-cc87-46e2-8b8b-c239363b3fb5\" />\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/45624e7e-0a30-4e1b-ba58-5484f0532ace\" />\r\n\r\n* Enter CLI \"powersaving\", \"powersaving on\" and \"powersaving off\" with detailed responses\r\n* Enter CLI \"sensor\" to check I2C and GPS Serial pins\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/060dd847-5984-4dc2-a5fe-cfe81180dc6c\" /> \r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/49f25de7-a122-480f-a54a-a7176ec25f26\" />\r\n\r\n* Telemetry works properly for Heltec v4 when OLED is off\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/2dd82658-1d01-4727-aa44-2c1864dd2e64\" />\r\n\r\n* RAK4631 / Heltec T114 / Xiao NRF52 works at lower voltage lock. Boot lock is reduced from 3.3v to 1.8v,\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9fdfedea-c5b9-4b42-8fa6-4cf\n…",
          "notesHtml": "<h2>MeshCore v1.13 plus latest PowerSaving and more features:</h2>\n<h4>1. More Power Saving support [Repeater] :</h4>\n<ul>\n<li>CLI: powersaving, powersaving on and powersaving off with detailed messages: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1687\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1687</a></li>\n<li>PowerSaving for ALL ESP32-based (ESP32S3/C3/C6 and SX1276/sx1262) repeaters: Sleep after 2 minutes from boot. Wakeup on LoRa messages and sleep IMMEDIATELY. Reduced time drift (5 minutes/day to 1 minute/day) for ALL ESP32 repeaters. </li>\n<li>Power Saving for NRF52 at 5.5mA in MeshCore v1.13 is from another contributor: Wakeup on LoRa messages and sleep immediately.</li>\n</ul>\n<h4>2. More sensor support [Repeater]:</h4>\n<ul>\n<li>[Heltec v4] Fixed broken I2C sensors (BME, INA sensors...) for Heltec v4: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1569\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1569</a></li>\n<li>Automatically selected I2C addresses 0x76 or 0x77 for BME280, BMP280 and BME680. Just plug the sensors to the VCC, GND, SDA and SCL.</li>\n<li>Added i2c probe for sensors to start only in-use sensors: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1282\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1282</a></li>\n</ul>\n<h4>3. Hot fixes [Repeater/Companion]:</h4>\n<ul>\n<li>[RAK4631 / Heltec T114 / Xiao NRF52] Reduced voltage boot lock from 3.3v to 1.8v in NRF52 power management. This is useful for devices with non-Lipo batteries: <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1629\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/issues/1629</a></li>\n<li>Automatically restart after flash for Heltec v4 (CDC support): <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1335\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/meshcore-dev/MeshCore/pull/1335</a></li>\n</ul>\n<h4>4. More variant support [Repeater/Companion]</h4>\n<ul>\n<li>Xiao S3 (non-Wio) and Wio SX1262 (Initial support): SDA=D6, SCL=D7</li>\n<li>Xiao C3 (Latest support): SDA=D6, SCL=D7</li>\n<li>Xiao C6 (Latest support): SDA=D6, SCL=D7</li>\n</ul>\n<h2>Instruction:</h2>\n<p>Please upgrade your easy to access repeaters first.</p>\n<ul>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a></li>\n<li>Please read the instruction in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n<li>Source code for <a href=\"https://github.com/IoTThinks/MeshCore/tree/PowerSaving-v13\" target=\"_blank\" rel=\"noopener noreferrer\">PowerSaving 13</a></li>\n</ul>\n<h2>Support</h2>\n<ul>\n<li>You may buy us a cofee ☕ for good work via Paypal <a href=\"https://www.paypal.com/paypalme/iotthinks/9usd\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/Buy%20me%20a%20coffee-iotthinks-0070ba?style=flat&amp;logo=paypal&amp;logoColor=white&amp;labelColor=0070ba&amp;color=555555\" alt=\"Buy me a coffee\" /></a> or Github <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\"><img src=\"https://img.shields.io/badge/Sponsor-iotthinks-ea4aaa?style=flat&amp;logo=github-sponsors&amp;logoColor=white&amp;labelColor=ea4aaa&amp;color=555555\" alt=\"Sponsor\" /></a></li>\n<li>If you want us to compile for your boards or have question, please comment in <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">IDEAS</a></li>\n</ul>\n<h2>Demo</h2>\n<ul>\n<li>Enter powersaving mode (CLI &gt; powersaving on), 5.8mA for RAK4631 / Xiao NRF52, 6mA for Xiao S6/C3/C6, 10mA for Heltec v3, 13mA for Heltec v4...</li>\n</ul>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/81b6e215-046b-4349-a372-0f2da4c61cf9\" />\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/89e811fd-cc87-46e2-8b8b-c239363b3fb5\" />\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/45624e7e-0a30-4e1b-ba58-5484f0532ace\" /><ul>\n<li>Enter CLI \"powersaving\", \"powersaving on\" and \"powersaving off\" with detailed responses</li>\n<li>Enter CLI \"sensor\" to check I2C and GPS Serial pins</li>\n</ul>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/060dd847-5984-4dc2-a5fe-cfe81180dc6c\" /> \n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/49f25de7-a122-480f-a54a-a7176ec25f26\" /><ul>\n<li>Telemetry works properly for Heltec v4 when OLED is off</li>\n</ul>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/2dd82658-1d01-4727-aa44-2c1864dd2e64\" /><ul>\n<li>RAK4631 / Heltec T114 / Xiao NRF52 works at lower voltage lock. Boot lock is reduced from 3.3v to 1.8v,\n&lt;img height=\"384\" alt=\"image\" src=\"<a href=\"https://github.com/user-attachments/assets/9fdfedea-c5b9-4b42-8fa6-4cf\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/user-attachments/assets/9fdfedea-c5b9-4b42-8fa6-4cf</a>\n…</li>\n</ul>\n"
        },
        {
          "version": "PowerSaving11",
          "name": "Power Saving 11 - 6mA power consumption for ALL NRF52-based repeaters and 10mA power consumption for ALL ESP32-based repeaters",
          "datetime": "2026-01-07T15:49:04Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving11",
          "prerelease": false,
          "notes": "This is for all NRF52-based repeaters and ESP32-based repeaters: **6mA** power consumption for ALL NRF52-based repeaters and **10mA** power consumption for ALL ESP32-based repeaters\r\n- [Production] For ESP32-based repeaters, the firmware is very stable and in production. We will improve the timedrift for ESP32-based repeaters in the next version.\r\n- [**Beta**] For NRF52-based repeaters, the firmware is newly released. Please test it a while with easy to access repeaters.\r\n- We will push this PowerSaving version to MeshCore github within 7 days. Usually, we will listen for your feedback before we push to MeshCore github.\r\n\r\nNRF52-based repeater at **6mA** and ESP32-based repeater at **10mA**\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/8c5ea995-3af2-4b22-b5c7-9af68a4127a3\" /> <img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/194442e6-3228-4df4-a060-07de34bd651d\" />\r\n\r\n**IMPORTANT:** \r\n- On CLI, you need to type \"**powersaving on**\" ONCE to achieve 10mA power consumption. The setting will persist even after reboot.\r\n- Powersaving (if enabled) will start 2 minutes since boot.\r\n- If you enable OTA via `start ota` in CLI, then powersaving will have no effect.\r\n\r\n**New features:**\r\n- Improved PowerSaving for ALL NRF52-based repeaters from 8.5mA down to 6mA. Initially, NRF52 consumes 12mA down to 8.5mA (PowerSaving 9+) and now 6mA (PowerSaving 11).\r\n\r\n**Instruction:** \r\n- Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\r\n- Please read the instruction in [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n\r\n**Videos:**\r\nThis is a RAK4631 repeater with PowerSaving in action: Sleep at 6mA, wakeup when a LoRa packet comes, process it, wake up for 5s and go to sleep again.\r\n\r\nhttps://github.com/user-attachments/assets/fbb698ce-f551-4900-bf2b-1c9945d6f3a4\r\n\r\nPing us if you want us to compile for your boards [HERE](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas)\r\nYou may want to buy us [a coffee](https://github.com/sponsors/IoTThinks) &#x2615;  for good work.\r\nEnjoy.",
          "notesHtml": "<p>This is for all NRF52-based repeaters and ESP32-based repeaters: <strong>6mA</strong> power consumption for ALL NRF52-based repeaters and <strong>10mA</strong> power consumption for ALL ESP32-based repeaters</p>\n<ul>\n<li>[Production] For ESP32-based repeaters, the firmware is very stable and in production. We will improve the timedrift for ESP32-based repeaters in the next version.</li>\n<li>[<strong>Beta</strong>] For NRF52-based repeaters, the firmware is newly released. Please test it a while with easy to access repeaters.</li>\n<li>We will push this PowerSaving version to MeshCore github within 7 days. Usually, we will listen for your feedback before we push to MeshCore github.</li>\n</ul>\n<p>NRF52-based repeater at <strong>6mA</strong> and ESP32-based repeater at <strong>10mA</strong>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/8c5ea995-3af2-4b22-b5c7-9af68a4127a3\" /> <img alt=\"image\" src=\"https://github.com/user-attachments/assets/194442e6-3228-4df4-a060-07de34bd651d\" /></p>\n<p><strong>IMPORTANT:</strong> </p>\n<ul>\n<li>On CLI, you need to type \"<strong>powersaving on</strong>\" ONCE to achieve 10mA power consumption. The setting will persist even after reboot.</li>\n<li>Powersaving (if enabled) will start 2 minutes since boot.</li>\n<li>If you enable OTA via <code>start ota</code> in CLI, then powersaving will have no effect.</li>\n</ul>\n<p><strong>New features:</strong></p>\n<ul>\n<li>Improved PowerSaving for ALL NRF52-based repeaters from 8.5mA down to 6mA. Initially, NRF52 consumes 12mA down to 8.5mA (PowerSaving 9+) and now 6mA (PowerSaving 11).</li>\n</ul>\n<p><strong>Instruction:</strong> </p>\n<ul>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a></li>\n<li>Please read the instruction in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n</ul>\n<p><strong>Videos:</strong>\nThis is a RAK4631 repeater with PowerSaving in action: Sleep at 6mA, wakeup when a LoRa packet comes, process it, wake up for 5s and go to sleep again.</p>\n<p><a href=\"https://github.com/user-attachments/assets/fbb698ce-f551-4900-bf2b-1c9945d6f3a4\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/user-attachments/assets/fbb698ce-f551-4900-bf2b-1c9945d6f3a4</a></p>\n<p>Ping us if you want us to compile for your boards <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">HERE</a>\nYou may want to buy us <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\">a coffee</a> ☕  for good work.\nEnjoy.</p>\n"
        },
        {
          "version": "PowerSaving10",
          "name": "Power Saving 10 - 10mA power consumption for ALL ESP32-based repeaters",
          "datetime": "2026-01-02T15:40:28Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving10",
          "prerelease": false,
          "notes": "If your ESP32 boards have not had power saving yet, you could use this PowerSaving 10 to achieve 10mA.\r\nElse you may stay with PowerSaving 09.\r\n\r\nHOT_FIXES - 06 JAN 2026: v10.1\r\n- Hot-fixes for old boards with SX1276: To wake up on DIO0 (instead of DIO1) for Heltec v2, LilyGo_T3S3_sx1276, LilyGo_TLora_V2_1_1_6 and Tbeam_SX1276. Known issue: Deepsleep is only working for SX1262, however it is not in scope of the powersaving.\r\n- Hot-fixes for TBeam boards: To fix TBeam boards to separate boards with SX1262 and SX1276.\r\n\r\nIMPORTANT: \r\n- On CLI, you need to type \"**powersaving on**\" ONCE to achieve 10mA power consumption. The setting will persist even after reboot.\r\n- Powersaving (if enabled) will start 2 minutes since boot.\r\n\r\nNew features:\r\n- Supports PowerSaving for ALL ESP32-based repeaters\r\n\r\nExisting features:\r\n- PowerSaving for RTC-DIO1 boards: 9mA for Heltec v2, v3, v4, WSL3, TBeam... since PowerSaving 07\r\n- PowerSaving for NRF52 boards: 8.5mA for RAK4631, Heltec T114, Xiao-NRF52 and T-Echo/T-Echo Lite... since PowerSaving 07\r\n- PowerSaving CLI: \"powersaving\" to check status, \"powersaving on\" and \"powersaving off\". \r\n- Built-in temperature in telemetry for ESP32S3 and NRF52 repeaters.\r\n- Fixed BME280 and BME680 for all boards.\r\n- Added force clock sync in CLI \"clock fsync\"\r\n- Fixed measurement of battery voltage for T-Echo lite\r\n\r\nInstruction: \r\n- Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\r\n- Please read the instruction in [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n\r\nHeltec v3, RAK4631 and simulated Xiao Wio S3 (by Heltec v3)\r\n\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/4bf662cc-d289-4b1a-8799-df618ff703f5\" />\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/10a9fd6a-d915-46ee-ac5a-0363e69373ab\" /> \r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/194442e6-3228-4df4-a060-07de34bd651d\" />\r\n\r\nPing us if you want us to compile for your boards [HERE](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas)\r\nYou may want to buy us [a coffee](https://github.com/sponsors/IoTThinks) &#x2615;  for good work.\r\nEnjoy.",
          "notesHtml": "<p>If your ESP32 boards have not had power saving yet, you could use this PowerSaving 10 to achieve 10mA.\nElse you may stay with PowerSaving 09.</p>\n<p>HOT_FIXES - 06 JAN 2026: v10.1</p>\n<ul>\n<li>Hot-fixes for old boards with SX1276: To wake up on DIO0 (instead of DIO1) for Heltec v2, LilyGo_T3S3_sx1276, LilyGo_TLora_V2_1_1_6 and Tbeam_SX1276. Known issue: Deepsleep is only working for SX1262, however it is not in scope of the powersaving.</li>\n<li>Hot-fixes for TBeam boards: To fix TBeam boards to separate boards with SX1262 and SX1276.</li>\n</ul>\n<p>IMPORTANT: </p>\n<ul>\n<li>On CLI, you need to type \"<strong>powersaving on</strong>\" ONCE to achieve 10mA power consumption. The setting will persist even after reboot.</li>\n<li>Powersaving (if enabled) will start 2 minutes since boot.</li>\n</ul>\n<p>New features:</p>\n<ul>\n<li>Supports PowerSaving for ALL ESP32-based repeaters</li>\n</ul>\n<p>Existing features:</p>\n<ul>\n<li>PowerSaving for RTC-DIO1 boards: 9mA for Heltec v2, v3, v4, WSL3, TBeam... since PowerSaving 07</li>\n<li>PowerSaving for NRF52 boards: 8.5mA for RAK4631, Heltec T114, Xiao-NRF52 and T-Echo/T-Echo Lite... since PowerSaving 07</li>\n<li>PowerSaving CLI: \"powersaving\" to check status, \"powersaving on\" and \"powersaving off\". </li>\n<li>Built-in temperature in telemetry for ESP32S3 and NRF52 repeaters.</li>\n<li>Fixed BME280 and BME680 for all boards.</li>\n<li>Added force clock sync in CLI \"clock fsync\"</li>\n<li>Fixed measurement of battery voltage for T-Echo lite</li>\n</ul>\n<p>Instruction: </p>\n<ul>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a></li>\n<li>Please read the instruction in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n</ul>\n<p>Heltec v3, RAK4631 and simulated Xiao Wio S3 (by Heltec v3)</p>\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/4bf662cc-d289-4b1a-8799-df618ff703f5\" />\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/10a9fd6a-d915-46ee-ac5a-0363e69373ab\" /> \n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/194442e6-3228-4df4-a060-07de34bd651d\" /><p>Ping us if you want us to compile for your boards <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">HERE</a>\nYou may want to buy us <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\">a coffee</a> ☕  for good work.\nEnjoy.</p>\n"
        },
        {
          "version": "PowerSaving09",
          "name": "Power Saving 09 - Added PowerSaving CLI and fixed sensor support",
          "datetime": "2025-12-28T05:20:14Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving09",
          "prerelease": false,
          "notes": "Power Saving 09: Power saving CLI and more sensor support\r\n- Added PowerSaving CLI: To type in CLI \"powersaving\" to check status, \"powersaving on\" and \"powersaving off\". You need to type \"**powersaving on**\" ONCE. The setting will persist even after reboot.\r\n- Used the default I2C pins as same as MeshCore\r\n- Improved performance for repeaters' boot: To check availability of I2C addresses of sensors before triggering begin() for sensors.\r\n- Added sensor support for T114. Please help to test it.\r\n- Fixed to use temperature of BME280/680 (if available) instead of MCU Temperature\r\n- Fixed the accuracy of MCU temperature for ESP32 boards: To get the MCU temperature 4 times and average them to have better accuracy in low temperature (~0*C)\r\n- Updated the instruction to [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n\r\nNotes:\r\n- Please read the instruction in [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n- Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\r\n- PING us if you want us to compile for your boards [HERE](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas)\r\n\r\nPlease type \"powersaving on\" to enjoy the power consumption as low as 9.5mA for ESP32-based boards (Except Xiao S3) and 8.5mA for NRF52 boards.\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/c7c6c252-1407-465f-81d2-5042d0cc5c43\" />\r\n\r\nThe temperature of BME280/680 will override the default temperature of MCU.\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9d451727-39f7-4e02-9cc8-9ea0affc00a4\" />\r\n\r\nYou may want to buy us [a coffee](https://github.com/sponsors/IoTThinks) for good work.\r\nEnjoy.",
          "notesHtml": "<p>Power Saving 09: Power saving CLI and more sensor support</p>\n<ul>\n<li>Added PowerSaving CLI: To type in CLI \"powersaving\" to check status, \"powersaving on\" and \"powersaving off\". You need to type \"<strong>powersaving on</strong>\" ONCE. The setting will persist even after reboot.</li>\n<li>Used the default I2C pins as same as MeshCore</li>\n<li>Improved performance for repeaters' boot: To check availability of I2C addresses of sensors before triggering begin() for sensors.</li>\n<li>Added sensor support for T114. Please help to test it.</li>\n<li>Fixed to use temperature of BME280/680 (if available) instead of MCU Temperature</li>\n<li>Fixed the accuracy of MCU temperature for ESP32 boards: To get the MCU temperature 4 times and average them to have better accuracy in low temperature (~0*C)</li>\n<li>Updated the instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n</ul>\n<p>Notes:</p>\n<ul>\n<li>Please read the instruction in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a></li>\n<li>PING us if you want us to compile for your boards <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">HERE</a></li>\n</ul>\n<p>Please type \"powersaving on\" to enjoy the power consumption as low as 9.5mA for ESP32-based boards (Except Xiao S3) and 8.5mA for NRF52 boards.\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/c7c6c252-1407-465f-81d2-5042d0cc5c43\" /></p>\n<p>The temperature of BME280/680 will override the default temperature of MCU.\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/9d451727-39f7-4e02-9cc8-9ea0affc00a4\" /></p>\n<p>You may want to buy us <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\">a coffee</a> for good work.\nEnjoy.</p>\n"
        },
        {
          "version": "PowerSaving08",
          "name": "Power Saving 08 - Fixed BME280 and BME680 for all boards",
          "datetime": "2025-12-21T13:58:52Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving08",
          "prerelease": false,
          "notes": "Power Saving 08 fixed BME280/BME680 for repeaters\r\n- Fixed BME280 and BME680 for all boards.\r\n- Added force clock sync in CLI \"clock fsync\"\r\n- Fixed measurement of battery voltage for T-Echo lite\r\n\r\nNotes:\r\n- Please read the instruction in [Add sensors to repeaters](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md)\r\n- Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\r\n- PING us if you want us to compile for your boards [HERE](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas)\r\n\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/3e65cf19-0d49-42d4-b9fc-b10e6f0889f9\" /> <img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/b94fb4ea-5ae1-4f99-99f1-788c76a7da29\" />\r\n\r\nYou may want to buy us [a coffee](https://github.com/sponsors/IoTThinks) for good work.\r\nEnjoy.",
          "notesHtml": "<p>Power Saving 08 fixed BME280/BME680 for repeaters</p>\n<ul>\n<li>Fixed BME280 and BME680 for all boards.</li>\n<li>Added force clock sync in CLI \"clock fsync\"</li>\n<li>Fixed measurement of battery voltage for T-Echo lite</li>\n</ul>\n<p>Notes:</p>\n<ul>\n<li>Please read the instruction in <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Add-sensors-to-repeaters.md\" target=\"_blank\" rel=\"noopener noreferrer\">Add sensors to repeaters</a></li>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a></li>\n<li>PING us if you want us to compile for your boards <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">HERE</a></li>\n</ul>\n<p><img alt=\"image\" src=\"https://github.com/user-attachments/assets/3e65cf19-0d49-42d4-b9fc-b10e6f0889f9\" /> <img alt=\"image\" src=\"https://github.com/user-attachments/assets/b94fb4ea-5ae1-4f99-99f1-788c76a7da29\" /></p>\n<p>You may want to buy us <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\">a coffee</a> for good work.\nEnjoy.</p>\n"
        },
        {
          "version": "PowerSaving07",
          "name": "Power Saving 07 - Improved power saving and added built-in temperature",
          "datetime": "2025-12-11T04:28:59Z",
          "url": "https://github.com/IoTThinks/EasySkyMesh/releases/tag/PowerSaving07",
          "prerelease": false,
          "notes": "Improved power saving and added built-in temperature for ESP32S3 and NRF52 repeaters\r\n- Based on MeshCore repeater v1.11.0\r\n- ESP32S3 boards: Heltec v3 and Heltec v4\r\n- NRF52 boards: RAK4631, Heltec T114, Xiao-NRF52 and T-Echo/T-Echo Lite\r\n- Powersaving: **9mA for ESP32 boards and 8.5mA for NRF52 boards**. You need to measure at the battery cable (NOT from USB cable).\r\n- Built-in temperature in telemetry for ESP32S3 and NRF52 repeaters.\r\n\r\nNotes:\r\n\r\n- Instruction to [Flash Custom Firmware](https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md)\r\n- PING us if you want us to compile for your boards [HERE](https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas)\r\n\r\nHeltec v3 from 50mA down to 9mA. RAK4631 from 12.5mA down to 8.5mA\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9858c8bc-03b2-4c92-ba8f-0626bda3489e\" /> <img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/7c1dff6c-81a9-4168-8a44-2361b81cc686\" />\r\n\r\nBuilt-in temperature (BME280/680/688 is NOT required.)\r\n<img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/68e0f31b-bf12-42e6-9ab9-58ba6286ec04\" /> <img height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/75c2ae05-ba77-4217-8618-212d2192c5ca\" />\r\n\r\nYou may want to buy us [a coffee](https://github.com/sponsors/IoTThinks) for good work.\r\nEnjoy.",
          "notesHtml": "<p>Improved power saving and added built-in temperature for ESP32S3 and NRF52 repeaters</p>\n<ul>\n<li>Based on MeshCore repeater v1.11.0</li>\n<li>ESP32S3 boards: Heltec v3 and Heltec v4</li>\n<li>NRF52 boards: RAK4631, Heltec T114, Xiao-NRF52 and T-Echo/T-Echo Lite</li>\n<li>Powersaving: <strong>9mA for ESP32 boards and 8.5mA for NRF52 boards</strong>. You need to measure at the battery cable (NOT from USB cable).</li>\n<li>Built-in temperature in telemetry for ESP32S3 and NRF52 repeaters.</li>\n</ul>\n<p>Notes:</p>\n<ul>\n<li>Instruction to <a href=\"https://github.com/IoTThinks/EasySkyMesh/blob/main/firmware/Instruction-to-flash-firmware.md\" target=\"_blank\" rel=\"noopener noreferrer\">Flash Custom Firmware</a></li>\n<li>PING us if you want us to compile for your boards <a href=\"https://github.com/IoTThinks/EasySkyMesh/discussions/categories/ideas\" target=\"_blank\" rel=\"noopener noreferrer\">HERE</a></li>\n</ul>\n<p>Heltec v3 from 50mA down to 9mA. RAK4631 from 12.5mA down to 8.5mA\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/9858c8bc-03b2-4c92-ba8f-0626bda3489e\" /> <img alt=\"image\" src=\"https://github.com/user-attachments/assets/7c1dff6c-81a9-4168-8a44-2361b81cc686\" /></p>\n<p>Built-in temperature (BME280/680/688 is NOT required.)\n<img alt=\"image\" src=\"https://github.com/user-attachments/assets/68e0f31b-bf12-42e6-9ab9-58ba6286ec04\" /> <img alt=\"image\" src=\"https://github.com/user-attachments/assets/75c2ae05-ba77-4217-8618-212d2192c5ca\" /></p>\n<p>You may want to buy us <a href=\"https://github.com/sponsors/IoTThinks\" target=\"_blank\" rel=\"noopener noreferrer\">a coffee</a> for good work.\nEnjoy.</p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:29.384Z"
    },
    {
      "id": "fennek",
      "name": "Fennek",
      "type": "fork",
      "maintainer": "danst0",
      "description": "An alternative open-source firmware for the LilyGO T-Deck Pro — music, audiobooks, eBooks and LoRa mesh chat via MeshCore. Features a homescreen launcher, touch and physical keyboard support, EPUB reader, audiobook player, and PCM5102A DAC audio output.\n",
      "repository": "https://github.com/danst0/fennek",
      "license": "GPL-3.0",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "standalone-ui"
      ],
      "features": [
        "Homescreen launcher",
        "Music playback (PCM5102A DAC)",
        "Audiobook player",
        "EPUB and TXT reader with page-index cache",
        "LoRa mesh chat via MeshCore",
        "Touch + physical keyboard support",
        "Per-book reading position"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": false,
          "webFlasher": false
        },
        "networking": {
          "repeater": false,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-tdeck-pro",
          "status": "supported"
        }
      ],
      "popularity": {
        "githubStars": 2,
        "githubForks": 0,
        "githubWatchers": 0,
        "githubOpenIssues": 0,
        "githubContributors": 101,
        "releaseDownloads": 0,
        "latestReleaseDownloads": 0,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": false,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "2.4.8",
      "released": "2026-06-20",
      "releases": [
        {
          "version": "v2.4.8",
          "name": "Fennek v2.4.8",
          "datetime": "2026-06-20T19:59:52Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v2.4.8",
          "prerelease": false,
          "notes": "## Änderungen\n\n- **OTA:** Semver-Vergleich für Update-Erkennung (`tag_name != FENNEK_VERSION` → korrekte Versionslogik)\n- **Akku:** Batterieanzeige-Fix in der Statuszeile\n\n## Flashen\n\n```\npio run -e fennek -t upload\n```\n\noder OTA via `fennek.local` → Firmware-Update.",
          "notesHtml": "<h2>Änderungen</h2>\n<ul>\n<li><strong>OTA:</strong> Semver-Vergleich für Update-Erkennung (<code>tag_name != FENNEK_VERSION</code> → korrekte Versionslogik)</li>\n<li><strong>Akku:</strong> Batterieanzeige-Fix in der Statuszeile</li>\n</ul>\n<h2>Flashen</h2>\n<pre><code>pio run -e fennek -t upload\n</code></pre>\n<p>oder OTA via <code>fennek.local</code> → Firmware-Update.</p>\n"
        },
        {
          "version": "v2.3.1",
          "name": "Fennek v2.3.1",
          "datetime": "2026-06-19T14:27:33Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v2.3.1",
          "prerelease": false,
          "notes": "## Notizen / Audio\n- **Sprachnotiz-Liste** zeigt jetzt **Datum + HH:MM** (statt HH:MM:SS bzw. generisch „Sprachnotiz\").\n- **Aufnahme-Gain ×6** mit Sättigung: das PDM-Mikro war ~−20 dBFS leise → Wiedergabe kaum hörbar. Neue Aufnahmen sitzen bei ~−7 dBFS (kein Clipping).\n- **Sauberer I2S0-Handover** nach der Aufnahme: kein doppeltes `i2s_driver_uninstall` mehr (`endMic`/`MicResume` macht uninstall+install in einem Schritt).\n\n## Karten / GPS\n- **No-Fix-Fallback** zentriert jetzt auf **Düsseldorf** (51.2277/6.7735); `DEFAULT_ZOOM` 15 → 13 (NRW-weit bekachelt).\n- **GPS-Zeit-Diagnose**: Einmal-Log `[MAPS] GPS-Zeit empfangen …` pro Karten-Session.\n\nEnthält außerdem v2.3.0 (GPS-/WAV-Diagnose-Logs, Karten-Fallback, Notizen-Zeitlabel).",
          "notesHtml": "<h2>Notizen / Audio</h2>\n<ul>\n<li><strong>Sprachnotiz-Liste</strong> zeigt jetzt <strong>Datum + HH:MM</strong> (statt HH:MM:SS bzw. generisch „Sprachnotiz\").</li>\n<li><strong>Aufnahme-Gain ×6</strong> mit Sättigung: das PDM-Mikro war ~−20 dBFS leise → Wiedergabe kaum hörbar. Neue Aufnahmen sitzen bei ~−7 dBFS (kein Clipping).</li>\n<li><strong>Sauberer I2S0-Handover</strong> nach der Aufnahme: kein doppeltes <code>i2s_driver_uninstall</code> mehr (<code>endMic</code>/<code>MicResume</code> macht uninstall+install in einem Schritt).</li>\n</ul>\n<h2>Karten / GPS</h2>\n<ul>\n<li><strong>No-Fix-Fallback</strong> zentriert jetzt auf <strong>Düsseldorf</strong> (51.2277/6.7735); <code>DEFAULT_ZOOM</code> 15 → 13 (NRW-weit bekachelt).</li>\n<li><strong>GPS-Zeit-Diagnose</strong>: Einmal-Log <code>[MAPS] GPS-Zeit empfangen …</code> pro Karten-Session.</li>\n</ul>\n<p>Enthält außerdem v2.3.0 (GPS-/WAV-Diagnose-Logs, Karten-Fallback, Notizen-Zeitlabel).</p>\n"
        },
        {
          "version": "v2.0.4",
          "name": "v2.0.4",
          "datetime": "2026-06-17T17:30:26Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v2.0.4",
          "prerelease": false,
          "notes": "## Changes\n\n- **Regenerated README/website screenshots.** The home-screen mirror in the host renderer (`tools/screenshot.cpp`) was stuck on an old layout (6 tiles, 2×3); it now matches the real `launcher.cpp` — a 2×5 grid with all 10 slots (Music/Listen/Read/Mesh/Settings/Games/Files/Notes/Alarm). The Settings screenshot now shows the current version.\n- Images updated in `docs/screenshots/{de,en,sv}/` and on [fennek.dumke.me](https://fennek.dumke.me).\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "notesHtml": "<h2>Changes</h2>\n<ul>\n<li><strong>Regenerated README/website screenshots.</strong> The home-screen mirror in the host renderer (<code>tools/screenshot.cpp</code>) was stuck on an old layout (6 tiles, 2×3); it now matches the real <code>launcher.cpp</code> — a 2×5 grid with all 10 slots (Music/Listen/Read/Mesh/Settings/Games/Files/Notes/Alarm). The Settings screenshot now shows the current version.</li>\n<li>Images updated in <code>docs/screenshots/{de,en,sv}/</code> and on <a href=\"https://fennek.dumke.me/\" target=\"_blank\" rel=\"noopener noreferrer\">fennek.dumke.me</a>.</li>\n</ul>\n<p>🤖 Generated with <a href=\"https://claude.com/claude-code\" target=\"_blank\" rel=\"noopener noreferrer\">Claude Code</a></p>\n"
        },
        {
          "version": "v1.9.4",
          "name": "v1.9.4",
          "datetime": "2026-06-17T06:53:30Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.9.4",
          "prerelease": false,
          "notes": "## Änderungen\n\n- **Web-Dateimanager**: Löschen ohne Rückfrage. Nur Ordner mit Unterordnern fragen kurz nach und werden dann rekursiv gelöscht (`rmRecursive`); Dateien und flache Ordner verschwinden sofort.\n- **Notizen-App + Konsole**: weitere Verbesserungen.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "notesHtml": "<h2>Änderungen</h2>\n<ul>\n<li><strong>Web-Dateimanager</strong>: Löschen ohne Rückfrage. Nur Ordner mit Unterordnern fragen kurz nach und werden dann rekursiv gelöscht (<code>rmRecursive</code>); Dateien und flache Ordner verschwinden sofort.</li>\n<li><strong>Notizen-App + Konsole</strong>: weitere Verbesserungen.</li>\n</ul>\n<p>🤖 Generated with <a href=\"https://claude.com/claude-code\" target=\"_blank\" rel=\"noopener noreferrer\">Claude Code</a></p>\n"
        },
        {
          "version": "v1.9.2",
          "name": "Fennek v1.9.2",
          "datetime": "2026-06-15T15:51:06Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.9.2",
          "prerelease": false,
          "notes": "### Added\n- **`BATTLOG` — opt-in battery & activity logger** (`services/battlog`). When the `BATTLOG` build flag is set, the firmware writes one record per event (app switch, audio track, mesh radio on, Wi-Fi on/off, standby/wake) **and** a battery probe every 60 s to `/.fennek/battery.log` (timestamp + %/mV/charging? + Wi-Fi/mesh status). It's a throttled PSRAM ring flushed to SD before standby, and downloadable via the Web file manager — useful for diagnosing real-world battery drain. Deliberately zero-cost when the flag is off (all `BATTLOG_*` calls compile to nothing).\n\n🌐 Project page & screenshots: **https://fennek.dumke.me**\n\n**Full changelog:** [`CHANGELOG.md`](https://github.com/danst0/fennek/blob/main/CHANGELOG.md)",
          "notesHtml": "<h3>Added</h3>\n<ul>\n<li><strong><code>BATTLOG</code> — opt-in battery &amp; activity logger</strong> (<code>services/battlog</code>). When the <code>BATTLOG</code> build flag is set, the firmware writes one record per event (app switch, audio track, mesh radio on, Wi-Fi on/off, standby/wake) <strong>and</strong> a battery probe every 60 s to <code>/.fennek/battery.log</code> (timestamp + %/mV/charging? + Wi-Fi/mesh status). It's a throttled PSRAM ring flushed to SD before standby, and downloadable via the Web file manager — useful for diagnosing real-world battery drain. Deliberately zero-cost when the flag is off (all <code>BATTLOG_*</code> calls compile to nothing).</li>\n</ul>\n<p>🌐 Project page &amp; screenshots: <strong><a href=\"https://fennek.dumke.me/\" target=\"_blank\" rel=\"noopener noreferrer\">https://fennek.dumke.me</a></strong></p>\n<p><strong>Full changelog:</strong> <a href=\"https://github.com/danst0/fennek/blob/main/CHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\"><code>CHANGELOG.md</code></a></p>\n"
        },
        {
          "version": "v1.9.1",
          "name": "Fennek v1.9.1",
          "datetime": "2026-06-15T15:51:06Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.9.1",
          "prerelease": false,
          "notes": "### Fixed\n- **Notes never silently lost on a failed SD write.** The save path now clears its dirty flag only on a *complete* success; if an SD write or remove fails, the note stays dirty and is retried on the next autosave instead of being overwritten on the next editor open.\n- **Just-played track now reaches the scrobble queue before standby.** `power::poll()` stops audio (and lets the audio task drain the stop command) *before* the pre-standby Navidrome flush, so the current track is enqueued via `noteTrackEnded()` rather than landing in the PSRAM ring that deep sleep would otherwise discard.\n\n**Full changelog:** [`CHANGELOG.md`](https://github.com/danst0/fennek/blob/main/CHANGELOG.md)",
          "notesHtml": "<h3>Fixed</h3>\n<ul>\n<li><strong>Notes never silently lost on a failed SD write.</strong> The save path now clears its dirty flag only on a <em>complete</em> success; if an SD write or remove fails, the note stays dirty and is retried on the next autosave instead of being overwritten on the next editor open.</li>\n<li><strong>Just-played track now reaches the scrobble queue before standby.</strong> <code>power::poll()</code> stops audio (and lets the audio task drain the stop command) <em>before</em> the pre-standby Navidrome flush, so the current track is enqueued via <code>noteTrackEnded()</code> rather than landing in the PSRAM ring that deep sleep would otherwise discard.</li>\n</ul>\n<p><strong>Full changelog:</strong> <a href=\"https://github.com/danst0/fennek/blob/main/CHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\"><code>CHANGELOG.md</code></a></p>\n"
        },
        {
          "version": "v1.9.0",
          "name": "Fennek v1.9.0",
          "datetime": "2026-06-15T15:51:05Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.9.0",
          "prerelease": false,
          "notes": "### Added\n- **Mesh: `contacts reset` console command** + `mesh_client::resetContacts()`. Clears all contacts and their persistent mirrors (SPIFFS `/contacts`, SD `/meshcore/contacts.bin`); the contact table then rebuilds itself from incoming adverts. Handy when the 64-slot table fills up with stale nodes or you want a clean slate.\n\n**Full changelog:** [`CHANGELOG.md`](https://github.com/danst0/fennek/blob/main/CHANGELOG.md)",
          "notesHtml": "<h3>Added</h3>\n<ul>\n<li><strong>Mesh: <code>contacts reset</code> console command</strong> + <code>mesh_client::resetContacts()</code>. Clears all contacts and their persistent mirrors (SPIFFS <code>/contacts</code>, SD <code>/meshcore/contacts.bin</code>); the contact table then rebuilds itself from incoming adverts. Handy when the 64-slot table fills up with stale nodes or you want a clean slate.</li>\n</ul>\n<p><strong>Full changelog:</strong> <a href=\"https://github.com/danst0/fennek/blob/main/CHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\"><code>CHANGELOG.md</code></a></p>\n"
        },
        {
          "version": "v1.8.1",
          "name": "Fennek v1.8.1",
          "datetime": "2026-06-15T15:51:04Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.8.1",
          "prerelease": false,
          "notes": "### Changed\n- **Unified back/home navigation across all apps.** Home is now a visible affordance: the status bar shows a house glyph (⌂) outside the launcher and the whole bar taps to Home. Lower corner buttons are consistently labelled **\"Back\"** (exactly one level) — audiobook/reader/notes lists and Settings now say \"Back\" instead of \"Home\", and the Settings back button steps edit → category → root → launcher. Mesh sub-screens dropped their redundant second \"Home\" button, the Files app gained a visible \"Back\" button, and the reader footer tap-zone is labelled \"◄ List\". Games keep no on-screen back button (exit via the ⌂ glyph; keyboard `Backspace`/`Q` still works). Keyboard conventions (`Q` = Home, `Backspace` = one level back) unchanged.\n\n**Full changelog:** [`CHANGELOG.md`](https://github.com/danst0/fennek/blob/main/CHANGELOG.md)",
          "notesHtml": "<h3>Changed</h3>\n<ul>\n<li><strong>Unified back/home navigation across all apps.</strong> Home is now a visible affordance: the status bar shows a house glyph (⌂) outside the launcher and the whole bar taps to Home. Lower corner buttons are consistently labelled <strong>\"Back\"</strong> (exactly one level) — audiobook/reader/notes lists and Settings now say \"Back\" instead of \"Home\", and the Settings back button steps edit → category → root → launcher. Mesh sub-screens dropped their redundant second \"Home\" button, the Files app gained a visible \"Back\" button, and the reader footer tap-zone is labelled \"◄ List\". Games keep no on-screen back button (exit via the ⌂ glyph; keyboard <code>Backspace</code>/<code>Q</code> still works). Keyboard conventions (<code>Q</code> = Home, <code>Backspace</code> = one level back) unchanged.</li>\n</ul>\n<p><strong>Full changelog:</strong> <a href=\"https://github.com/danst0/fennek/blob/main/CHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\"><code>CHANGELOG.md</code></a></p>\n"
        },
        {
          "version": "v1.8.0",
          "name": "Fennek v1.8.0",
          "datetime": "2026-06-13T19:18:10Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.8.0",
          "prerelease": false,
          "notes": "## Added\n- **Notes app** (launcher tile 7): a daily-notes model — exactly one note per day, named after the local date (`/notes/YYYY-MM-DD.md`). **\"+ Today\"** opens or appends to today's note; the list shows every day newest-first with a first-line preview, and notes can be deleted with a confirmation. The editor is append-style (type / Backspace / Enter) with its own word wrap and a compact header.\n\n  Persistence is chunked under `spiLock` (never inside `draw()`), with a 30 s autosave and a save on leave; empty notes are removed. Without an SD card it shows \"No SD card\" + \"Search again\" like the other apps. The date comes from the local system clock (`timesync`). New console command `notes` runs an SD round-trip / scan self-check (in the style of `books`).\n\nLocalized in DE/IT/SV/EN/ES. Verified on device (clean boot, SD round-trip with UTF-8 preserved, scan/sort).\n\n**Full changelog:** [CHANGELOG.md](https://github.com/danst0/fennek/blob/main/CHANGELOG.md)",
          "notesHtml": "<h2>Added</h2>\n<ul>\n<li><p><strong>Notes app</strong> (launcher tile 7): a daily-notes model — exactly one note per day, named after the local date (<code>/notes/YYYY-MM-DD.md</code>). <strong>\"+ Today\"</strong> opens or appends to today's note; the list shows every day newest-first with a first-line preview, and notes can be deleted with a confirmation. The editor is append-style (type / Backspace / Enter) with its own word wrap and a compact header.</p>\n<p>Persistence is chunked under <code>spiLock</code> (never inside <code>draw()</code>), with a 30 s autosave and a save on leave; empty notes are removed. Without an SD card it shows \"No SD card\" + \"Search again\" like the other apps. The date comes from the local system clock (<code>timesync</code>). New console command <code>notes</code> runs an SD round-trip / scan self-check (in the style of <code>books</code>).</p>\n</li>\n</ul>\n<p>Localized in DE/IT/SV/EN/ES. Verified on device (clean boot, SD round-trip with UTF-8 preserved, scan/sort).</p>\n<p><strong>Full changelog:</strong> <a href=\"https://github.com/danst0/fennek/blob/main/CHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\">CHANGELOG.md</a></p>\n"
        },
        {
          "version": "v1.7.1",
          "name": "Fennek v1.7.1",
          "datetime": "2026-06-13T04:08:05Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.7.1",
          "prerelease": false,
          "notes": "## ✨ Added\n- **Settings backup as INI** (`services/settingsfile`): export/import all NVS settings to/from an SD file. SPI-free serialization on a RAM buffer, SD I/O isolated under `spiLock`. Per-book bookmarks/reading positions are excluded (CRC32-hashed keys). New console command + `main`/`power` wiring.\n\n## 📝 Docs\n- Added `CHANGELOG.md` and GitHub releases for v1.3.0–v1.7.0.\n- README now ships in **English (default)**, German (`README.de.md`) and Swedish (`README.sv.md`) with a language switcher and release/changelog badges.\n\n📋 Full history: [CHANGELOG.md](https://github.com/danst0/fennek/blob/main/CHANGELOG.md)",
          "notesHtml": "<h2>✨ Added</h2>\n<ul>\n<li><strong>Settings backup as INI</strong> (<code>services/settingsfile</code>): export/import all NVS settings to/from an SD file. SPI-free serialization on a RAM buffer, SD I/O isolated under <code>spiLock</code>. Per-book bookmarks/reading positions are excluded (CRC32-hashed keys). New console command + <code>main</code>/<code>power</code> wiring.</li>\n</ul>\n<h2>📝 Docs</h2>\n<ul>\n<li>Added <code>CHANGELOG.md</code> and GitHub releases for v1.3.0–v1.7.0.</li>\n<li>README now ships in <strong>English (default)</strong>, German (<code>README.de.md</code>) and Swedish (<code>README.sv.md</code>) with a language switcher and release/changelog badges.</li>\n</ul>\n<p>📋 Full history: <a href=\"https://github.com/danst0/fennek/blob/main/CHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\">CHANGELOG.md</a></p>\n"
        },
        {
          "version": "v1.7.0",
          "name": "Fennek v1.7.0",
          "datetime": "2026-06-13T04:03:33Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.7.0",
          "prerelease": false,
          "notes": "## ✨ Added\n- **\"+ New Channel\" UI** for joining hashtag channels — a \"► New Channel\" row at the top of the chat list opens a join screen (keyboard types the `#name`, PSK derived from it, persisted to `channels.txt` on SD; jumps straight into the new channel after joining).\n\n## 🔄 Changed\n- **Robust time synchronization without a hardware RTC.** Canonical clock is now ESP32 system time (`SystemRTCClock`), which survives deep sleep. New `services/timesync` coordinator: opportunistic NTP (when Wi-Fi is up) + a top-up before auto-standby, with Mesh adverts as a passive source. Quality model (`estErr = learned drift × time since sync`) with exponential back-off, `s_clockConfident` bootstrap for the first advert after boot, POSIX time zone (default `Europe/Berlin` incl. DST), settings rows \"Time zone\"/\"Time\", and console `time` / `time set` / `time sync` / `tz`.\n\n📋 Full history: [CHANGELOG.md](https://github.com/danst0/fennek/blob/main/CHANGELOG.md)",
          "notesHtml": "<h2>✨ Added</h2>\n<ul>\n<li><strong>\"+ New Channel\" UI</strong> for joining hashtag channels — a \"► New Channel\" row at the top of the chat list opens a join screen (keyboard types the <code>#name</code>, PSK derived from it, persisted to <code>channels.txt</code> on SD; jumps straight into the new channel after joining).</li>\n</ul>\n<h2>🔄 Changed</h2>\n<ul>\n<li><strong>Robust time synchronization without a hardware RTC.</strong> Canonical clock is now ESP32 system time (<code>SystemRTCClock</code>), which survives deep sleep. New <code>services/timesync</code> coordinator: opportunistic NTP (when Wi-Fi is up) + a top-up before auto-standby, with Mesh adverts as a passive source. Quality model (<code>estErr = learned drift × time since sync</code>) with exponential back-off, <code>s_clockConfident</code> bootstrap for the first advert after boot, POSIX time zone (default <code>Europe/Berlin</code> incl. DST), settings rows \"Time zone\"/\"Time\", and console <code>time</code> / <code>time set</code> / <code>time sync</code> / <code>tz</code>.</li>\n</ul>\n<p>📋 Full history: <a href=\"https://github.com/danst0/fennek/blob/main/CHANGELOG.md\" target=\"_blank\" rel=\"noopener noreferrer\">CHANGELOG.md</a></p>\n"
        },
        {
          "version": "v1.6.3",
          "name": "v1.6.3",
          "datetime": "2026-06-13T04:03:32Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.6.3",
          "prerelease": false,
          "notes": "## 📡 Mesh SD persistence & clock hardening\n- Contact mirror (`/meshcore/contacts.bin`, SD takes load priority over SPIFFS, deferred write from `loop()`) and joined hashtag channels (`/meshcore/channels.txt`, re-joined on boot).\n- RTC sync guard against future-clock outliers (bootstrap + forward jumps < 1 h, backward only on a 3× advert consensus).\n- Contact overflow fix: overwrite the oldest non-favorite when the table (64) is full instead of dropping new adverts.\n- Console hashtag commands `join` / `chan`, plus a new `i2cscan` command. Verified on device: the T-Deck Pro V1.1 has **no hardware RTC** (0x51 empty).",
          "notesHtml": "<h2>📡 Mesh SD persistence &amp; clock hardening</h2>\n<ul>\n<li>Contact mirror (<code>/meshcore/contacts.bin</code>, SD takes load priority over SPIFFS, deferred write from <code>loop()</code>) and joined hashtag channels (<code>/meshcore/channels.txt</code>, re-joined on boot).</li>\n<li>RTC sync guard against future-clock outliers (bootstrap + forward jumps &lt; 1 h, backward only on a 3× advert consensus).</li>\n<li>Contact overflow fix: overwrite the oldest non-favorite when the table (64) is full instead of dropping new adverts.</li>\n<li>Console hashtag commands <code>join</code> / <code>chan</code>, plus a new <code>i2cscan</code> command. Verified on device: the T-Deck Pro V1.1 has <strong>no hardware RTC</strong> (0x51 empty).</li>\n</ul>\n"
        },
        {
          "version": "v1.6.2",
          "name": "v1.6.2",
          "datetime": "2026-06-13T04:03:31Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.6.2",
          "prerelease": false,
          "notes": "## 📄 Licensing\n- SPDX `GPL-3.0-or-later` / © Dr. Daniel Dumke headers added to all Fennek-owned `src` files (the vendored Hynitron touch driver in `src/core/hyn/` is left untouched).\n- Options screen now shows an author/copyright footer.",
          "notesHtml": "<h2>📄 Licensing</h2>\n<ul>\n<li>SPDX <code>GPL-3.0-or-later</code> / © Dr. Daniel Dumke headers added to all Fennek-owned <code>src</code> files (the vendored Hynitron touch driver in <code>src/core/hyn/</code> is left untouched).</li>\n<li>Options screen now shows an author/copyright footer.</li>\n</ul>\n"
        },
        {
          "version": "v1.6.1",
          "name": "v1.6.1",
          "datetime": "2026-06-13T04:03:30Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.6.1",
          "prerelease": false,
          "notes": "## 📡 Mesh app overhaul (MVP)\n- Contacts split from the chat list (chats show only channels + contacts with history; a new contacts screen lists all adverts).\n- HH:MM timestamps + touch scrollback in conversations.\n- Status line (noise floor / RX / TX / contacts / clock), contact detail view (hops + last seen).\n- Touch scroll strip for lists, error-retry button, DM resend on timeout, and multi-ACK tracking for parallel DMs.",
          "notesHtml": "<h2>📡 Mesh app overhaul (MVP)</h2>\n<ul>\n<li>Contacts split from the chat list (chats show only channels + contacts with history; a new contacts screen lists all adverts).</li>\n<li>HH:MM timestamps + touch scrollback in conversations.</li>\n<li>Status line (noise floor / RX / TX / contacts / clock), contact detail view (hops + last seen).</li>\n<li>Touch scroll strip for lists, error-retry button, DM resend on timeout, and multi-ACK tracking for parallel DMs.</li>\n</ul>\n"
        },
        {
          "version": "v1.6.0",
          "name": "v1.6.0",
          "datetime": "2026-06-13T04:03:29Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.6.0",
          "prerelease": false,
          "notes": "## ✨ Added\n- **Unlimited music library:** on-demand growing PSRAM blocks (instead of `MAX_TRACKS=512`), track cache `/.fennek/tracks.bin` (boot in seconds), background scan in `readdir` chunks. Scans pause during playback (anti-stutter). Track paths up to 256 chars (Calibre).\n- **Web file manager** (Files app + `webfm`): Wi-Fi station with an embedded HTML page + JSON API to browse/upload/download/delete SD files over `http://fennek.local`.\n- Console: `sleep` command + boot/reset diagnostics in `status`.",
          "notesHtml": "<h2>✨ Added</h2>\n<ul>\n<li><strong>Unlimited music library:</strong> on-demand growing PSRAM blocks (instead of <code>MAX_TRACKS=512</code>), track cache <code>/.fennek/tracks.bin</code> (boot in seconds), background scan in <code>readdir</code> chunks. Scans pause during playback (anti-stutter). Track paths up to 256 chars (Calibre).</li>\n<li><strong>Web file manager</strong> (Files app + <code>webfm</code>): Wi-Fi station with an embedded HTML page + JSON API to browse/upload/download/delete SD files over <code>http://fennek.local</code>.</li>\n<li>Console: <code>sleep</code> command + boot/reset diagnostics in <code>status</code>.</li>\n</ul>\n"
        },
        {
          "version": "v1.5.0",
          "name": "v1.5.0",
          "datetime": "2026-06-13T04:03:29Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.5.0",
          "prerelease": false,
          "notes": "## 🌍 Localization\n- Extended with **English and Spanish** (`FENNEK_STRS` now 5 columns, EN/ES appended — NVS-compatible).\n- Documented the CP437 limitation for missing uppercase accented characters.\n- Reader rescan rework, chess brace fixes, MeshSeeLog entry.",
          "notesHtml": "<h2>🌍 Localization</h2>\n<ul>\n<li>Extended with <strong>English and Spanish</strong> (<code>FENNEK_STRS</code> now 5 columns, EN/ES appended — NVS-compatible).</li>\n<li>Documented the CP437 limitation for missing uppercase accented characters.</li>\n<li>Reader rescan rework, chess brace fixes, MeshSeeLog entry.</li>\n</ul>\n"
        },
        {
          "version": "v1.4.0",
          "name": "v1.4.0",
          "datetime": "2026-06-13T04:03:28Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.4.0",
          "prerelease": false,
          "notes": "## 🌍 Internationalization framework\n- New `core/i18n`: central string table, language selectable in settings, applied across all apps (launcher, music, book, reader, mesh, games, settings).\n- README screenshots + host-side renderer (`tools/screenshot.cpp`) for generating UI screenshots without the device.",
          "notesHtml": "<h2>🌍 Internationalization framework</h2>\n<ul>\n<li>New <code>core/i18n</code>: central string table, language selectable in settings, applied across all apps (launcher, music, book, reader, mesh, games, settings).</li>\n<li>README screenshots + host-side renderer (<code>tools/screenshot.cpp</code>) for generating UI screenshots without the device.</li>\n</ul>\n"
        },
        {
          "version": "v1.3.1",
          "name": "v1.3.1",
          "datetime": "2026-06-13T04:03:27Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.3.1",
          "prerelease": false,
          "notes": "## 🎨 Standby & project\n- **Standby screen:** AI-generated sleeping fennec as a 1-bit bitmap (Floyd–Steinberg, 240×320) with a bottom banner.\n- GPL-3.0+ license, README reworked as an alternative firmware.\n- Repo slimmed down and detached from the Meck fork; build env renamed `mp3player` → `fennek`.",
          "notesHtml": "<h2>🎨 Standby &amp; project</h2>\n<ul>\n<li><strong>Standby screen:</strong> AI-generated sleeping fennec as a 1-bit bitmap (Floyd–Steinberg, 240×320) with a bottom banner.</li>\n<li>GPL-3.0+ license, README reworked as an alternative firmware.</li>\n<li>Repo slimmed down and detached from the Meck fork; build env renamed <code>mp3player</code> → <code>fennek</code>.</li>\n</ul>\n"
        },
        {
          "version": "v1.3.0",
          "name": "v1.3.0",
          "datetime": "2026-06-13T04:03:26Z",
          "url": "https://github.com/danst0/fennek/releases/tag/v1.3.0",
          "prerelease": false,
          "notes": "## 🎮 Games app\n- New Games app: **2048, Minesweeper, Chess (Negamax AI), Tic-Tac-Toe**. Game logic lives in Arduino-free, host-tested cores.",
          "notesHtml": "<h2>🎮 Games app</h2>\n<ul>\n<li>New Games app: <strong>2048, Minesweeper, Chess (Negamax AI), Tic-Tac-Toe</strong>. Game logic lives in Arduino-free, host-tested cores.</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:29.691Z"
    },
    {
      "id": "fieldmesh",
      "name": "FieldMesh",
      "type": "fork",
      "maintainer": "TogeriX-hub (Tobias Guertler)",
      "maintainers": [
        {
          "name": "TogeriX-hub",
          "url": "https://github.com/TogeriX-hub"
        }
      ],
      "repository": "https://github.com/TogeriX-hub/FieldMesh",
      "website": "https://www.tobiasguertler.de/blog/en/fieldmesh",
      "license": "MIT",
      "description": "A MeshCore firmware fork optimized for outdoor use — festivals, hiking, off-grid events. Adds automatic GPS advertising, dedicated tracking page with distance calculation, Off-Grid mode with legal frequency defaults and one-press toggle, SOS system with buzzer alarms, message history with RAM ring buffer, and text input/send on joystick-equipped devices. Designed to be field-ready: put it in your backpack and trust it's doing its job.\n",
      "status": "active",
      "lifecycle": "active",
      "maturity": "stable",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "standalone-ui"
      ],
      "features": [
        "Automatic GPS advertising (zero-hop, every 5 minutes)",
        "Dedicated tracking page with Haversine distance calculation",
        "Off-Grid mode with Client Repeat on separate legal frequencies",
        "One-press Off-Grid toggle (menu or 5x button press on headless devices)",
        "SOS system with two-step confirmation and buzzer alarm",
        "Message history (RAM ring buffer, up to 32 entries)",
        "Text input and send via joystick (Wio Tracker L1)",
        "Online node counter on home screen",
        "Mode indicators (GPS-SHARE, OFF-GRID)",
        "Headless device support (T1000-E, RAK WiseMesh TAG)",
        "Forced buzzer feedback for all actions on headless devices",
        "Splash screen with version info and FieldMesh branding",
        "Backlight fixes for various displays"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true,
          "rawPacketSend": true,
          "rawPacketObserve": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": false,
          "wifiAp": false
        },
        "operations": {
          "webFlasher": false,
          "ota": false,
          "bleDfu": false,
          "configurationBackup": true
        },
        "networking": {
          "repeater": true,
          "roomServer": false,
          "observer": false,
          "mqtt": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "changelog": {
        "source": "github",
        "repo": "TogeriX-hub/FieldMesh"
      },
      "devices": [
        {
          "id": "thinknode-m1",
          "status": "supported",
          "target": "thinknode_m1",
          "platformio_board": "thinknode_m1",
          "notes": "E-Ink display, single button; primary development target"
        },
        {
          "id": "wio-tracker-l1",
          "status": "supported",
          "target": "wio-tracker-l1",
          "platformio_board": "seeed-wio-tracker-l1",
          "notes": "OLED display (SSD1306/SH1106 128x64), joystick; text input and send supported"
        },
        {
          "id": "wio-tracker-l1-eink",
          "status": "supported",
          "target": "wio-tracker-l1-eink",
          "platformio_board": "seeed-wio-tracker-l1",
          "notes": "E-ink variant (GxEPD2 250x122)"
        },
        {
          "id": "sensecap-t1000e",
          "status": "supported",
          "target": "t1000-e",
          "platformio_board": "tracker-t1000-e",
          "notes": "Headless device (no display, single button); primary headless reference"
        },
        {
          "id": "rak-wismesh-tag",
          "status": "supported",
          "target": "rak_wismesh_tag",
          "platformio_board": "rak4631",
          "notes": "Headless device; contributions welcome"
        }
      ],
      "popularity": {
        "githubStars": 25,
        "githubForks": 0,
        "githubWatchers": 1,
        "githubOpenIssues": 3,
        "githubContributors": 151,
        "releaseDownloads": 0,
        "latestReleaseDownloads": 0,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": true,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "5.3",
      "released": "2026-04-28",
      "releases": [
        {
          "version": "v5.3",
          "name": "FieldMesh v5.3",
          "datetime": "2026-04-28T07:00:54Z",
          "url": "https://github.com/TogeriX-hub/FieldMesh/releases/tag/v5.3",
          "prerelease": false,
          "notes": "## [5.3] — MeshCore Upstream Sync\r\n\r\n\r\n### Changes\r\n- **MeshCore upstream alignment** — codebase updated to track MeshCore v1.15.0; no FieldMesh-specific feature changes in this release\r\n\r\n\r\n# Download latest build\r\n## EU Offgrid frequency\r\n[ThinkNode_M1_companion_radio_ble_FieldMeshv5.3.zip](https://github.com/user-attachments/files/27154033/ThinkNode_M1_companion_radio_ble_FieldMeshv5.3.zip)\r\n[WioTrackerL1_companion_radio_ble_FieldMeshv5.3.zip](https://github.com/user-attachments/files/27154037/WioTrackerL1_companion_radio_ble_FieldMeshv5.3.zip)\r\n[t1000e_companion_radio_ble_FieldMeshv5.3.zip](https://github.com/user-attachments/files/27154044/t1000e_companion_radio_ble_FieldMeshv5.3.zip)\r\n\r\n\r\n## US Offgrid frequency\r\n[ThinkNode_M1_companion_radio_ble_USFieldMeshv5.3.zip](https://github.com/user-attachments/files/27154065/ThinkNode_M1_companion_radio_ble_USFieldMeshv5.3.zip)\r\n[WioTrackerL1_companion_radio_ble_USFieldMeshv5.3.zip](https://github.com/user-attachments/files/27154067/WioTrackerL1_companion_radio_ble_USFieldMeshv5.3.zip)\r\n[t1000e_companion_radio_ble_USFieldMeshv5.3.zip](https://github.com/user-attachments/files/27154071/t1000e_companion_radio_ble_USFieldMeshv5.3.zip)",
          "notesHtml": "<h2>[5.3] — MeshCore Upstream Sync</h2>\n<h3>Changes</h3>\n<ul>\n<li><strong>MeshCore upstream alignment</strong> — codebase updated to track MeshCore v1.15.0; no FieldMesh-specific feature changes in this release</li>\n</ul>\n<h1>Download latest build</h1>\n<h2>EU Offgrid frequency</h2>\n<p><a href=\"https://github.com/user-attachments/files/27154033/ThinkNode_M1_companion_radio_ble_FieldMeshv5.3.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_FieldMeshv5.3.zip</a>\n<a href=\"https://github.com/user-attachments/files/27154037/WioTrackerL1_companion_radio_ble_FieldMeshv5.3.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_FieldMeshv5.3.zip</a>\n<a href=\"https://github.com/user-attachments/files/27154044/t1000e_companion_radio_ble_FieldMeshv5.3.zip\" target=\"_blank\" rel=\"noopener noreferrer\">t1000e_companion_radio_ble_FieldMeshv5.3.zip</a></p>\n<h2>US Offgrid frequency</h2>\n<p><a href=\"https://github.com/user-attachments/files/27154065/ThinkNode_M1_companion_radio_ble_USFieldMeshv5.3.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_USFieldMeshv5.3.zip</a>\n<a href=\"https://github.com/user-attachments/files/27154067/WioTrackerL1_companion_radio_ble_USFieldMeshv5.3.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_USFieldMeshv5.3.zip</a>\n<a href=\"https://github.com/user-attachments/files/27154071/t1000e_companion_radio_ble_USFieldMeshv5.3.zip\" target=\"_blank\" rel=\"noopener noreferrer\">t1000e_companion_radio_ble_USFieldMeshv5.3.zip</a></p>\n"
        },
        {
          "version": "v5.2",
          "name": "FieldMesh v5.2",
          "datetime": "2026-04-09T14:29:21Z",
          "url": "https://github.com/TogeriX-hub/FieldMesh/releases/tag/v5.2",
          "prerelease": false,
          "notes": "## [5.2] — HomeScreen Redesign & Online Node Counter\r\n\r\n### New features\r\n- **Online node counter** — HomeScreen now shows how many nodes have been\r\n  heard in the last 30 minutes, combining advert senders and message senders\r\n  in a single deduplicated count (16-entry LRU cache)\r\n- **Node counter icon** — the online count is displayed with a filled circle\r\n  icon (●) instead of plain [X] text\r\n- **Real channel name in title bar** — message history and favorite preview\r\n  now show the actual channel name (e.g. \"Public\") instead of the hardcoded\r\n  \"[CH]\" tag\r\n- **Mode indicator** — GPS-SHARE and OFF-GRID modes are now shown on the\r\n  HomeScreen FIRST page\r\n\r\n### Changes\r\n- **M1 HomeScreen layout** — node counter fixed at y=22 regardless of\r\n  connection state; MSG:X replaces `< Connected >` when disconnected;\r\n  nodes_icon y-offset corrected (+3px) to align with text baseline\r\n- **Channel message title bar** — sender name omitted from title bar for\r\n  channel messages (already visible inside the message text)\r\n- **Favorite indicator** — clears correctly after all messages are deleted\r\n  (deleteEntry / clearAll); no longer persists stale data after app sync\r\n- **MSG:X counter** — hidden on HomeScreen while phone app is connected\r\n- **RECENT/TRACKING pages** — row limits now display-height-adaptive via\r\n  max_y variable instead of hardcoded values\r\n\r\n### Bug fixes\r\n- **BLE init: send_queue flood** — between `onSecured()` and `CMD_APP_START`\r\n  async pushes could fill all 12 send_queue slots, causing the app to time\r\n  out. Fixed via `_app_initialized` flag and `isWriteBusy()` guard\r\n- **Double-counting in node counter** — nodes heard via both advert and\r\n  message were counted twice. Fixed via `countOnlineNodesExcluding()`\r\n- **adv_fresh buffer** — was reusing the 4-entry RECENT display array,\r\n  capping the advert-based node count at 4. Now uses a dedicated\r\n  ADVERT_PATH_TABLE_SIZE (16) buffer\r\n- **formatRelTime undefined behavior** — replaced signed int cast with\r\n  safe uint32_t arithmetic\r\n\r\n### Technical notes\r\n- Changes confined to `UITask.cpp`, `UITask.h`, `MyMesh.cpp`, `MyMesh.h`,\r\n  `icons.h`\r\n- `DataStore`, `AbstractUITask`, `platformio.ini` unaffected\r\n\r\n# Download latest build\r\n## EU Offgrid frequency\r\n[ThinkNode_M1_companion_radio_ble_FieldMeshv5.2.zip](https://github.com/user-attachments/files/26605877/ThinkNode_M1_companion_radio_ble_FieldMeshv5.2.zip)\r\n[WioTrackerL1_companion_radio_ble_FieldMeshv5.2.zip](https://github.com/user-attachments/files/26605890/WioTrackerL1_companion_radio_ble_FieldMeshv5.2.zip)\r\n[t1000e_companion_radio_ble_FieldMeshv5.2.zip](https://github.com/user-attachments/files/26605896/t1000e_companion_radio_ble_FieldMeshv5.2.zip)\r\n\r\n## US Offgrid frequency\r\n[ThinkNode_M1_companion_radio_ble_USFieldMeshv5.2.zip](https://github.com/user-attachments/files/26605905/ThinkNode_M1_companion_radio_ble_USFieldMeshv5.2.zip)\r\n[WioTrackerL1_companion_radio_ble_USFieldMeshv5.2.zip](https://github.com/user-attachments/files/26605916/WioTrackerL1_companion_radio_ble_USFieldMeshv5.2.zip)\r\n[t1000e_companion_radio_ble_USFieldMeshv5.2.zip](https://github.com/user-attachments/files/26605923/t1000e_companion_radio_ble_USFieldMeshv5.2.zip)",
          "notesHtml": "<h2>[5.2] — HomeScreen Redesign &amp; Online Node Counter</h2>\n<h3>New features</h3>\n<ul>\n<li><strong>Online node counter</strong> — HomeScreen now shows how many nodes have been\nheard in the last 30 minutes, combining advert senders and message senders\nin a single deduplicated count (16-entry LRU cache)</li>\n<li><strong>Node counter icon</strong> — the online count is displayed with a filled circle\nicon (●) instead of plain [X] text</li>\n<li><strong>Real channel name in title bar</strong> — message history and favorite preview\nnow show the actual channel name (e.g. \"Public\") instead of the hardcoded\n\"[CH]\" tag</li>\n<li><strong>Mode indicator</strong> — GPS-SHARE and OFF-GRID modes are now shown on the\nHomeScreen FIRST page</li>\n</ul>\n<h3>Changes</h3>\n<ul>\n<li><strong>M1 HomeScreen layout</strong> — node counter fixed at y=22 regardless of\nconnection state; MSG:X replaces <code>&lt; Connected &gt;</code> when disconnected;\nnodes_icon y-offset corrected (+3px) to align with text baseline</li>\n<li><strong>Channel message title bar</strong> — sender name omitted from title bar for\nchannel messages (already visible inside the message text)</li>\n<li><strong>Favorite indicator</strong> — clears correctly after all messages are deleted\n(deleteEntry / clearAll); no longer persists stale data after app sync</li>\n<li><strong>MSG:X counter</strong> — hidden on HomeScreen while phone app is connected</li>\n<li><strong>RECENT/TRACKING pages</strong> — row limits now display-height-adaptive via\nmax_y variable instead of hardcoded values</li>\n</ul>\n<h3>Bug fixes</h3>\n<ul>\n<li><strong>BLE init: send_queue flood</strong> — between <code>onSecured()</code> and <code>CMD_APP_START</code>\nasync pushes could fill all 12 send_queue slots, causing the app to time\nout. Fixed via <code>_app_initialized</code> flag and <code>isWriteBusy()</code> guard</li>\n<li><strong>Double-counting in node counter</strong> — nodes heard via both advert and\nmessage were counted twice. Fixed via <code>countOnlineNodesExcluding()</code></li>\n<li><strong>adv_fresh buffer</strong> — was reusing the 4-entry RECENT display array,\ncapping the advert-based node count at 4. Now uses a dedicated\nADVERT_PATH_TABLE_SIZE (16) buffer</li>\n<li><strong>formatRelTime undefined behavior</strong> — replaced signed int cast with\nsafe uint32_t arithmetic</li>\n</ul>\n<h3>Technical notes</h3>\n<ul>\n<li>Changes confined to <code>UITask.cpp</code>, <code>UITask.h</code>, <code>MyMesh.cpp</code>, <code>MyMesh.h</code>,\n<code>icons.h</code></li>\n<li><code>DataStore</code>, <code>AbstractUITask</code>, <code>platformio.ini</code> unaffected</li>\n</ul>\n<h1>Download latest build</h1>\n<h2>EU Offgrid frequency</h2>\n<p><a href=\"https://github.com/user-attachments/files/26605877/ThinkNode_M1_companion_radio_ble_FieldMeshv5.2.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_FieldMeshv5.2.zip</a>\n<a href=\"https://github.com/user-attachments/files/26605890/WioTrackerL1_companion_radio_ble_FieldMeshv5.2.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_FieldMeshv5.2.zip</a>\n<a href=\"https://github.com/user-attachments/files/26605896/t1000e_companion_radio_ble_FieldMeshv5.2.zip\" target=\"_blank\" rel=\"noopener noreferrer\">t1000e_companion_radio_ble_FieldMeshv5.2.zip</a></p>\n<h2>US Offgrid frequency</h2>\n<p><a href=\"https://github.com/user-attachments/files/26605905/ThinkNode_M1_companion_radio_ble_USFieldMeshv5.2.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_USFieldMeshv5.2.zip</a>\n<a href=\"https://github.com/user-attachments/files/26605916/WioTrackerL1_companion_radio_ble_USFieldMeshv5.2.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_USFieldMeshv5.2.zip</a>\n<a href=\"https://github.com/user-attachments/files/26605923/t1000e_companion_radio_ble_USFieldMeshv5.2.zip\" target=\"_blank\" rel=\"noopener noreferrer\">t1000e_companion_radio_ble_USFieldMeshv5.2.zip</a></p>\n"
        },
        {
          "version": "v5.1",
          "name": "FieldMesh v5.1",
          "datetime": "2026-04-04T08:18:12Z",
          "url": "https://github.com/TogeriX-hub/FieldMesh/releases/tag/v5.1",
          "prerelease": false,
          "notes": "## [5.1] — Headless Device Support (T1000-E, RAK WiseMesh TAG)\r\n\r\n### New features\r\n- **Headless device support** — `ui-orig` now fully integrated into FieldMesh; devices with no display and a single button (Seeed T1000-E, RAK WiseMesh TAG) are supported as first-class citizens\r\n- **Off-Grid toggle via 5× click** — 5 presses on the single button toggles Off-Grid mode on/off; buzzer feedback is forced regardless of mute state (ascending tone = on, descending = off)\r\n- **SOS alarm via buzzer** — incoming `!SOS` messages trigger a continuous buzzer siren that overrides quiet mode and loops until acknowledged with a short press\r\n\r\n### Changes\r\n- All button actions (advert, GPS toggle, buzzer toggle, Off-Grid toggle) now produce forced buzzer feedback regardless of quiet mode — essential for display-less operation\r\n- Ascending tone (`c,e`) = feature enabled; descending tone (`e,c`) = feature disabled — consistent across all actions\r\n- `newMsg()` signature updated to include `is_favorite` parameter — compatible with V5 `AbstractUITask` interface\r\n- `refreshDisplay()` and `isOnRecentOrTrackingPage()` added as explicit no-op overrides — required for `MyMesh` compatibility\r\n\r\n### Button mapping (headless devices — single button)\r\n| Press | Action |\r\n|---|---|\r\n| 1× | Wake display / acknowledge SOS alarm |\r\n| 2× | Send advert |\r\n| 3× | Buzzer mute on/off |\r\n| 4× | GPS on/off |\r\n| 5× | Off-Grid mode on/off |\r\n| Long press (first 8 s) | CLI Rescue Mode |\r\n| Long press | Shutdown |\r\n\r\n### Technical notes\r\n- Changes confined to `ui-orig/Button.h`, `ui-orig/Button.cpp`, `ui-orig/UITask.h`, `ui-orig/UITask.cpp`\r\n- `ui-new` (ThinkNode M1, Wio Tracker L1) is completely unaffected\r\n- `_buzzer_restore_quiet` flag ensures non-blocking buzzer playback before quiet state is restored\r\n\r\n# Download latest build\r\n\r\n## EU Offgrid frequency\r\n[ThinkNode_M1_companion_radio_ble_FieldMeshv5.1.zip](https://github.com/user-attachments/files/26479266/ThinkNode_M1_companion_radio_ble_FieldMeshv5.1.zip)\r\n[WioTrackerL1_companion_radio_ble_FieldMeshv5.1.zip](https://github.com/user-attachments/files/26479268/WioTrackerL1_companion_radio_ble_FieldMeshv5.1.zip)\r\n[t1000e_companion_radio_ble_FieldMeshv5.1.zip](https://github.com/user-attachments/files/26479270/t1000e_companion_radio_ble_FieldMeshv5.1.zip)\r\n\r\n## US Offgrid frequency\r\n[ThinkNode_M1_companion_radio_ble_USFieldMeshv5.1.zip](https://github.com/user-attachments/files/26479519/ThinkNode_M1_companion_radio_ble_USFieldMeshv5.1.zip)\r\n[WioTrackerL1_companion_radio_ble_USFieldMeshv5.1.zip](https://github.com/user-attachments/files/26479520/WioTrackerL1_companion_radio_ble_USFieldMeshv5.1.zip)\r\n[t1000e_companion_radio_ble_USFieldMeshv5.1.zip](https://github.com/user-attachments/files/26479521/t1000e_companion_radio_ble_USFieldMeshv5.1.zip)",
          "notesHtml": "<h2>[5.1] — Headless Device Support (T1000-E, RAK WiseMesh TAG)</h2>\n<h3>New features</h3>\n<ul>\n<li><strong>Headless device support</strong> — <code>ui-orig</code> now fully integrated into FieldMesh; devices with no display and a single button (Seeed T1000-E, RAK WiseMesh TAG) are supported as first-class citizens</li>\n<li><strong>Off-Grid toggle via 5× click</strong> — 5 presses on the single button toggles Off-Grid mode on/off; buzzer feedback is forced regardless of mute state (ascending tone = on, descending = off)</li>\n<li><strong>SOS alarm via buzzer</strong> — incoming <code>!SOS</code> messages trigger a continuous buzzer siren that overrides quiet mode and loops until acknowledged with a short press</li>\n</ul>\n<h3>Changes</h3>\n<ul>\n<li>All button actions (advert, GPS toggle, buzzer toggle, Off-Grid toggle) now produce forced buzzer feedback regardless of quiet mode — essential for display-less operation</li>\n<li>Ascending tone (<code>c,e</code>) = feature enabled; descending tone (<code>e,c</code>) = feature disabled — consistent across all actions</li>\n<li><code>newMsg()</code> signature updated to include <code>is_favorite</code> parameter — compatible with V5 <code>AbstractUITask</code> interface</li>\n<li><code>refreshDisplay()</code> and <code>isOnRecentOrTrackingPage()</code> added as explicit no-op overrides — required for <code>MyMesh</code> compatibility</li>\n</ul>\n<h3>Button mapping (headless devices — single button)</h3>\n<table>\n<thead>\n<tr>\n<th>Press</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>1×</td>\n<td>Wake display / acknowledge SOS alarm</td>\n</tr>\n<tr>\n<td>2×</td>\n<td>Send advert</td>\n</tr>\n<tr>\n<td>3×</td>\n<td>Buzzer mute on/off</td>\n</tr>\n<tr>\n<td>4×</td>\n<td>GPS on/off</td>\n</tr>\n<tr>\n<td>5×</td>\n<td>Off-Grid mode on/off</td>\n</tr>\n<tr>\n<td>Long press (first 8 s)</td>\n<td>CLI Rescue Mode</td>\n</tr>\n<tr>\n<td>Long press</td>\n<td>Shutdown</td>\n</tr>\n</tbody></table>\n<h3>Technical notes</h3>\n<ul>\n<li>Changes confined to <code>ui-orig/Button.h</code>, <code>ui-orig/Button.cpp</code>, <code>ui-orig/UITask.h</code>, <code>ui-orig/UITask.cpp</code></li>\n<li><code>ui-new</code> (ThinkNode M1, Wio Tracker L1) is completely unaffected</li>\n<li><code>_buzzer_restore_quiet</code> flag ensures non-blocking buzzer playback before quiet state is restored</li>\n</ul>\n<h1>Download latest build</h1>\n<h2>EU Offgrid frequency</h2>\n<p><a href=\"https://github.com/user-attachments/files/26479266/ThinkNode_M1_companion_radio_ble_FieldMeshv5.1.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_FieldMeshv5.1.zip</a>\n<a href=\"https://github.com/user-attachments/files/26479268/WioTrackerL1_companion_radio_ble_FieldMeshv5.1.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_FieldMeshv5.1.zip</a>\n<a href=\"https://github.com/user-attachments/files/26479270/t1000e_companion_radio_ble_FieldMeshv5.1.zip\" target=\"_blank\" rel=\"noopener noreferrer\">t1000e_companion_radio_ble_FieldMeshv5.1.zip</a></p>\n<h2>US Offgrid frequency</h2>\n<p><a href=\"https://github.com/user-attachments/files/26479519/ThinkNode_M1_companion_radio_ble_USFieldMeshv5.1.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_USFieldMeshv5.1.zip</a>\n<a href=\"https://github.com/user-attachments/files/26479520/WioTrackerL1_companion_radio_ble_USFieldMeshv5.1.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_USFieldMeshv5.1.zip</a>\n<a href=\"https://github.com/user-attachments/files/26479521/t1000e_companion_radio_ble_USFieldMeshv5.1.zip\" target=\"_blank\" rel=\"noopener noreferrer\">t1000e_companion_radio_ble_USFieldMeshv5.1.zip</a></p>\n"
        },
        {
          "version": "v5.09",
          "name": "Release v5.09 — Message History & Text Input",
          "datetime": "2026-04-03T12:35:15Z",
          "url": "https://github.com/TogeriX-hub/FieldMesh/releases/tag/v5.09",
          "prerelease": false,
          "notes": "FieldMesh V5 — the first release that makes the node fully standalone for messaging. No phone required.\r\n\r\n## What's new\r\n\r\n### Message History (ThinkNode M1 + Wio Tracker L1)\r\n- Received messages are stored on the device and browsable without the companion app\r\n- Home screen redesigned: shows unread counter and the name + timestamp of the most recent message from a favourite contact\r\n- Long press on home screen opens the message menu (filter: All / Favourites)\r\n- One message per view, newest first — short press = next, long press = clear all\r\n- Channel tag (`[CH1]`, `[DM]`) and timestamp shown per message\r\n- New message while history is open: `+1 new` alert, no automatic screen switch\r\n\r\n### Text Input & Send (Wio Tracker L1 only)\r\n- Compose and send channel messages directly from the device via joystick\r\n- Channel select → character compose → \"Sent!\" confirmation\r\n- Character selection via joystick left/right, confirm with short press, send with long press\r\n- 80 character limit\r\n\r\n## Important notes\r\n- Message history is RAM-only — messages are lost on reboot. This is intentional: smartphone sync via the companion app is never affected by what the device shows or clears.\r\n- Text send is available on Wio Tracker L1 only. Single-button input on ThinkNode M1 does not support text composition.\r\n- No DM sending — channel messages only.\r\n\r\n## Files changed\r\n`UITask.h`, `UITask.cpp`, `MyMesh.h`, `MyMesh.cpp`, `AbstractUITask.h`\r\n\r\n## Full changelog\r\nSee [RELEASE.md](RELEASE.md) for the complete version history.\r\n\r\n[ThinkNode_M1_companion_radio_ble_FieldMeshv5.09.zip](https://github.com/user-attachments/files/26460200/ThinkNode_M1_companion_radio_ble_FieldMeshv5.09.zip)\r\n\r\n[WioTrackerL1_companion_radio_ble_FieldMeshv5.09.zip](https://github.com/user-attachments/files/26460205/WioTrackerL1_companion_radio_ble_FieldMeshv5.09.zip)",
          "notesHtml": "<p>FieldMesh V5 — the first release that makes the node fully standalone for messaging. No phone required.</p>\n<h2>What's new</h2>\n<h3>Message History (ThinkNode M1 + Wio Tracker L1)</h3>\n<ul>\n<li>Received messages are stored on the device and browsable without the companion app</li>\n<li>Home screen redesigned: shows unread counter and the name + timestamp of the most recent message from a favourite contact</li>\n<li>Long press on home screen opens the message menu (filter: All / Favourites)</li>\n<li>One message per view, newest first — short press = next, long press = clear all</li>\n<li>Channel tag (<code>[CH1]</code>, <code>[DM]</code>) and timestamp shown per message</li>\n<li>New message while history is open: <code>+1 new</code> alert, no automatic screen switch</li>\n</ul>\n<h3>Text Input &amp; Send (Wio Tracker L1 only)</h3>\n<ul>\n<li>Compose and send channel messages directly from the device via joystick</li>\n<li>Channel select → character compose → \"Sent!\" confirmation</li>\n<li>Character selection via joystick left/right, confirm with short press, send with long press</li>\n<li>80 character limit</li>\n</ul>\n<h2>Important notes</h2>\n<ul>\n<li>Message history is RAM-only — messages are lost on reboot. This is intentional: smartphone sync via the companion app is never affected by what the device shows or clears.</li>\n<li>Text send is available on Wio Tracker L1 only. Single-button input on ThinkNode M1 does not support text composition.</li>\n<li>No DM sending — channel messages only.</li>\n</ul>\n<h2>Files changed</h2>\n<p><code>UITask.h</code>, <code>UITask.cpp</code>, <code>MyMesh.h</code>, <code>MyMesh.cpp</code>, <code>AbstractUITask.h</code></p>\n<h2>Full changelog</h2>\n<p>See <a href=\"https://github.com/TogeriX-hub/FieldMesh/blob/HEAD/RELEASE.md\" target=\"_blank\" rel=\"noopener noreferrer\">RELEASE.md</a> for the complete version history.</p>\n<p><a href=\"https://github.com/user-attachments/files/26460200/ThinkNode_M1_companion_radio_ble_FieldMeshv5.09.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_FieldMeshv5.09.zip</a></p>\n<p><a href=\"https://github.com/user-attachments/files/26460205/WioTrackerL1_companion_radio_ble_FieldMeshv5.09.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_FieldMeshv5.09.zip</a></p>\n"
        },
        {
          "version": "v4.04",
          "name": "FieldMesh v4.04",
          "datetime": "2026-03-30T20:55:22Z",
          "url": "https://github.com/TogeriX-hub/FieldMesh/releases/tag/v4.04",
          "prerelease": false,
          "notes": "## V4.04 — Wio Tracker L1 Joystick UI Fixes\r\n\r\n\r\n### target.cpp / target.h\r\n- Added `joystick_up` (`JOYSTICK_UP`) and `joystick_down` (`JOYSTICK_DOWN`) as `MomentaryButton`\r\n\r\n### UITask.cpp — loop()\r\n- Joystick Up → `KEY_PREV`, Joystick Down → `KEY_NEXT`\r\n- Joystick press short → `KEY_ENTER` (confirm in menus)\r\n- Joystick press long → `handleLongPress()` (context action)\r\n\r\n### UITask.cpp — HomeScreen\r\n- Removed dead code: `KEY_ENTER` on Tracking page directly toggled GPS-Share — unused since V2.02 (Outdoor Menu), but accidentally active on Wio Tracker\r\n- Tracking hint text: `\"Settings: press Enter\"` (joystick) instead of `\"Settings: long press\"`\r\n\r\n### UITask.cpp — OutdoorMenuScreen\r\n- Removed footer `\"short=next long=select\"` on joystick devices (self-explanatory)\r\n- Menu navigation: Up/Down instead of Left/Right\r\n\r\n### UITask.cpp — SOSSendScreen\r\n- `handleLongPress()` now sends `KEY_SELECT` instead of `KEY_ENTER` to `SOSSendScreen` to distinguish short and long press\r\n- Short press = always go back (both states)\r\n- Long press = confirm / send (both states)\r\n- Hint text both states: `\"long press: SEND`\r\n\r\n[ThinkNode_M1_companion_radio_ble_FieldMeshv4.04.zip](https://github.com/user-attachments/files/26416861/ThinkNode_M1_companion_radio_ble_FieldMeshv4.04.zip)\r\n\r\n\r\n[WioTrackerL1_companion_radio_ble_FieldMeshv4.04.zip](https://github.com/user-attachments/files/26416618/WioTrackerL1_companion_radio_ble_FieldMeshv4.04.zip)",
          "notesHtml": "<h2>V4.04 — Wio Tracker L1 Joystick UI Fixes</h2>\n<h3>target.cpp / target.h</h3>\n<ul>\n<li>Added <code>joystick_up</code> (<code>JOYSTICK_UP</code>) and <code>joystick_down</code> (<code>JOYSTICK_DOWN</code>) as <code>MomentaryButton</code></li>\n</ul>\n<h3>UITask.cpp — loop()</h3>\n<ul>\n<li>Joystick Up → <code>KEY_PREV</code>, Joystick Down → <code>KEY_NEXT</code></li>\n<li>Joystick press short → <code>KEY_ENTER</code> (confirm in menus)</li>\n<li>Joystick press long → <code>handleLongPress()</code> (context action)</li>\n</ul>\n<h3>UITask.cpp — HomeScreen</h3>\n<ul>\n<li>Removed dead code: <code>KEY_ENTER</code> on Tracking page directly toggled GPS-Share — unused since V2.02 (Outdoor Menu), but accidentally active on Wio Tracker</li>\n<li>Tracking hint text: <code>\"Settings: press Enter\"</code> (joystick) instead of <code>\"Settings: long press\"</code></li>\n</ul>\n<h3>UITask.cpp — OutdoorMenuScreen</h3>\n<ul>\n<li>Removed footer <code>\"short=next long=select\"</code> on joystick devices (self-explanatory)</li>\n<li>Menu navigation: Up/Down instead of Left/Right</li>\n</ul>\n<h3>UITask.cpp — SOSSendScreen</h3>\n<ul>\n<li><code>handleLongPress()</code> now sends <code>KEY_SELECT</code> instead of <code>KEY_ENTER</code> to <code>SOSSendScreen</code> to distinguish short and long press</li>\n<li>Short press = always go back (both states)</li>\n<li>Long press = confirm / send (both states)</li>\n<li>Hint text both states: <code>\"long press: SEND</code></li>\n</ul>\n<p><a href=\"https://github.com/user-attachments/files/26416861/ThinkNode_M1_companion_radio_ble_FieldMeshv4.04.zip\" target=\"_blank\" rel=\"noopener noreferrer\">ThinkNode_M1_companion_radio_ble_FieldMeshv4.04.zip</a></p>\n<p><a href=\"https://github.com/user-attachments/files/26416618/WioTrackerL1_companion_radio_ble_FieldMeshv4.04.zip\" target=\"_blank\" rel=\"noopener noreferrer\">WioTrackerL1_companion_radio_ble_FieldMeshv4.04.zip</a></p>\n"
        },
        {
          "version": "v4.03",
          "name": "FieldMesh V4.03",
          "datetime": "2026-03-30T14:46:33Z",
          "url": "https://github.com/TogeriX-hub/FieldMesh/releases/tag/v4.03",
          "prerelease": false,
          "notes": "## V4.03 – Backlight & Display Logic Overhaul\r\n\r\n### Fixed\r\n- `AUTO_OFF_MILLIS=0` removed from `platformio.ini` – display now correctly sleeps after 15 seconds of inactivity\r\n- 5-minute backlight auto-off timer removed – no longer needed with display sleep active\r\n- Backlight now correctly follows `_backlight_on` state on every `turnOn()` call, overriding GxEPD driver behavior\r\n\r\n### Improved\r\n- Backlight state is fully decoupled from display wake events – incoming messages and adverts wake the display without changing the backlight state\r\n- Added `refreshDisplay()` – wakes display briefly on incoming adverts when on Recent or Tracking page, without affecting backlight\r\n- Advert-triggered display refresh works even when a phone is connected via BLE\r\n\r\n### Technical\r\n- Added `refreshDisplay()` and `isOnRecentOrTrackingPage()` to `AbstractUITask` as virtual methods\r\n- `_backlight_off_at` member removed from `UITask`",
          "notesHtml": "<h2>V4.03 – Backlight &amp; Display Logic Overhaul</h2>\n<h3>Fixed</h3>\n<ul>\n<li><code>AUTO_OFF_MILLIS=0</code> removed from <code>platformio.ini</code> – display now correctly sleeps after 15 seconds of inactivity</li>\n<li>5-minute backlight auto-off timer removed – no longer needed with display sleep active</li>\n<li>Backlight now correctly follows <code>_backlight_on</code> state on every <code>turnOn()</code> call, overriding GxEPD driver behavior</li>\n</ul>\n<h3>Improved</h3>\n<ul>\n<li>Backlight state is fully decoupled from display wake events – incoming messages and adverts wake the display without changing the backlight state</li>\n<li>Added <code>refreshDisplay()</code> – wakes display briefly on incoming adverts when on Recent or Tracking page, without affecting backlight</li>\n<li>Advert-triggered display refresh works even when a phone is connected via BLE</li>\n</ul>\n<h3>Technical</h3>\n<ul>\n<li>Added <code>refreshDisplay()</code> and <code>isOnRecentOrTrackingPage()</code> to <code>AbstractUITask</code> as virtual methods</li>\n<li><code>_backlight_off_at</code> member removed from <code>UITask</code></li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:30.022Z"
    },
    {
      "id": "mclite",
      "name": "MCLite",
      "type": "fork",
      "maintainer": "laserir",
      "description": "A lightweight off-grid communicator firmware for the LilyGo T-Deck Plus and T-Watch Ultra. Purpose-built for emergency and outdoor communication — no internet, no cell towers needed. SD card configuration, web flasher, and room server support. Compatible with MeshCore apps.\n",
      "repository": "https://github.com/laserir/MCLite",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion"
      ],
      "features": [
        "Web flasher (Chrome/Edge)",
        "SD card configuration (one person sets up, copies to everyone)",
        "Room server support (up to 8)",
        "On-screen keyboard",
        "GPS support",
        "No accounts, no pairing, no per-device setup"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": false,
          "wifiAp": false
        },
        "operations": {
          "ota": false,
          "webFlasher": true
        },
        "networking": {
          "repeater": false,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-t-deck",
          "status": "supported",
          "notes": "T-Deck Plus — primary target with QWERTY keyboard, trackball, GPS."
        },
        {
          "id": "lilygo-twatch-s3",
          "status": "supported",
          "notes": "T-Watch Ultra — wrist-worn with AMOLED touchscreen."
        }
      ],
      "popularity": {
        "githubStars": 17,
        "githubForks": 2,
        "githubWatchers": 3,
        "githubOpenIssues": 2,
        "githubContributors": 3,
        "releaseDownloads": 179,
        "latestReleaseDownloads": 6,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": true,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "0.3.9",
      "released": "2026-06-21",
      "releases": [
        {
          "version": "v0.3.9",
          "name": "0.3.9",
          "datetime": "2026-06-21T08:09:35Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.9",
          "prerelease": false,
          "notes": "### Added\n- **Step-wise admin permissions.** Beyond the existing `security.admin_enabled` (global on/off for the Admin\n  screen), a new `permissions` config block scopes what's reachable *inside* Admin: `permissions.settings`\n  (`full` / `restricted` / `none`) — **restricted** keeps only the basics editable (brightness, auto-dim, dim\n  brightness, keyboard brightness, theme) and shows everything else read-only (no chevron); **none** makes all\n  settings read-only. `permissions.companion` (default on) hides the Companion group (WiFi/USB/Bluetooth) when\n  off — configured services still run. `permissions.conversation_management` (default off) is reserved for a\n  future release (on-device add/edit/remove of contacts/channels/rooms; they stay read-only views for now). All\n  three are provisionable from the config tool. Defaults are fully permissive, so existing configs are unchanged.\n- **Settings reorganised into per-section screens + Admin is now a pure hub.** The on-device Admin screen no\n  longer mixes settings, diagnostics and shortcuts — it's three labelled groups of links: **Companion** (WiFi /\n  USB / Bluetooth), **Conversations** (Contacts / Channels / Rooms, read-only views), and **Settings** (Device,\n  Radio, Display, Messaging, Sound, GPS, Battery, Security). Each section is its own screen mirroring the config\n  tool, with all of its editable settings *and* its read-only diagnostics in one place (no more duplicated rows\n  across Admin and Device Settings). Newly editable on-device: **Radio** (region preset picker — EU/UK/CH vs\n  US/Canada — plus a TX-power slider and an advert-interval picker; frequency/SF/BW/CR/scope/path-hash stay read-only),\n  **Messaging** (history, max-per-chat, location format, retries, telemetry request/badges/auto-refresh, canned\n  messages, allow-mute), and **GPS** (enable, location-advert precision, timezone, clock offset, last-known max\n  age). Offgrid mode and the live Heard-Adverts count now live at the top of the Radio screen. Each hub link\n  carries an icon (gear for settings; `@`/`#`/`R` for contacts/channels/rooms; Wi-Fi/USB/Bluetooth for\n  companion), and the 3rd-party licenses moved to an *About* block at the bottom of the hub. Radio/GPS changes\n  reboot once on exit (same batched-save model as theme/language). The old single \"Device Settings\" screen is\n  superseded by this layout.\n- **Selectable UI themes.** Choose a color palette — **Dark** (default), **Light**, **Amber** (a \"military\"\n  night mode that preserves night vision), or **High contrast** — on-device (Admin → Theme, reboots to apply)\n  or via `display.theme` in config. Custom palettes can be defined under `display.themes` (start from a built-in\n  `base`, override any color with `#RRGGBB`). Default appearance is unchanged. On/off switches now use the\n  theme accent colour too. Thanks [@jason-s13r](https://github.com/jason-s13r) (#24).\n- **Per-row Info + Map buttons on the Heard Adverts screen.** Each heard node now has an explicit info (eye)\n  button that opens its detail dialog, and — when the advert carries a location — a map button that opens the\n  map centered on that node. Back now returns to the Admin screen. Thanks [@jason-s13r](https://github.com/jason-s13r) (#15).\n- **Map screen pan buttons + windowed chrome.** The map gains an on-screen D-pad (up/left/centre/right/down)\n  alongside the existing drag-to-pan. On the T-Deck the map now keeps the **status bar visible** and uses the\n  standard `lv_win` header with a back button (the T-Watch stays full-screen). Thanks [@jason-s13r](https://github.com/jason-s13r) (#22, supersedes #20/#21).\n- **Uptime + last-charged in the Admin Battery section.** Shows when the device booted (wall-clock + relative)\n  and when charging last stopped (with the level at the time). Thanks [@jason-s13r](https://github.com/jason-s13r) (#23).\n- **On-device Device Settings.** A new editable settings screen (Admin → Device Settings, behind the existing\n  `admin.enabled` gate) for changing device n\n…",
          "notesHtml": "<h3>Added</h3>\n<ul>\n<li><strong>Step-wise admin permissions.</strong> Beyond the existing <code>security.admin_enabled</code> (global on/off for the Admin\nscreen), a new <code>permissions</code> config block scopes what's reachable <em>inside</em> Admin: <code>permissions.settings</code>\n(<code>full</code> / <code>restricted</code> / <code>none</code>) — <strong>restricted</strong> keeps only the basics editable (brightness, auto-dim, dim\nbrightness, keyboard brightness, theme) and shows everything else read-only (no chevron); <strong>none</strong> makes all\nsettings read-only. <code>permissions.companion</code> (default on) hides the Companion group (WiFi/USB/Bluetooth) when\noff — configured services still run. <code>permissions.conversation_management</code> (default off) is reserved for a\nfuture release (on-device add/edit/remove of contacts/channels/rooms; they stay read-only views for now). All\nthree are provisionable from the config tool. Defaults are fully permissive, so existing configs are unchanged.</li>\n<li><strong>Settings reorganised into per-section screens + Admin is now a pure hub.</strong> The on-device Admin screen no\nlonger mixes settings, diagnostics and shortcuts — it's three labelled groups of links: <strong>Companion</strong> (WiFi /\nUSB / Bluetooth), <strong>Conversations</strong> (Contacts / Channels / Rooms, read-only views), and <strong>Settings</strong> (Device,\nRadio, Display, Messaging, Sound, GPS, Battery, Security). Each section is its own screen mirroring the config\ntool, with all of its editable settings <em>and</em> its read-only diagnostics in one place (no more duplicated rows\nacross Admin and Device Settings). Newly editable on-device: <strong>Radio</strong> (region preset picker — EU/UK/CH vs\nUS/Canada — plus a TX-power slider and an advert-interval picker; frequency/SF/BW/CR/scope/path-hash stay read-only),\n<strong>Messaging</strong> (history, max-per-chat, location format, retries, telemetry request/badges/auto-refresh, canned\nmessages, allow-mute), and <strong>GPS</strong> (enable, location-advert precision, timezone, clock offset, last-known max\nage). Offgrid mode and the live Heard-Adverts count now live at the top of the Radio screen. Each hub link\ncarries an icon (gear for settings; <code>@</code>/<code>#</code>/<code>R</code> for contacts/channels/rooms; Wi-Fi/USB/Bluetooth for\ncompanion), and the 3rd-party licenses moved to an <em>About</em> block at the bottom of the hub. Radio/GPS changes\nreboot once on exit (same batched-save model as theme/language). The old single \"Device Settings\" screen is\nsuperseded by this layout.</li>\n<li><strong>Selectable UI themes.</strong> Choose a color palette — <strong>Dark</strong> (default), <strong>Light</strong>, <strong>Amber</strong> (a \"military\"\nnight mode that preserves night vision), or <strong>High contrast</strong> — on-device (Admin → Theme, reboots to apply)\nor via <code>display.theme</code> in config. Custom palettes can be defined under <code>display.themes</code> (start from a built-in\n<code>base</code>, override any color with <code>#RRGGBB</code>). Default appearance is unchanged. On/off switches now use the\ntheme accent colour too. Thanks <a href=\"https://github.com/jason-s13r\" target=\"_blank\" rel=\"noopener noreferrer\">@jason-s13r</a> (#24).</li>\n<li><strong>Per-row Info + Map buttons on the Heard Adverts screen.</strong> Each heard node now has an explicit info (eye)\nbutton that opens its detail dialog, and — when the advert carries a location — a map button that opens the\nmap centered on that node. Back now returns to the Admin screen. Thanks <a href=\"https://github.com/jason-s13r\" target=\"_blank\" rel=\"noopener noreferrer\">@jason-s13r</a> (#15).</li>\n<li><strong>Map screen pan buttons + windowed chrome.</strong> The map gains an on-screen D-pad (up/left/centre/right/down)\nalongside the existing drag-to-pan. On the T-Deck the map now keeps the <strong>status bar visible</strong> and uses the\nstandard <code>lv_win</code> header with a back button (the T-Watch stays full-screen). Thanks <a href=\"https://github.com/jason-s13r\" target=\"_blank\" rel=\"noopener noreferrer\">@jason-s13r</a> (#22, supersedes #20/#21).</li>\n<li><strong>Uptime + last-charged in the Admin Battery section.</strong> Shows when the device booted (wall-clock + relative)\nand when charging last stopped (with the level at the time). Thanks <a href=\"https://github.com/jason-s13r\" target=\"_blank\" rel=\"noopener noreferrer\">@jason-s13r</a> (#23).</li>\n<li><strong>On-device Device Settings.</strong> A new editable settings screen (Admin → Device Settings, behind the existing\n<code>admin.enabled</code> gate) for changing device n\n…</li>\n</ul>\n"
        },
        {
          "version": "v0.3.8",
          "name": "MCLite 0.3.8",
          "datetime": "2026-06-16T09:19:15Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.8",
          "prerelease": false,
          "notes": "## Highlights\n\n**Less advert spam, more location privacy.**\n\n### Added\n- **Location-advert privacy precision.** The location-advert setting (now `gps.location_precision`) can coarsen the position you broadcast: **Off · Exact · ~100 m · ~750 m · ~3 km · ~12 km · ~50 km** (Meshtastic-style grid snapping, centred in the cell). Only the broadcast advert is coarsened — **telemetry replies to authorized contacts and the in-chat GPS insert always use your exact position**. Default off; old `location_advert: true/false` configs are read automatically. Scheme adopted from @jason-s13r.\n- **Zero-hop \"Local\" advert button** on the Heard Adverts screen — announce yourself to immediate neighbours without flooding the whole mesh.\n\n### Changed\n- **No more periodic flood adverts by default** (#13). MCLite previously flooded a mesh-wide advert every ~9 min; on a 110-repeater mesh one device generated ~half of all adverts. Now it sends a single flood advert **on boot** and otherwise advertises **on demand** — matching stock MeshCore clients. Thanks @stucamp and @jason-s13r.\n- **Opt-in periodic advert** — new `radio.advert_interval_min` field (config tool → Radio) re-enables periodic adverts for ad-hoc / SAR / private meshes. Default 0 = off; if set, enforced to ≥60 min (720 / 12 h recommended).\n- **GPS button inserts your location into the message** instead of a \"Send Location?\" confirm — append `@ <coords>` to the input, add context, send normally (byte-guarded against the 160-byte limit).\n\n---\nFlash from the web flasher or grab the merged `.bin` below. T-Deck Plus: `mclite-v0.3.8.bin` · T-Watch Ultra: `mclite-watch-v0.3.8.bin`.",
          "notesHtml": "<h2>Highlights</h2>\n<p><strong>Less advert spam, more location privacy.</strong></p>\n<h3>Added</h3>\n<ul>\n<li><strong>Location-advert privacy precision.</strong> The location-advert setting (now <code>gps.location_precision</code>) can coarsen the position you broadcast: <strong>Off · Exact · ~100 m · ~750 m · ~3 km · ~12 km · ~50 km</strong> (Meshtastic-style grid snapping, centred in the cell). Only the broadcast advert is coarsened — <strong>telemetry replies to authorized contacts and the in-chat GPS insert always use your exact position</strong>. Default off; old <code>location_advert: true/false</code> configs are read automatically. Scheme adopted from @jason-s13r.</li>\n<li><strong>Zero-hop \"Local\" advert button</strong> on the Heard Adverts screen — announce yourself to immediate neighbours without flooding the whole mesh.</li>\n</ul>\n<h3>Changed</h3>\n<ul>\n<li><strong>No more periodic flood adverts by default</strong> (#13). MCLite previously flooded a mesh-wide advert every ~9 min; on a 110-repeater mesh one device generated ~half of all adverts. Now it sends a single flood advert <strong>on boot</strong> and otherwise advertises <strong>on demand</strong> — matching stock MeshCore clients. Thanks @stucamp and @jason-s13r.</li>\n<li><strong>Opt-in periodic advert</strong> — new <code>radio.advert_interval_min</code> field (config tool → Radio) re-enables periodic adverts for ad-hoc / SAR / private meshes. Default 0 = off; if set, enforced to ≥60 min (720 / 12 h recommended).</li>\n<li><strong>GPS button inserts your location into the message</strong> instead of a \"Send Location?\" confirm — append <code>@ &lt;coords&gt;</code> to the input, add context, send normally (byte-guarded against the 160-byte limit).</li>\n</ul>\n<hr />\n<p>Flash from the web flasher or grab the merged <code>.bin</code> below. T-Deck Plus: <code>mclite-v0.3.8.bin</code> · T-Watch Ultra: <code>mclite-watch-v0.3.8.bin</code>.</p>\n"
        },
        {
          "version": "v0.3.7",
          "name": "MCLite 0.3.7",
          "datetime": "2026-06-15T09:34:57Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.7",
          "prerelease": false,
          "notes": "MCLite 0.3.7 — tappable map coordinates, lv_win screen chrome, and on-device screenshots.\n\n## Added\n- **Tap a shared location to open it on the map.** A received/sent message containing a GPS position — decimal `lat, lon` or MGRS/UTMREF — shows an underlined \"Open in map\" link under the bubble; tapping it opens the map centered there. Touch-only, shown only when map tiles are present on SD. Adds a reverse MGRS→lat/lon parser, unit-tested.\n- **Screenshot to SD** (debug aid, off by default). Enable `debug.screenshots` (config tool → Display) and capture the current screen to `/screenshots/*.bmp` (24-bit BMP, opens on any PC) — T-Deck: **Shift+$**; T-Watch: **double-press the side (PEK) button**. (Top-layer overlays like toasts/PIN/SOS aren't captured.)\n\n## Changed\n- **Heard Adverts** screen now uses the standard `lv_win` chrome (back arrow + title + action buttons) — the first step of rolling consistent screen headers across the app (community PR #8, @jason-s13r).\n\n## Removed\n- The non-functional Alt+L \"insert location\" keyboard shortcut (the chat GPS button already does this).\n\n## Notes\n- Config tool: \"Save screenshots\" toggle (Display); Security section relayout (Lock + Auto Lock on one line, Admin Screen separate).\n- Both boards (T-Deck Plus, T-Watch Ultra) build; 246 native tests pass.",
          "notesHtml": "<p>MCLite 0.3.7 — tappable map coordinates, lv_win screen chrome, and on-device screenshots.</p>\n<h2>Added</h2>\n<ul>\n<li><strong>Tap a shared location to open it on the map.</strong> A received/sent message containing a GPS position — decimal <code>lat, lon</code> or MGRS/UTMREF — shows an underlined \"Open in map\" link under the bubble; tapping it opens the map centered there. Touch-only, shown only when map tiles are present on SD. Adds a reverse MGRS→lat/lon parser, unit-tested.</li>\n<li><strong>Screenshot to SD</strong> (debug aid, off by default). Enable <code>debug.screenshots</code> (config tool → Display) and capture the current screen to <code>/screenshots/*.bmp</code> (24-bit BMP, opens on any PC) — T-Deck: <strong>Shift+$</strong>; T-Watch: <strong>double-press the side (PEK) button</strong>. (Top-layer overlays like toasts/PIN/SOS aren't captured.)</li>\n</ul>\n<h2>Changed</h2>\n<ul>\n<li><strong>Heard Adverts</strong> screen now uses the standard <code>lv_win</code> chrome (back arrow + title + action buttons) — the first step of rolling consistent screen headers across the app (community PR #8, @jason-s13r).</li>\n</ul>\n<h2>Removed</h2>\n<ul>\n<li>The non-functional Alt+L \"insert location\" keyboard shortcut (the chat GPS button already does this).</li>\n</ul>\n<h2>Notes</h2>\n<ul>\n<li>Config tool: \"Save screenshots\" toggle (Display); Security section relayout (Lock + Auto Lock on one line, Admin Screen separate).</li>\n<li>Both boards (T-Deck Plus, T-Watch Ultra) build; 246 native tests pass.</li>\n</ul>\n"
        },
        {
          "version": "v0.3.6",
          "name": "MCLite 0.3.6",
          "datetime": "2026-06-12T09:45:06Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.6",
          "prerelease": false,
          "notes": "MCLite 0.3.6 — emoji, three-step volume, and reliability polish.\n\n## Added\n- **Emoji in chat** — received emoji render inline (monochrome OpenMoji font with a Montserrat fallback, so plain text is unchanged and unknown glyphs degrade gracefully). An on-device emoji picker (`display.emoji`, default on, can be disabled) adds a smiley button to compose from a curated set, capped to the 160-byte message budget. Incoming/outgoing text is sanitized (strips emoji variation selectors, normalizes smart quotes to ASCII). Adopted from the @jason-s13r fork; OpenMoji is CC-BY-SA 4.0.\n- **Three-step volume** — the status-bar bell now cycles max → mute → mid → max; the built-in chime and custom WAV notifications scale to the level. Default is max (loudness unchanged); SOS stays fixed and loud (@jason-s13r, #11).\n\n## Changed\n- **`sound.enabled` is now a true master switch.** `false` means fully silent — no notifications, no chime, and no SOS sound — and the status-bar bell is hidden. Set `true` (the default) for the 3-step volume bell.\n\n## Fixed\n- A last-known position restored after reboot no longer reports \"~0s ago\" before the clock has synced — it shows \"Last known position\" until GPS/NTP re-locks, then the real age.\n- A failed send now shows a \"Send failed - try again\" toast instead of a silently FAILED bubble (still tap-to-retry).\n- Map tile loader hardening: oversized/corrupt PNGs and out-of-range tile coordinates are rejected and grey-filled cleanly.\n\nBoth boards (T-Deck Plus, T-Watch Ultra) build; 219 native tests pass.",
          "notesHtml": "<p>MCLite 0.3.6 — emoji, three-step volume, and reliability polish.</p>\n<h2>Added</h2>\n<ul>\n<li><strong>Emoji in chat</strong> — received emoji render inline (monochrome OpenMoji font with a Montserrat fallback, so plain text is unchanged and unknown glyphs degrade gracefully). An on-device emoji picker (<code>display.emoji</code>, default on, can be disabled) adds a smiley button to compose from a curated set, capped to the 160-byte message budget. Incoming/outgoing text is sanitized (strips emoji variation selectors, normalizes smart quotes to ASCII). Adopted from the @jason-s13r fork; OpenMoji is CC-BY-SA 4.0.</li>\n<li><strong>Three-step volume</strong> — the status-bar bell now cycles max → mute → mid → max; the built-in chime and custom WAV notifications scale to the level. Default is max (loudness unchanged); SOS stays fixed and loud (@jason-s13r, #11).</li>\n</ul>\n<h2>Changed</h2>\n<ul>\n<li><strong><code>sound.enabled</code> is now a true master switch.</strong> <code>false</code> means fully silent — no notifications, no chime, and no SOS sound — and the status-bar bell is hidden. Set <code>true</code> (the default) for the 3-step volume bell.</li>\n</ul>\n<h2>Fixed</h2>\n<ul>\n<li>A last-known position restored after reboot no longer reports \"~0s ago\" before the clock has synced — it shows \"Last known position\" until GPS/NTP re-locks, then the real age.</li>\n<li>A failed send now shows a \"Send failed - try again\" toast instead of a silently FAILED bubble (still tap-to-retry).</li>\n<li>Map tile loader hardening: oversized/corrupt PNGs and out-of-range tile coordinates are rejected and grey-filled cleanly.</li>\n</ul>\n<p>Both boards (T-Deck Plus, T-Watch Ultra) build; 219 native tests pass.</p>\n"
        },
        {
          "version": "v0.3.5",
          "name": "v0.3.5 — i18n cap + config-tool WiFi-wipe fixes",
          "datetime": "2026-06-11T10:32:26Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.5",
          "prerelease": false,
          "notes": "### Fixed\n- **Translations past ~128 keys reverted to English.** The i18n loader capped SD-loaded strings at 128, but the\n  language files now hold ~197 keys — so on German/French/Italian every key past the cap silently fell back to\n  English (e.g. `canned_5`–`8`, plus the offgrid / firmware-update / WiFi / USB / BLE / map / heard-adverts /\n  toast screens). Raised the cap to 256 and added a boot-time warning if a language file ever exceeds it.\n- **Config tool wiped stored WiFi on edit.** The tool's file-import never loaded the `wifi` section, so\n  importing a device's `config.json`, editing it, and re-exporting produced an empty `wifi` block — clearing\n  the device's stored SSID/password on the next copy to SD. WiFi (and the persisted BLE pairing PIN) now\n  round-trip correctly, including through the share-link and start-fresh paths.",
          "notesHtml": "<h3>Fixed</h3>\n<ul>\n<li><strong>Translations past ~128 keys reverted to English.</strong> The i18n loader capped SD-loaded strings at 128, but the\nlanguage files now hold ~197 keys — so on German/French/Italian every key past the cap silently fell back to\nEnglish (e.g. <code>canned_5</code>–<code>8</code>, plus the offgrid / firmware-update / WiFi / USB / BLE / map / heard-adverts /\ntoast screens). Raised the cap to 256 and added a boot-time warning if a language file ever exceeds it.</li>\n<li><strong>Config tool wiped stored WiFi on edit.</strong> The tool's file-import never loaded the <code>wifi</code> section, so\nimporting a device's <code>config.json</code>, editing it, and re-exporting produced an empty <code>wifi</code> block — clearing\nthe device's stored SSID/password on the next copy to SD. WiFi (and the persisted BLE pairing PIN) now\nround-trip correctly, including through the share-link and start-fresh paths.</li>\n</ul>\n"
        },
        {
          "version": "v0.3.4",
          "name": "v0.3.4 — Quick replies, auto-GPS refresh, companion advert + fixes",
          "datetime": "2026-06-11T10:03:31Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.4",
          "prerelease": false,
          "notes": "### Added\n- **Auto-refresh contact GPS** — keeps the map markers / convo-list badges of contacts who *don't* broadcast\n  their own location fresh, by quietly re-requesting telemetry GPS before the cached fix goes stale. Throttled\n  (one request per scan, respects the EU duty cycle, yields to manual requests) and self-limiting (stops asking\n  a contact that doesn't answer). New setting `messaging.auto_telemetry`, **default on**, can be disabled.\n- **Per-conversation quick replies** — any contact, channel, or room can carry its own `canned` list (max 8)\n  that overrides the global quick-reply list *for that chat only*; leave it empty to fall back to the global\n  list. Editable per card in the config tool. Turns a conversation into a command menu — e.g. a Home Assistant\n  / automation bridge (\"Open gate\", \"Lights on\", \"Status?\").\n- **Last-known location persists across reboots** — the most recent GPS fix is saved to SD\n  (`/mclite/last_location.json`, throttled) and restored on boot, so the map opens to your last position\n  without waiting for a fresh fix ([@jason-s13r](https://github.com/jason-s13r), #10).\n- **Advertise from the companion app** — the MeshCore phone/desktop app's **Advertise** button now works while\n  connected (BLE/WiFi/USB); previously it was rejected as an unsupported command. Honours the app's flood vs\n  local (zero-hop) option. The on-device advert button and the automatic periodic advert are unchanged.\n\n### Changed\n- The device-info / admin screen is now fully localized — every row label routes through the translation\n  table (de/fr/it) ([@jason-s13r](https://github.com/jason-s13r), #9).\n- Conversation history now loads only the most recent `max_history_per_chat` messages per chat at boot\n  (previously the whole file was loaded into RAM). Bounds memory if a history file is larger than the cap —\n  e.g. after lowering the setting. No visible change; the runtime cap was already in place.\n\n### Fixed\n- Telemetry retry is no longer cancelled by the contact-info pop-up's own timeout when the mesh's outbound\n  queue is busy (the two timers now stay in lockstep) — the retry fires under congestion as intended.\n- Closing the contact-info pop-up now cancels its in-flight telemetry retry, so no stray flood request goes\n  out for a pop-up you already closed.\n- Muting a chat is now absolute: it silences notifications even for a contact flagged `always_sound`\n  (`always_sound` still overrides *global* mute, unchanged).\n- Messages that exceed the 160-**byte** limit (e.g. emoji or accented/non-Latin text — which can be ≤160\n  *characters* but more bytes) are now refused with a \"Message too long\" toast that keeps your text, instead\n  of silently failing to send while still drawing a (failed) bubble.\n- A timed-out telemetry request now releases the radio's single telemetry slot when the exchange ends\n  (previously the slot stayed held after a no-response request). Without this, **auto-refresh contact GPS**\n  would stall for the rest of the session after the first contact that didn't answer, and slow/multi-hop\n  contacts could be backed off too eagerly; both are resolved.\n- Auto-refresh no longer lets a single un-sendable contact block the rest of the round-robin, and\n  `max_history_per_chat: 0` now consistently means \"unlimited\" on both load and prune (previously prune at 0\n  would wipe the conversation).",
          "notesHtml": "<h3>Added</h3>\n<ul>\n<li><strong>Auto-refresh contact GPS</strong> — keeps the map markers / convo-list badges of contacts who <em>don't</em> broadcast\ntheir own location fresh, by quietly re-requesting telemetry GPS before the cached fix goes stale. Throttled\n(one request per scan, respects the EU duty cycle, yields to manual requests) and self-limiting (stops asking\na contact that doesn't answer). New setting <code>messaging.auto_telemetry</code>, <strong>default on</strong>, can be disabled.</li>\n<li><strong>Per-conversation quick replies</strong> — any contact, channel, or room can carry its own <code>canned</code> list (max 8)\nthat overrides the global quick-reply list <em>for that chat only</em>; leave it empty to fall back to the global\nlist. Editable per card in the config tool. Turns a conversation into a command menu — e.g. a Home Assistant\n/ automation bridge (\"Open gate\", \"Lights on\", \"Status?\").</li>\n<li><strong>Last-known location persists across reboots</strong> — the most recent GPS fix is saved to SD\n(<code>/mclite/last_location.json</code>, throttled) and restored on boot, so the map opens to your last position\nwithout waiting for a fresh fix (<a href=\"https://github.com/jason-s13r\" target=\"_blank\" rel=\"noopener noreferrer\">@jason-s13r</a>, #10).</li>\n<li><strong>Advertise from the companion app</strong> — the MeshCore phone/desktop app's <strong>Advertise</strong> button now works while\nconnected (BLE/WiFi/USB); previously it was rejected as an unsupported command. Honours the app's flood vs\nlocal (zero-hop) option. The on-device advert button and the automatic periodic advert are unchanged.</li>\n</ul>\n<h3>Changed</h3>\n<ul>\n<li>The device-info / admin screen is now fully localized — every row label routes through the translation\ntable (de/fr/it) (<a href=\"https://github.com/jason-s13r\" target=\"_blank\" rel=\"noopener noreferrer\">@jason-s13r</a>, #9).</li>\n<li>Conversation history now loads only the most recent <code>max_history_per_chat</code> messages per chat at boot\n(previously the whole file was loaded into RAM). Bounds memory if a history file is larger than the cap —\ne.g. after lowering the setting. No visible change; the runtime cap was already in place.</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>Telemetry retry is no longer cancelled by the contact-info pop-up's own timeout when the mesh's outbound\nqueue is busy (the two timers now stay in lockstep) — the retry fires under congestion as intended.</li>\n<li>Closing the contact-info pop-up now cancels its in-flight telemetry retry, so no stray flood request goes\nout for a pop-up you already closed.</li>\n<li>Muting a chat is now absolute: it silences notifications even for a contact flagged <code>always_sound</code>\n(<code>always_sound</code> still overrides <em>global</em> mute, unchanged).</li>\n<li>Messages that exceed the 160-<strong>byte</strong> limit (e.g. emoji or accented/non-Latin text — which can be ≤160\n<em>characters</em> but more bytes) are now refused with a \"Message too long\" toast that keeps your text, instead\nof silently failing to send while still drawing a (failed) bubble.</li>\n<li>A timed-out telemetry request now releases the radio's single telemetry slot when the exchange ends\n(previously the slot stayed held after a no-response request). Without this, <strong>auto-refresh contact GPS</strong>\nwould stall for the rest of the session after the first contact that didn't answer, and slow/multi-hop\ncontacts could be backed off too eagerly; both are resolved.</li>\n<li>Auto-refresh no longer lets a single un-sendable contact block the rest of the round-robin, and\n<code>max_history_per_chat: 0</code> now consistently means \"unlimited\" on both load and prune (previously prune at 0\nwould wipe the conversation).</li>\n</ul>\n"
        },
        {
          "version": "v0.3.3",
          "name": "v0.3.3 — Unified contact location + reliability batch",
          "datetime": "2026-06-10T16:51:48Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.3",
          "prerelease": false,
          "notes": "Contact-location and delivery-reliability improvements, plus a batch of community contributions from [@jason-s13r](https://github.com/jason-s13r).\n\n## Added\n- **Unified contact location** — one source of truth for where a contact is: fresh telemetry (accurate) → their advert GPS → a heard advert. The conversation-list **GPS badge** now shows for *any* known position (not just telemetry); the **contact info pop-up** shows that position even without a telemetry reply (advert-sourced coordinates are marked approximate with `~`), offers the **Map** button whenever any position is known, and on a request timeout shows the known position instead of a bare \"No response\". Telemetry stays primary; the 30-minute freshness window is unchanged.\n- **Flood-routing retries** for better delivery when a direct path degrades — on **DM** retries and on **telemetry-request** retries (with a \"Retrying…\" state).\n- **Per-chat mute** — opt-in (`messaging.allow_mute`, default off). Long-press a conversation to mute; muted chats don't beep or wake the screen (SOS always does), with an indicator in the list and chat header.\n- **Vendor row** on the device-info screen showing the firmware's source repo (`owner/repo`) — handy with fork flashing.\n\n## Fixed\n- Chat scroll-to-bottom is more robust on an empty chat area / on open.\n\n## Thanks\n- @jason-s13r for PRs #3–#7.\n\nInstall/update via the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/), or on-device (SD card / WiFi). Binaries: `mclite-v0.3.3.bin` (T-Deck Plus), `mclite-watch-v0.3.3.bin` (T-Watch Ultra).\n\n**Full Changelog**: https://github.com/laserir/MCLite/compare/v0.3.2...v0.3.3",
          "notesHtml": "<p>Contact-location and delivery-reliability improvements, plus a batch of community contributions from <a href=\"https://github.com/jason-s13r\" target=\"_blank\" rel=\"noopener noreferrer\">@jason-s13r</a>.</p>\n<h2>Added</h2>\n<ul>\n<li><strong>Unified contact location</strong> — one source of truth for where a contact is: fresh telemetry (accurate) → their advert GPS → a heard advert. The conversation-list <strong>GPS badge</strong> now shows for <em>any</em> known position (not just telemetry); the <strong>contact info pop-up</strong> shows that position even without a telemetry reply (advert-sourced coordinates are marked approximate with <code>~</code>), offers the <strong>Map</strong> button whenever any position is known, and on a request timeout shows the known position instead of a bare \"No response\". Telemetry stays primary; the 30-minute freshness window is unchanged.</li>\n<li><strong>Flood-routing retries</strong> for better delivery when a direct path degrades — on <strong>DM</strong> retries and on <strong>telemetry-request</strong> retries (with a \"Retrying…\" state).</li>\n<li><strong>Per-chat mute</strong> — opt-in (<code>messaging.allow_mute</code>, default off). Long-press a conversation to mute; muted chats don't beep or wake the screen (SOS always does), with an indicator in the list and chat header.</li>\n<li><strong>Vendor row</strong> on the device-info screen showing the firmware's source repo (<code>owner/repo</code>) — handy with fork flashing.</li>\n</ul>\n<h2>Fixed</h2>\n<ul>\n<li>Chat scroll-to-bottom is more robust on an empty chat area / on open.</li>\n</ul>\n<h2>Thanks</h2>\n<ul>\n<li>@jason-s13r for PRs #3–#7.</li>\n</ul>\n<p>Install/update via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a>, or on-device (SD card / WiFi). Binaries: <code>mclite-v0.3.3.bin</code> (T-Deck Plus), <code>mclite-watch-v0.3.3.bin</code> (T-Watch Ultra).</p>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/laserir/MCLite/compare/v0.3.2...v0.3.3\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/laserir/MCLite/compare/v0.3.2...v0.3.3</a></p>\n"
        },
        {
          "version": "v0.3.2",
          "name": "v0.3.2 — Unified map + review fixes",
          "datetime": "2026-06-09T11:03:17Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.2",
          "prerelease": false,
          "notes": "Map unification plus fixes from a careful review of 0.3.0/0.3.1.\n\n## Changed\n- The contact **Map** button and the status-bar **GPS icon** now open the *same* map (one screen, one set of controls). Opening from a contact just centers on that contact and pre-selects it — drawn slightly larger with a highlight ring and its name in the bottom bar — while still showing every other contact / telemetry / heard-node location and your own position (a distinct green/amber dot).\n- **Reload** rebuilds all markers and re-checks your own position; **Center** always jumps to your own location once a fix is available (even when opened from a contact), falling back to the location the map opened on when there's no fix.\n\n## Fixed\n- Center now uses your own location on a contact-opened map (previously it only ever recentered on the contact).\n- The status-bar GPS icon stays visible (dimmed) and tappable when GPS is disabled, so the map remains reachable.\n- @mention no longer truncates a near-full message draft.\n- Companion: the contacts `since` field is read safely (removed an unaligned read).\n\nInstall/update via the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/), or on-device (SD card / WiFi). Binaries: `mclite-v0.3.2.bin` (T-Deck Plus), `mclite-watch-v0.3.2.bin` (T-Watch Ultra).\n\n**Full Changelog**: https://github.com/laserir/MCLite/compare/v0.3.1...v0.3.2",
          "notesHtml": "<p>Map unification plus fixes from a careful review of 0.3.0/0.3.1.</p>\n<h2>Changed</h2>\n<ul>\n<li>The contact <strong>Map</strong> button and the status-bar <strong>GPS icon</strong> now open the <em>same</em> map (one screen, one set of controls). Opening from a contact just centers on that contact and pre-selects it — drawn slightly larger with a highlight ring and its name in the bottom bar — while still showing every other contact / telemetry / heard-node location and your own position (a distinct green/amber dot).</li>\n<li><strong>Reload</strong> rebuilds all markers and re-checks your own position; <strong>Center</strong> always jumps to your own location once a fix is available (even when opened from a contact), falling back to the location the map opened on when there's no fix.</li>\n</ul>\n<h2>Fixed</h2>\n<ul>\n<li>Center now uses your own location on a contact-opened map (previously it only ever recentered on the contact).</li>\n<li>The status-bar GPS icon stays visible (dimmed) and tappable when GPS is disabled, so the map remains reachable.</li>\n<li>@mention no longer truncates a near-full message draft.</li>\n<li>Companion: the contacts <code>since</code> field is read safely (removed an unaligned read).</li>\n</ul>\n<p>Install/update via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a>, or on-device (SD card / WiFi). Binaries: <code>mclite-v0.3.2.bin</code> (T-Deck Plus), <code>mclite-watch-v0.3.2.bin</code> (T-Watch Ultra).</p>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/laserir/MCLite/compare/v0.3.1...v0.3.2\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/laserir/MCLite/compare/v0.3.1...v0.3.2</a></p>\n"
        },
        {
          "version": "v0.3.1",
          "name": "v0.3.1 — GPS in adverts + map",
          "datetime": "2026-06-09T09:01:00Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.1",
          "prerelease": false,
          "notes": "Fork-adoption batch (features adopted from the jason-s13r/MCLite fork) plus map polish.\n\n## Added\n- **GPS location in adverts** (opt-in, `gps.location_advert`, default off) — broadcast your position so contacts see you on their map. Uses MeshCore's native advert location; sends a live fix or a still-valid last-known one. Unencrypted broadcast — hence opt-in. Read-only status on the admin GPS screen; toggled via the config tool / SD.\n- **General map** — tap the status-bar GPS icon for a map of your own location plus every heard node / contact that carries GPS (same chat / repeater / room / sensor symbols as the heard-adverts list). Tap a marker for its name; **Reload** button re-scans heard nodes.\n- **NTP time sync** — set the clock from an NTP server over WiFi when GPS hasn't locked (GPS still overrides once it does).\n- **@mention** — tap a sender's name in a channel/room to insert `@name `.\n- **Fork-aware OTA** — build-time overridable update repo so forks can self-update.\n- **Web flasher repo/fork picker** — choose which repo's published releases to flash.\n\n## Changed\n- Map markers render as filled colored dots (type color + contrasting symbol) so they read against any tile; selection ring sits just outside the dot.\n\n## Fixed\n- Map markers are reliably tappable (tap-slop dead-zone; wider hit tolerance).\n- Map markers no longer blink out near the viewport edge across zoom levels.\n\nInstall/update via the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/), or on-device (SD card / WiFi). Binaries: `mclite-v0.3.1.bin` (T-Deck Plus), `mclite-watch-v0.3.1.bin` (T-Watch Ultra).\n\n**Full Changelog**: https://github.com/laserir/MCLite/compare/v0.3.0...v0.3.1",
          "notesHtml": "<p>Fork-adoption batch (features adopted from the jason-s13r/MCLite fork) plus map polish.</p>\n<h2>Added</h2>\n<ul>\n<li><strong>GPS location in adverts</strong> (opt-in, <code>gps.location_advert</code>, default off) — broadcast your position so contacts see you on their map. Uses MeshCore's native advert location; sends a live fix or a still-valid last-known one. Unencrypted broadcast — hence opt-in. Read-only status on the admin GPS screen; toggled via the config tool / SD.</li>\n<li><strong>General map</strong> — tap the status-bar GPS icon for a map of your own location plus every heard node / contact that carries GPS (same chat / repeater / room / sensor symbols as the heard-adverts list). Tap a marker for its name; <strong>Reload</strong> button re-scans heard nodes.</li>\n<li><strong>NTP time sync</strong> — set the clock from an NTP server over WiFi when GPS hasn't locked (GPS still overrides once it does).</li>\n<li><strong>@mention</strong> — tap a sender's name in a channel/room to insert <code>@name </code>.</li>\n<li><strong>Fork-aware OTA</strong> — build-time overridable update repo so forks can self-update.</li>\n<li><strong>Web flasher repo/fork picker</strong> — choose which repo's published releases to flash.</li>\n</ul>\n<h2>Changed</h2>\n<ul>\n<li>Map markers render as filled colored dots (type color + contrasting symbol) so they read against any tile; selection ring sits just outside the dot.</li>\n</ul>\n<h2>Fixed</h2>\n<ul>\n<li>Map markers are reliably tappable (tap-slop dead-zone; wider hit tolerance).</li>\n<li>Map markers no longer blink out near the viewport edge across zoom levels.</li>\n</ul>\n<p>Install/update via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a>, or on-device (SD card / WiFi). Binaries: <code>mclite-v0.3.1.bin</code> (T-Deck Plus), <code>mclite-watch-v0.3.1.bin</code> (T-Watch Ultra).</p>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/laserir/MCLite/compare/v0.3.0...v0.3.1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/laserir/MCLite/compare/v0.3.0...v0.3.1</a></p>\n"
        },
        {
          "version": "v0.3.0",
          "name": "v0.3.0 — Companion mode (WiFi / USB / BLE)",
          "datetime": "2026-06-08T12:18:56Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.3.0",
          "prerelease": false,
          "notes": "## Highlights\n\n**Companion mode** — bridge the radio to a phone, desktop, or CLI using the standard MeshCore companion protocol, in parallel with normal on-device use (messages appear in both):\n- **Bluetooth** — pairs with the official MeshCore iOS/Android apps (6-digit passkey + bonding).\n- **WiFi** — reach it from `meshcore-cli`/`meshcore.js`/`meshcore_py` on your LAN.\n- **USB** — wired serial companion.\n\nOne transport at a time; messaging is read-only for config. WiFi and Bluetooth can't run together (shared radio/RAM) — the device handles the switch and offers a reboot when needed.\n\nAlso includes the on-device firmware-update fixes and a refreshed README (Quick Start + balanced companion docs).\n\nInstall/update via the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/), or on-device (SD card / WiFi). Binaries: `mclite-v0.3.0.bin` (T-Deck Plus), `mclite-watch-v0.3.0.bin` (T-Watch Ultra).\n\n**Full Changelog**: https://github.com/laserir/MCLite/compare/v0.2.2...v0.3.0",
          "notesHtml": "<h2>Highlights</h2>\n<p><strong>Companion mode</strong> — bridge the radio to a phone, desktop, or CLI using the standard MeshCore companion protocol, in parallel with normal on-device use (messages appear in both):</p>\n<ul>\n<li><strong>Bluetooth</strong> — pairs with the official MeshCore iOS/Android apps (6-digit passkey + bonding).</li>\n<li><strong>WiFi</strong> — reach it from <code>meshcore-cli</code>/<code>meshcore.js</code>/<code>meshcore_py</code> on your LAN.</li>\n<li><strong>USB</strong> — wired serial companion.</li>\n</ul>\n<p>One transport at a time; messaging is read-only for config. WiFi and Bluetooth can't run together (shared radio/RAM) — the device handles the switch and offers a reboot when needed.</p>\n<p>Also includes the on-device firmware-update fixes and a refreshed README (Quick Start + balanced companion docs).</p>\n<p>Install/update via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a>, or on-device (SD card / WiFi). Binaries: <code>mclite-v0.3.0.bin</code> (T-Deck Plus), <code>mclite-watch-v0.3.0.bin</code> (T-Watch Ultra).</p>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/laserir/MCLite/compare/v0.2.2...v0.3.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/laserir/MCLite/compare/v0.2.2...v0.3.0</a></p>\n"
        },
        {
          "version": "v0.2.2",
          "name": "v0.2.2 — Fix WiFi OTA crash",
          "datetime": "2026-06-07T15:20:45Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.2.2",
          "prerelease": false,
          "notes": "Fixes a stack overflow that crashed the device when installing a firmware update over WiFi (the TLS handshake + on-stack buffer exceeded the loop-task stack). WiFi over-the-air updates now work end-to-end. SD-card install and USB flashing were unaffected.\n\nNote: devices on 0.2.1 should update via SD card or USB (the 0.2.1 WiFi installer has the crash); 0.2.2 onward updates over WiFi cleanly.",
          "notesHtml": "<p>Fixes a stack overflow that crashed the device when installing a firmware update over WiFi (the TLS handshake + on-stack buffer exceeded the loop-task stack). WiFi over-the-air updates now work end-to-end. SD-card install and USB flashing were unaffected.</p>\n<p>Note: devices on 0.2.1 should update via SD card or USB (the 0.2.1 WiFi installer has the crash); 0.2.2 onward updates over WiFi cleanly.</p>\n"
        },
        {
          "version": "v0.2.0",
          "name": "v0.2.0 — T-Watch Ultra support",
          "datetime": "2026-06-01T14:43:59Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.2.0",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/laserir/MCLite/compare/v0.1.8...v0.2.0",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/laserir/MCLite/compare/v0.1.8...v0.2.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/laserir/MCLite/compare/v0.1.8...v0.2.0</a></p>\n"
        },
        {
          "version": "v0.1.8",
          "name": "v0.1.8 — Heard Adverts",
          "datetime": "2026-05-05T12:01:26Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.8",
          "prerelease": false,
          "notes": "## Highlights\n\n**Heard Adverts** — every advert MeshCore decodes goes into a 64-entry LRU buffer (RAM, evaporates on reboot). New screen reachable from the admin menu lists them with type icons, last-heard age, alias-when-known, and a queued badge for entries you've saved this session. Detail modal shows fingerprint-style pubkey + per-hop path direction.\n\n- **Live updates** while the screen is visible: 1 Hz rate-limited rebuild, focus preserved by pubkey, skipped while a modal is open.\n- **Save discovered chat contacts** — Save button on the detail modal appends a `from_discovery: true` entry to `config.json` with conservative defaults (all permissions off, no SOS in/out). Activates on next boot via the existing ContactStore + MCLiteMesh registration path. CHAT-only — repeaters/rooms/sensors stay infrastructure. After save: `[Reboot now, OK]` confirmation.\n- **Manual advert** button in the header — sends a local advert immediately and re-anchors the periodic 9-min schedule. Toast confirms.\n- **Clear button** wipes the in-memory buffer.\n\n## Config persistence hardening\n\n- `ConfigManager::save()` now uses **atomic writes**: stage to `.tmp`, retain previous file as `.bak` during the rename, drop `.bak` on successful completion. Steady state is just `config.json`.\n- **Boot fallback** to `config.json.bak` if the live file is missing or corrupt (mid-save power loss). Successful recovery promotes the loaded content back to main and removes `.bak`.\n- Required because `config.json` holds the device identity keys — a torn truncate-write would brick the unit.\n\n## Other changes\n\n- **Boot screen** — MCLite mark glyph above the title, drawn programmatically (no raster asset).\n- **Default `dim_brightness` 20 → 0** — auto-dim now goes fully dark, prevents long-term burn-in on the always-on status bar.\n- **Long-standing log fix**: `[MCLiteMesh] Discovered contact` was printing the raw packed `path_len` byte (low 6 bits = hops, upper 2 = hash size). Values like `70` actually meant 6 hops with 2-byte hashes. Now masked correctly.\n- **Config tool**: amber 'Added via device — review me' badge on `from_discovery` contacts, with an inline ✕ to mark reviewed. Round-trip preserves the flag on both load paths and the export builder.\n- **i18n**: 19 new keys covering type names, field labels, hops format, save/reboot/queue/error states, advert-sent toast — across en/de/fr/it and the embedded LANG_FILES.\n\n## Tests\n\n- 185 native test cases (was 172). New coverage in `test_heard_advert_cache` (14) and `test_config` (atomic writes, `.bak` fallback, recovery cleanup, `from_discovery` round-trip, append-discovered-contact success/duplicate/cap).\n\n## Compatibility\n\n- Backward-compatible config: missing `from_discovery` parses as `false`. Old firmware ignores the field.\n- ConfigManager now writes through the atomic path even for the existing offgrid-toggle save — no caller change needed.\n- To force first-boot regen, delete **both** `config.json` and `config.json.bak`.\n\n## Install\n\n- **Web flasher:** [laserir.github.io/MCLite/tools/web-flasher](https://laserir.github.io/MCLite/tools/web-flasher/) — pick v0.1.8\n- **Manual:** \\`esptool.py write_flash 0x0 mclite-v0.1.8.bin\\`\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "notesHtml": "<h2>Highlights</h2>\n<p><strong>Heard Adverts</strong> — every advert MeshCore decodes goes into a 64-entry LRU buffer (RAM, evaporates on reboot). New screen reachable from the admin menu lists them with type icons, last-heard age, alias-when-known, and a queued badge for entries you've saved this session. Detail modal shows fingerprint-style pubkey + per-hop path direction.</p>\n<ul>\n<li><strong>Live updates</strong> while the screen is visible: 1 Hz rate-limited rebuild, focus preserved by pubkey, skipped while a modal is open.</li>\n<li><strong>Save discovered chat contacts</strong> — Save button on the detail modal appends a <code>from_discovery: true</code> entry to <code>config.json</code> with conservative defaults (all permissions off, no SOS in/out). Activates on next boot via the existing ContactStore + MCLiteMesh registration path. CHAT-only — repeaters/rooms/sensors stay infrastructure. After save: <code>[Reboot now, OK]</code> confirmation.</li>\n<li><strong>Manual advert</strong> button in the header — sends a local advert immediately and re-anchors the periodic 9-min schedule. Toast confirms.</li>\n<li><strong>Clear button</strong> wipes the in-memory buffer.</li>\n</ul>\n<h2>Config persistence hardening</h2>\n<ul>\n<li><code>ConfigManager::save()</code> now uses <strong>atomic writes</strong>: stage to <code>.tmp</code>, retain previous file as <code>.bak</code> during the rename, drop <code>.bak</code> on successful completion. Steady state is just <code>config.json</code>.</li>\n<li><strong>Boot fallback</strong> to <code>config.json.bak</code> if the live file is missing or corrupt (mid-save power loss). Successful recovery promotes the loaded content back to main and removes <code>.bak</code>.</li>\n<li>Required because <code>config.json</code> holds the device identity keys — a torn truncate-write would brick the unit.</li>\n</ul>\n<h2>Other changes</h2>\n<ul>\n<li><strong>Boot screen</strong> — MCLite mark glyph above the title, drawn programmatically (no raster asset).</li>\n<li><strong>Default <code>dim_brightness</code> 20 → 0</strong> — auto-dim now goes fully dark, prevents long-term burn-in on the always-on status bar.</li>\n<li><strong>Long-standing log fix</strong>: <code>[MCLiteMesh] Discovered contact</code> was printing the raw packed <code>path_len</code> byte (low 6 bits = hops, upper 2 = hash size). Values like <code>70</code> actually meant 6 hops with 2-byte hashes. Now masked correctly.</li>\n<li><strong>Config tool</strong>: amber 'Added via device — review me' badge on <code>from_discovery</code> contacts, with an inline ✕ to mark reviewed. Round-trip preserves the flag on both load paths and the export builder.</li>\n<li><strong>i18n</strong>: 19 new keys covering type names, field labels, hops format, save/reboot/queue/error states, advert-sent toast — across en/de/fr/it and the embedded LANG_FILES.</li>\n</ul>\n<h2>Tests</h2>\n<ul>\n<li>185 native test cases (was 172). New coverage in <code>test_heard_advert_cache</code> (14) and <code>test_config</code> (atomic writes, <code>.bak</code> fallback, recovery cleanup, <code>from_discovery</code> round-trip, append-discovered-contact success/duplicate/cap).</li>\n</ul>\n<h2>Compatibility</h2>\n<ul>\n<li>Backward-compatible config: missing <code>from_discovery</code> parses as <code>false</code>. Old firmware ignores the field.</li>\n<li>ConfigManager now writes through the atomic path even for the existing offgrid-toggle save — no caller change needed.</li>\n<li>To force first-boot regen, delete <strong>both</strong> <code>config.json</code> and <code>config.json.bak</code>.</li>\n</ul>\n<h2>Install</h2>\n<ul>\n<li><strong>Web flasher:</strong> <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">laserir.github.io/MCLite/tools/web-flasher</a> — pick v0.1.8</li>\n<li><strong>Manual:</strong> `esptool.py write_flash 0x0 mclite-v0.1.8.bin`</li>\n</ul>\n<p>🤖 Generated with <a href=\"https://claude.com/claude-code\" target=\"_blank\" rel=\"noopener noreferrer\">Claude Code</a></p>\n"
        },
        {
          "version": "v0.1.7",
          "name": "v0.1.7 — Room Server Client",
          "datetime": "2026-04-29T10:39:57Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.7",
          "prerelease": false,
          "notes": "## Highlights\n\n**Room server client** — join community message boards run by MeshCore room servers. Posts appear in the conversation list with an `R` icon (purple), ordered alongside DMs and channels by last activity. Up to 8 rooms.\n\n- **Auto-login on boot** with exponential backoff (1 → 2 → 4 → cap 30 min).\n- **Disconnect recovery** — re-login on chat-open (rate-limited 30s) and after 10 minutes of silence while a room chat is foreground. Both wake the server's 3-strike push-freeze that trips after ~36s of radio dropout, so passive readers don't miss posts after brief out-of-range moments.\n- **Per-room flags** mirroring channels: `read_only`, `allow_sos` (default true), `send_sos` (default false), `scope` override.\n- **Sender resolution** — 4-byte `sender_prefix` looked up against ContactStore: alias if known, else 8-hex-char fallback.\n- **`sync_since` persisted** per-room across reboots; only newer posts replay on next login.\n- **AdminScreen Rooms section** under Channels: name, online/offline indicator, last-sync timestamp.\n- **Config tool** Rooms card with all four toggles and the new `info-icon` collapsible-hint pattern.\n\n## Other changes\n\n- `MAX_CONTACTS=32 → 40` (32 chat + 8 room) with cap warnings on overflow.\n- `MAX_CONVERSATIONS=48 → 56`.\n- Translations: `sec_rooms` added in de/fr/it.\n- `data[5]` keep-alive byte runtime watch — warns if a future MeshCore server re-enables the legacy interval.\n\n## Compatibility\n\n- Backward-compatible config: missing `room_servers` block parses as empty list. Old firmware ignores the field.\n- DM and channel history files stay byte-identical (no `syncSince` written when zero).\n- Telemetry, SOS, key/PIN lock, offgrid mode all unaffected.\n\n## Install\n\n- **Web flasher:** [laserir.github.io/MCLite/tools/web-flasher](https://laserir.github.io/MCLite/tools/web-flasher/) — pick v0.1.7\n- **Manual:** `esptool.py write_flash 0x0 mclite-v0.1.7.bin`\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "notesHtml": "<h2>Highlights</h2>\n<p><strong>Room server client</strong> — join community message boards run by MeshCore room servers. Posts appear in the conversation list with an <code>R</code> icon (purple), ordered alongside DMs and channels by last activity. Up to 8 rooms.</p>\n<ul>\n<li><strong>Auto-login on boot</strong> with exponential backoff (1 → 2 → 4 → cap 30 min).</li>\n<li><strong>Disconnect recovery</strong> — re-login on chat-open (rate-limited 30s) and after 10 minutes of silence while a room chat is foreground. Both wake the server's 3-strike push-freeze that trips after ~36s of radio dropout, so passive readers don't miss posts after brief out-of-range moments.</li>\n<li><strong>Per-room flags</strong> mirroring channels: <code>read_only</code>, <code>allow_sos</code> (default true), <code>send_sos</code> (default false), <code>scope</code> override.</li>\n<li><strong>Sender resolution</strong> — 4-byte <code>sender_prefix</code> looked up against ContactStore: alias if known, else 8-hex-char fallback.</li>\n<li><strong><code>sync_since</code> persisted</strong> per-room across reboots; only newer posts replay on next login.</li>\n<li><strong>AdminScreen Rooms section</strong> under Channels: name, online/offline indicator, last-sync timestamp.</li>\n<li><strong>Config tool</strong> Rooms card with all four toggles and the new <code>info-icon</code> collapsible-hint pattern.</li>\n</ul>\n<h2>Other changes</h2>\n<ul>\n<li><code>MAX_CONTACTS=32 → 40</code> (32 chat + 8 room) with cap warnings on overflow.</li>\n<li><code>MAX_CONVERSATIONS=48 → 56</code>.</li>\n<li>Translations: <code>sec_rooms</code> added in de/fr/it.</li>\n<li><code>data[5]</code> keep-alive byte runtime watch — warns if a future MeshCore server re-enables the legacy interval.</li>\n</ul>\n<h2>Compatibility</h2>\n<ul>\n<li>Backward-compatible config: missing <code>room_servers</code> block parses as empty list. Old firmware ignores the field.</li>\n<li>DM and channel history files stay byte-identical (no <code>syncSince</code> written when zero).</li>\n<li>Telemetry, SOS, key/PIN lock, offgrid mode all unaffected.</li>\n</ul>\n<h2>Install</h2>\n<ul>\n<li><strong>Web flasher:</strong> <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">laserir.github.io/MCLite/tools/web-flasher</a> — pick v0.1.7</li>\n<li><strong>Manual:</strong> <code>esptool.py write_flash 0x0 mclite-v0.1.7.bin</code></li>\n</ul>\n<p>🤖 Generated with <a href=\"https://claude.com/claude-code\" target=\"_blank\" rel=\"noopener noreferrer\">Claude Code</a></p>\n"
        },
        {
          "version": "v0.1.5",
          "name": "v0.1.5",
          "datetime": "2026-04-21T09:31:28Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.5",
          "prerelease": false,
          "notes": "## Highlights\n\n- **MeshCore upgraded to v1.15.0** (`companion-v1.15.0`) — catches up with upstream bug fixes, new token-bucket duty-cycle dispatcher, and default-scope aligned wire format. Binary-compatible with all MCLite v0.1.x peers.\n- **SOS burst hardened** — 50ms inter-send pacing and dispatcher yield between each recipient so the packet pool can drain. Fixes intermittent cases where SOS delivered to only some contacts/channels in meshes with many targets.\n- **SOS received → key lock auto-disengages** — when an incoming SOS alert appears, the device automatically unlocks its keys so the user can respond immediately. **PIN lock stays engaged** — no security compromise.\n- **Configurable path hash mode** — new `radio.path_hash_mode` setting (0/1/2 → 1/2/3 bytes per repeater fingerprint in the packet path). Larger sizes reduce path collisions in dense meshes at the cost of a few extra bytes per hop. Defaults to 0 for wire-identical compatibility with pre-v1.15 peers.\n- **Admin screen shows active path hash size** plus per-channel scope overrides rendered as `[scope:#name]`, distinct from the `[SOS]` / `[read-only]` capability flags.\n\n## Changes since v0.1.4\n\n- `08ca1f7` Bump MeshCore to v1.15.0, harden SOS burst delivery\n- `a90ad6e` Add configurable path hash mode and admin screen scope display\n- `0f53de1` Bump version to 0.1.5\n- `aba8ceb` Publish firmware v0.1.5 to web flasher\n- `debad94` Document scope and path_hash_mode in example config\n\n## Install\n\nFlash `mclite-v0.1.5.bin` via the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/) or manually with esptool. Use `mclite_config_tool.html` (offline, single file) to edit `config.json`.",
          "notesHtml": "<h2>Highlights</h2>\n<ul>\n<li><strong>MeshCore upgraded to v1.15.0</strong> (<code>companion-v1.15.0</code>) — catches up with upstream bug fixes, new token-bucket duty-cycle dispatcher, and default-scope aligned wire format. Binary-compatible with all MCLite v0.1.x peers.</li>\n<li><strong>SOS burst hardened</strong> — 50ms inter-send pacing and dispatcher yield between each recipient so the packet pool can drain. Fixes intermittent cases where SOS delivered to only some contacts/channels in meshes with many targets.</li>\n<li><strong>SOS received → key lock auto-disengages</strong> — when an incoming SOS alert appears, the device automatically unlocks its keys so the user can respond immediately. <strong>PIN lock stays engaged</strong> — no security compromise.</li>\n<li><strong>Configurable path hash mode</strong> — new <code>radio.path_hash_mode</code> setting (0/1/2 → 1/2/3 bytes per repeater fingerprint in the packet path). Larger sizes reduce path collisions in dense meshes at the cost of a few extra bytes per hop. Defaults to 0 for wire-identical compatibility with pre-v1.15 peers.</li>\n<li><strong>Admin screen shows active path hash size</strong> plus per-channel scope overrides rendered as <code>[scope:#name]</code>, distinct from the <code>[SOS]</code> / <code>[read-only]</code> capability flags.</li>\n</ul>\n<h2>Changes since v0.1.4</h2>\n<ul>\n<li><code>08ca1f7</code> Bump MeshCore to v1.15.0, harden SOS burst delivery</li>\n<li><code>a90ad6e</code> Add configurable path hash mode and admin screen scope display</li>\n<li><code>0f53de1</code> Bump version to 0.1.5</li>\n<li><code>aba8ceb</code> Publish firmware v0.1.5 to web flasher</li>\n<li><code>debad94</code> Document scope and path_hash_mode in example config</li>\n</ul>\n<h2>Install</h2>\n<p>Flash <code>mclite-v0.1.5.bin</code> via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a> or manually with esptool. Use <code>mclite_config_tool.html</code> (offline, single file) to edit <code>config.json</code>.</p>\n"
        },
        {
          "version": "v0.1.4",
          "name": "v0.1.4",
          "datetime": "2026-04-20T18:19:03Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.4",
          "prerelease": false,
          "notes": "## Highlights\n\n- **Map view on telemetry modal** — tap a contact's name in the chat header → telemetry modal → **Map** button (visible when the contact has fresh GPS and SD tiles are available). Full-screen slippy-tile map centred on the contact, own-device marker, `+`/`-` zoom, scale bar. Tile pack layout `/tiles/{z}/{x}/{y}.png` is compatible with upstream MeshCore T-Deck firmware — existing tile packs work unchanged. See the updated README for how to prepare a `/tiles` folder with [map-tiles-downloader](https://github.com/tekk/map-tiles-downloader).\n- **Screen lock & auto-lock unified** — single `lock` / `auto_lock` config with deferred click; backwards-compatible with older configs missing `auto_key_lock`.\n- **Region scope transport codes** — optional per-radio / per-channel scope for repeater filtering.\n- **MeshCore dependency pinned** to commit `792f2999` for reproducible builds.\n\n## Changes since v0.1.3\n\n- `444065d` Add map view on telemetry modal\n- `89c3825` Add Map view to features list, drop OSM attribution note\n- `b4598bb` Correct map-tiles-downloader description (TUI, not browser) and document GeoNames region codes\n- `6f378e0` Pin MeshCore dep to commit 792f2999 for reproducible builds\n\n## Install\n\nFlash `mclite-v0.1.4.bin` via the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/) or manually with esptool. Use `mclite_config_tool.html` (offline, single file) to edit `config.json`.",
          "notesHtml": "<h2>Highlights</h2>\n<ul>\n<li><strong>Map view on telemetry modal</strong> — tap a contact's name in the chat header → telemetry modal → <strong>Map</strong> button (visible when the contact has fresh GPS and SD tiles are available). Full-screen slippy-tile map centred on the contact, own-device marker, <code>+</code>/<code>-</code> zoom, scale bar. Tile pack layout <code>/tiles/{z}/{x}/{y}.png</code> is compatible with upstream MeshCore T-Deck firmware — existing tile packs work unchanged. See the updated README for how to prepare a <code>/tiles</code> folder with <a href=\"https://github.com/tekk/map-tiles-downloader\" target=\"_blank\" rel=\"noopener noreferrer\">map-tiles-downloader</a>.</li>\n<li><strong>Screen lock &amp; auto-lock unified</strong> — single <code>lock</code> / <code>auto_lock</code> config with deferred click; backwards-compatible with older configs missing <code>auto_key_lock</code>.</li>\n<li><strong>Region scope transport codes</strong> — optional per-radio / per-channel scope for repeater filtering.</li>\n<li><strong>MeshCore dependency pinned</strong> to commit <code>792f2999</code> for reproducible builds.</li>\n</ul>\n<h2>Changes since v0.1.3</h2>\n<ul>\n<li><code>444065d</code> Add map view on telemetry modal</li>\n<li><code>89c3825</code> Add Map view to features list, drop OSM attribution note</li>\n<li><code>b4598bb</code> Correct map-tiles-downloader description (TUI, not browser) and document GeoNames region codes</li>\n<li><code>6f378e0</code> Pin MeshCore dep to commit 792f2999 for reproducible builds</li>\n</ul>\n<h2>Install</h2>\n<p>Flash <code>mclite-v0.1.4.bin</code> via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a> or manually with esptool. Use <code>mclite_config_tool.html</code> (offline, single file) to edit <code>config.json</code>.</p>\n"
        },
        {
          "version": "v0.1.3",
          "name": "v0.1.3",
          "datetime": "2026-04-13T08:44:54Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.3",
          "prerelease": false,
          "notes": "## What's New\n\n- **Region scope** — tag outgoing packets with MeshCore transport codes so repeaters can filter by region. Set a global scope or override per channel. Compatible with 1-byte and 2-byte repeaters\n- **Automatic DST** — POSIX timezone strings for automatic daylight saving time transitions\n- **SOS fix** — SOS acknowledgement no longer triggers an SOS alert on the sender's device\n- **Telemetry fix** — CayenneLPP parsing off-by-one corrected\n- **Config tool** — region scope settings for radio and per-channel override\n\n## Install\n\nFlash via the [Web Flasher](https://laserir.github.io/MCLite/tools/web-flasher/) or download the binary below and flash with esptool:\n```\nesptool.py write_flash 0x0 mclite-v0.1.3.bin\n```",
          "notesHtml": "<h2>What's New</h2>\n<ul>\n<li><strong>Region scope</strong> — tag outgoing packets with MeshCore transport codes so repeaters can filter by region. Set a global scope or override per channel. Compatible with 1-byte and 2-byte repeaters</li>\n<li><strong>Automatic DST</strong> — POSIX timezone strings for automatic daylight saving time transitions</li>\n<li><strong>SOS fix</strong> — SOS acknowledgement no longer triggers an SOS alert on the sender's device</li>\n<li><strong>Telemetry fix</strong> — CayenneLPP parsing off-by-one corrected</li>\n<li><strong>Config tool</strong> — region scope settings for radio and per-channel override</li>\n</ul>\n<h2>Install</h2>\n<p>Flash via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">Web Flasher</a> or download the binary below and flash with esptool:</p>\n<pre><code>esptool.py write_flash 0x0 mclite-v0.1.3.bin\n</code></pre>\n"
        },
        {
          "version": "v0.1.2",
          "name": "v0.1.2",
          "datetime": "2026-03-30T12:01:18Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.2",
          "prerelease": false,
          "notes": "## What's New\n\n- **Quick replies** — optional canned message picker in chat (OK, Copy, Where are you?, Need help, etc.). Disabled by default, enable via config tool or `\"canned_messages\": true` in config.json. Supports custom messages via JSON array.\n- **Translations** — quick reply messages translated for German, French, and Italian\n- **Config tool** — Quick Replies toggle in Messaging section; auto-detects base64 identity keys from firmware-generated configs\n\n## Install\n\nFlash via the [Web Flasher](https://laserir.github.io/MCLite/tools/web-flasher/) or download the binary below and flash with esptool:\n```\nesptool.py write_flash 0x0 mclite-v0.1.2.bin\n```",
          "notesHtml": "<h2>What's New</h2>\n<ul>\n<li><strong>Quick replies</strong> — optional canned message picker in chat (OK, Copy, Where are you?, Need help, etc.). Disabled by default, enable via config tool or <code>\"canned_messages\": true</code> in config.json. Supports custom messages via JSON array.</li>\n<li><strong>Translations</strong> — quick reply messages translated for German, French, and Italian</li>\n<li><strong>Config tool</strong> — Quick Replies toggle in Messaging section; auto-detects base64 identity keys from firmware-generated configs</li>\n</ul>\n<h2>Install</h2>\n<p>Flash via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">Web Flasher</a> or download the binary below and flash with esptool:</p>\n<pre><code>esptool.py write_flash 0x0 mclite-v0.1.2.bin\n</code></pre>\n"
        },
        {
          "version": "v0.1.1",
          "name": "v0.1.1",
          "datetime": "2026-03-28T18:32:12Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.1",
          "prerelease": false,
          "notes": "## What's New\n\n- **Keyboard backlight support** — turns on at boot, off on auto-dim, restores on wake. Configurable via `kbd_backlight` (on/off) and `kbd_brightness` (1–255, default 127).\n- **Configurable dim brightness** — new `dim_brightness` setting (0–255, default 20). Set to 0 to turn the screen off completely when inactive.\n- **Config tool: Basic/Advanced mode** — new toggle to show only Device, Identity, Contacts, and Channels by default. Switch to Advanced for Radio, Display, Messaging, Sound, GPS, Battery, and Security settings.\n- Updated config tool, example config, admin screen, and README.\n\n## Flashing\n\nUse the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/) or download `mclite-v0.1.1.bin` below and flash with esptool:\n```\nesptool.py write_flash 0x0 mclite-v0.1.1.bin\n```",
          "notesHtml": "<h2>What's New</h2>\n<ul>\n<li><strong>Keyboard backlight support</strong> — turns on at boot, off on auto-dim, restores on wake. Configurable via <code>kbd_backlight</code> (on/off) and <code>kbd_brightness</code> (1–255, default 127).</li>\n<li><strong>Configurable dim brightness</strong> — new <code>dim_brightness</code> setting (0–255, default 20). Set to 0 to turn the screen off completely when inactive.</li>\n<li><strong>Config tool: Basic/Advanced mode</strong> — new toggle to show only Device, Identity, Contacts, and Channels by default. Switch to Advanced for Radio, Display, Messaging, Sound, GPS, Battery, and Security settings.</li>\n<li>Updated config tool, example config, admin screen, and README.</li>\n</ul>\n<h2>Flashing</h2>\n<p>Use the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a> or download <code>mclite-v0.1.1.bin</code> below and flash with esptool:</p>\n<pre><code>esptool.py write_flash 0x0 mclite-v0.1.1.bin\n</code></pre>\n"
        },
        {
          "version": "v0.1.0",
          "name": "MCLite v0.1.0",
          "datetime": "2026-03-27T06:34:31Z",
          "url": "https://github.com/laserir/MCLite/releases/tag/v0.1.0",
          "prerelease": false,
          "notes": "## MCLite v0.1.0\n\nPurpose-built MeshCore companion firmware for LilyGo T-Deck Plus.\n\n### Highlights\n- MeshCore mesh messaging (DM + channels)\n- SOS alert system with long-press trigger\n- GPS location sharing (decimal, MGRS, or both)\n- On-demand telemetry (battery, location, environment)\n- Multi-language support (EN/DE/FR/IT)\n- SD card message history with ACK persistence\n- Offline config tool (HTML)\n\n### Install\nFlash `mclite-v0.1.0.bin` via the [web flasher](https://laserir.github.io/MCLite/tools/web-flasher/) or esptool.",
          "notesHtml": "<h2>MCLite v0.1.0</h2>\n<p>Purpose-built MeshCore companion firmware for LilyGo T-Deck Plus.</p>\n<h3>Highlights</h3>\n<ul>\n<li>MeshCore mesh messaging (DM + channels)</li>\n<li>SOS alert system with long-press trigger</li>\n<li>GPS location sharing (decimal, MGRS, or both)</li>\n<li>On-demand telemetry (battery, location, environment)</li>\n<li>Multi-language support (EN/DE/FR/IT)</li>\n<li>SD card message history with ACK persistence</li>\n<li>Offline config tool (HTML)</li>\n</ul>\n<h3>Install</h3>\n<p>Flash <code>mclite-v0.1.0.bin</code> via the <a href=\"https://laserir.github.io/MCLite/tools/web-flasher/\" target=\"_blank\" rel=\"noopener noreferrer\">web flasher</a> or esptool.</p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:30.520Z"
    },
    {
      "id": "meck",
      "name": "Meck",
      "type": "fork",
      "maintainer": "pelgraine",
      "description": "A MeshCore companion firmware fork focused on enabling BLE and WiFi connectivity for the LilyGo T-Deck Pro, T-Deck Max, and T5 E-Paper S3 Pro. Features a full touch UI with on-device keyboard, games, voice notes over LoRa, web browser, SMS, and a configuration launcher with OTA updates.\n",
      "repository": "https://github.com/pelgraine/Meck",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "features": [
        "BLE and WiFi companion connectivity",
        "Touch UI with on-device keyboard",
        "Games (Sokoban, Pong, Snake)",
        "Voice notes over LoRa",
        "Web browser and IRC client",
        "SMS and phone app (4G models only)",
        "Per-channel notification preferences and custom tones",
        "Config export/import",
        "OTA firmware update",
        "Lock screen and shutdown"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-tdeck-pro",
          "status": "supported",
          "notes": "T-Deck Pro variant with ESP32-S3 and e-paper display."
        },
        {
          "id": "lilygo-t5-pro",
          "status": "supported",
          "notes": "T5 E-Paper S3 Pro (H752-XX) variant."
        },
        {
          "id": "heltec-v3",
          "status": "supported",
          "notes": "Remote repeater only."
        },
        {
          "id": "heltec-wsl3",
          "status": "supported",
          "notes": "Remote repeater only."
        },
        {
          "id": "heltec-v4",
          "status": "supported",
          "notes": "Remote repeater only."
        },
        {
          "id": "heltec-v4-exp",
          "status": "supported",
          "notes": "Remote repeater only."
        }
      ],
      "popularity": {
        "githubStars": 25,
        "githubForks": 2,
        "githubWatchers": 0,
        "githubOpenIssues": 4,
        "githubContributors": 99,
        "releaseDownloads": 381,
        "latestReleaseDownloads": 32,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": true,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "1.12.2",
      "released": "2026-06-16",
      "releases": [
        {
          "version": "v1.12.2",
          "name": "Meck v1.12.2 (patch): Notes & WiFi password 'q' input fix",
          "datetime": "2026-06-16T21:13:31Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.12.2",
          "prerelease": false,
          "notes": "v1.12.2 is a small patch release on top of [v1.12.1](https://github.com/pelgraine/Meck/releases/tag/v1.12.1). It fixes a regression on the **T-Deck Pro** and **T-Deck Max** where pressing \"q\" (or \"Q\") during text entry was caught as a back/exit shortcut instead of being typed. This affected two screens -- the Notes editor and the WiFi password prompt -- so any note or WiFi password containing the letter \"q\" could not be entered. Both screens now accept \"q\"/\"Q\" as normal characters, with Shift+Backspace used to leave instead.\r\n\r\n## What's Changed in v1.12.2\r\n\r\n### Notes editor -- \"q\" now types instead of exiting\r\n\r\nPreviously, pressing \"q\" while editing a note could exit the editor (when the buffer was empty or unchanged) rather than inserting the letter. \"q\"/\"Q\" are now entered like any other character. Shift+Backspace continues to save and exit.\r\n\r\n### WiFi password entry -- \"q\" now types instead of jumping back\r\n\r\nIn the WiFi password screen, \"q\"/\"Q\" were intercepted and sent you back to the network list, so passwords containing those letters could not be entered. They are now accepted as password characters. Shift+Backspace returns to the network list, and the on-screen footer now reads `Enter:Connect Sh+Del:Exit`.\r\n\r\nAll other devices and features are unchanged from [v1.12.1](https://github.com/pelgraine/Meck/releases/tag/v1.12.1).\r\n\r\n## First-Time Flashing\r\n\r\nEach build comes in two forms:\r\n\r\n- **`<name>-merged.bin`** -- bootloader, partition table, and firmware in a single image. Flash at address `0x0`. Use this for a first-time flash, when coming from other firmware, **or if a device will not boot after an update**.\r\n\r\n- **`<name>.bin`** -- application firmware only. Use this to update an existing Meck install, including OTA updates from your phone (**Settings -> OTA Tools**).\r\n\r\nThe partition layout supports dual OTA slots, so the previous firmware remains on the inactive partition as an automatic rollback target if a new image fails to boot.\r\n\r\n## MeshCore Companion Apps\r\n\r\n**BLE variants** connect to the standard MeshCore companion apps:\r\n\r\n- Web: <https://app.meshcore.nz/>\r\n- Android: <https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android>\r\n- iOS: <https://apps.apple.com/us/app/meshcore/id6742354151>\r\n\r\n**WiFi variants** connect via TCP on port 5000:\r\n\r\n- Web: <https://app.meshcore.nz/>\r\n- meshcore.js: <https://github.com/liamcottle/meshcore.js>\r\n- Python CLI: <https://github.com/fdlamotte/meshcore-cli>",
          "notesHtml": "<p>v1.12.2 is a small patch release on top of <a href=\"https://github.com/pelgraine/Meck/releases/tag/v1.12.1\" target=\"_blank\" rel=\"noopener noreferrer\">v1.12.1</a>. It fixes a regression on the <strong>T-Deck Pro</strong> and <strong>T-Deck Max</strong> where pressing \"q\" (or \"Q\") during text entry was caught as a back/exit shortcut instead of being typed. This affected two screens -- the Notes editor and the WiFi password prompt -- so any note or WiFi password containing the letter \"q\" could not be entered. Both screens now accept \"q\"/\"Q\" as normal characters, with Shift+Backspace used to leave instead.</p>\n<h2>What's Changed in v1.12.2</h2>\n<h3>Notes editor -- \"q\" now types instead of exiting</h3>\n<p>Previously, pressing \"q\" while editing a note could exit the editor (when the buffer was empty or unchanged) rather than inserting the letter. \"q\"/\"Q\" are now entered like any other character. Shift+Backspace continues to save and exit.</p>\n<h3>WiFi password entry -- \"q\" now types instead of jumping back</h3>\n<p>In the WiFi password screen, \"q\"/\"Q\" were intercepted and sent you back to the network list, so passwords containing those letters could not be entered. They are now accepted as password characters. Shift+Backspace returns to the network list, and the on-screen footer now reads <code>Enter:Connect Sh+Del:Exit</code>.</p>\n<p>All other devices and features are unchanged from <a href=\"https://github.com/pelgraine/Meck/releases/tag/v1.12.1\" target=\"_blank\" rel=\"noopener noreferrer\">v1.12.1</a>.</p>\n<h2>First-Time Flashing</h2>\n<p>Each build comes in two forms:</p>\n<ul>\n<li><p><strong><code>&lt;name&gt;-merged.bin</code></strong> -- bootloader, partition table, and firmware in a single image. Flash at address <code>0x0</code>. Use this for a first-time flash, when coming from other firmware, <strong>or if a device will not boot after an update</strong>.</p>\n</li>\n<li><p><strong><code>&lt;name&gt;.bin</code></strong> -- application firmware only. Use this to update an existing Meck install, including OTA updates from your phone (<strong>Settings -&gt; OTA Tools</strong>).</p>\n</li>\n</ul>\n<p>The partition layout supports dual OTA slots, so the previous firmware remains on the inactive partition as an automatic rollback target if a new image fails to boot.</p>\n<h2>MeshCore Companion Apps</h2>\n<p><strong>BLE variants</strong> connect to the standard MeshCore companion apps:</p>\n<ul>\n<li>Web: <a href=\"https://app.meshcore.nz/\" target=\"_blank\" rel=\"noopener noreferrer\">https://app.meshcore.nz/</a></li>\n<li>Android: <a href=\"https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android\" target=\"_blank\" rel=\"noopener noreferrer\">https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android</a></li>\n<li>iOS: <a href=\"https://apps.apple.com/us/app/meshcore/id6742354151\" target=\"_blank\" rel=\"noopener noreferrer\">https://apps.apple.com/us/app/meshcore/id6742354151</a></li>\n</ul>\n<p><strong>WiFi variants</strong> connect via TCP on port 5000:</p>\n<ul>\n<li>Web: <a href=\"https://app.meshcore.nz/\" target=\"_blank\" rel=\"noopener noreferrer\">https://app.meshcore.nz/</a></li>\n<li>meshcore.js: <a href=\"https://github.com/liamcottle/meshcore.js\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/liamcottle/meshcore.js</a></li>\n<li>Python CLI: <a href=\"https://github.com/fdlamotte/meshcore-cli\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/fdlamotte/meshcore-cli</a></li>\n</ul>\n"
        },
        {
          "version": "v1.12.1",
          "name": "Meck v1.12.1: T-Deck Max battery capacity correction",
          "datetime": "2026-06-10T23:01:12Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.12.1",
          "prerelease": false,
          "notes": "v1.12.1 is a small patch release on top of [v1.12.](https://github.com/pelgraine/Meck/releases/tag/v1.12) It corrects the configured battery capacity for the **T-Deck Max** from 1500 mAh to 1400 mAh, matching the cell actually shipped in the device. This improves the accuracy of battery percentage and runtime estimates on the Max.\r\n\r\n## What's Changed in v1.12.1\r\n\r\n### T-Deck Max battery capacity -- 1500 -> 1400 mAh\r\n\r\nThe Max's battery capacity was set to 1500 mAh; it is now 1400 mAh to reflect the real cell. No other behaviour changes.\r\n\r\nAll other devices and features are unchanged from [v1.12.](https://github.com/pelgraine/Meck/releases/tag/v1.12).\r\n\r\nDespite the LilyGO T-Deck Max readme reflecting 1500mAh, I've removed the battery from my Max (to put in a 2500mAh battery with a custom case) and can confirm my T-Deck Max battery was actually the same 1400mAh used in the T-Deck Pro.\r\n\r\n<img width=\"470\" height=\"588\" alt=\"Screenshot 2026-06-11 at 8 56 44 am\" src=\"https://github.com/user-attachments/assets/a295e9c2-346e-4eb7-b34a-255141de41a1\" />\r\n\r\n<img width=\"1500\" height=\"750\" alt=\"IMG_3378\" src=\"https://github.com/user-attachments/assets/017e9517-ffb1-4935-820c-968f089af4cf\" />\r\n\r\n## First-Time Flashing\r\n\r\nEach build comes in two forms:\r\n\r\n- **`<name>-merged.bin`** -- bootloader, partition table, and firmware in a single image. Flash at address `0x0`. Use this for a first-time flash, when coming from other firmware, **or if a device will not boot after an update**.\r\n\r\n- **`<name>.bin`** -- application firmware only. Use this to update an existing Meck install, including OTA updates from your phone (**Settings -> OTA Tools**).\r\n\r\nThe partition layout supports dual OTA slots, so the previous firmware remains on the inactive partition as an automatic rollback target if a new image fails to boot.\r\n\r\n## MeshCore Companion Apps\r\n\r\n**BLE variants** connect to the standard MeshCore companion apps:\r\n\r\n- Web: <https://app.meshcore.nz/>\r\n- Android: <https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android>\r\n- iOS: <https://apps.apple.com/us/app/meshcore/id6742354151>\r\n\r\n\r\n**WiFi variants** connect via TCP on port 5000:\r\n\r\n- Web: <https://app.meshcore.nz/>\r\n- meshcore.js: <https://github.com/liamcottle/meshcore.js>\r\n- Python CLI: <https://github.com/fdlamotte/meshcore-cli>",
          "notesHtml": "<p>v1.12.1 is a small patch release on top of <a href=\"https://github.com/pelgraine/Meck/releases/tag/v1.12\" target=\"_blank\" rel=\"noopener noreferrer\">v1.12.</a> It corrects the configured battery capacity for the <strong>T-Deck Max</strong> from 1500 mAh to 1400 mAh, matching the cell actually shipped in the device. This improves the accuracy of battery percentage and runtime estimates on the Max.</p>\n<h2>What's Changed in v1.12.1</h2>\n<h3>T-Deck Max battery capacity -- 1500 -&gt; 1400 mAh</h3>\n<p>The Max's battery capacity was set to 1500 mAh; it is now 1400 mAh to reflect the real cell. No other behaviour changes.</p>\n<p>All other devices and features are unchanged from <a href=\"https://github.com/pelgraine/Meck/releases/tag/v1.12\" target=\"_blank\" rel=\"noopener noreferrer\">v1.12.</a>.</p>\n<p>Despite the LilyGO T-Deck Max readme reflecting 1500mAh, I've removed the battery from my Max (to put in a 2500mAh battery with a custom case) and can confirm my T-Deck Max battery was actually the same 1400mAh used in the T-Deck Pro.</p>\n<img alt=\"Screenshot 2026-06-11 at 8 56 44 am\" src=\"https://github.com/user-attachments/assets/a295e9c2-346e-4eb7-b34a-255141de41a1\" /><img alt=\"IMG_3378\" src=\"https://github.com/user-attachments/assets/017e9517-ffb1-4935-820c-968f089af4cf\" /><h2>First-Time Flashing</h2>\n<p>Each build comes in two forms:</p>\n<ul>\n<li><p><strong><code>&lt;name&gt;-merged.bin</code></strong> -- bootloader, partition table, and firmware in a single image. Flash at address <code>0x0</code>. Use this for a first-time flash, when coming from other firmware, <strong>or if a device will not boot after an update</strong>.</p>\n</li>\n<li><p><strong><code>&lt;name&gt;.bin</code></strong> -- application firmware only. Use this to update an existing Meck install, including OTA updates from your phone (<strong>Settings -&gt; OTA Tools</strong>).</p>\n</li>\n</ul>\n<p>The partition layout supports dual OTA slots, so the previous firmware remains on the inactive partition as an automatic rollback target if a new image fails to boot.</p>\n<h2>MeshCore Companion Apps</h2>\n<p><strong>BLE variants</strong> connect to the standard MeshCore companion apps:</p>\n<ul>\n<li>Web: <a href=\"https://app.meshcore.nz/\" target=\"_blank\" rel=\"noopener noreferrer\">https://app.meshcore.nz/</a></li>\n<li>Android: <a href=\"https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android\" target=\"_blank\" rel=\"noopener noreferrer\">https://play.google.com/store/apps/details?id=com.liamcottle.meshcore.android</a></li>\n<li>iOS: <a href=\"https://apps.apple.com/us/app/meshcore/id6742354151\" target=\"_blank\" rel=\"noopener noreferrer\">https://apps.apple.com/us/app/meshcore/id6742354151</a></li>\n</ul>\n<p><strong>WiFi variants</strong> connect via TCP on port 5000:</p>\n<ul>\n<li>Web: <a href=\"https://app.meshcore.nz/\" target=\"_blank\" rel=\"noopener noreferrer\">https://app.meshcore.nz/</a></li>\n<li>meshcore.js: <a href=\"https://github.com/liamcottle/meshcore.js\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/liamcottle/meshcore.js</a></li>\n<li>Python CLI: <a href=\"https://github.com/fdlamotte/meshcore-cli\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/fdlamotte/meshcore-cli</a></li>\n</ul>\n"
        },
        {
          "version": "v1.12",
          "name": "Meck v1.12: RX log, RX packet counter, plus T-Deck Max power fixes",
          "datetime": "2026-06-06T21:30:49Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.12",
          "prerelease": false,
          "notes": "v1.12 is a polish-and-power release across all three companion devices. The headline addition is an on-device **Rx Log** packet sniffer -- a live view of every packet your radio hears -- available on every build. Alongside it: an unread badge for the SMS inbox, a batch of **T-Deck Max** power, wake, and GPS fixes, and a set of channel and repeater refinements. \r\n\r\n## What's New in v1.12\r\n\r\n### Rx Log packet sniffer -- all devices\r\n\r\nA new on-device packet sniffer, mirroring the Rx Log in the MeshCore companion app. Open it from **Settings -> Rx Log >>**. It captures every packet the radio receives -- including relays destined for other nodes, since capture happens before filtering -- into a buffer of the most recent 100 packets, newest first. Each entry shows the route type (flood/direct) and payload type, the receive time and wire size, the packet hash, the hop path, and the channel hash/name (group messages) or the From/To node hashes (addressed packets). For channel messages your device can decrypt, the decoded \"sender: message\" line is attached too. The log is RAM-only and clears on reboot.\r\n\r\nA running **RX packets** count also appears on the radio details page on the home screen, just beneath the noise-floor reading. It counts flood and direct packets received since boot and resets on reboot or when you change radio parameters.\r\n\r\n### SMS Inbox unread badge -- 4G and Max\r\n\r\nThe SMS app's inbox entry now shows a count of unread received messages in brackets (e.g. **SMS Inbox [3]**), and the badge disappears once everything is read. Read state is stored per message on the SD card, so the count survives reboots and modem power-cycles. Opening a conversation marks it read.\r\n\r\n### T-Deck Max power, wake, and GPS fixes\r\n\r\n- **USB-C wake after shutdown** -- after a full power-off, plugging in USB-C now reliably powers the Max back on. The Max uses the SY6970 charger (0x6A); its BATFET shutdown is now handled to match, so charger plug-in re-wakes the board.\r\n- **GPS power** -- GPS power on the Max is routed through the XL9555 I/O expander rather than a dedicated pin; powering it on and off now works correctly.\r\n- **CPU frequency scaling** -- idle / boost / low-power CPU management to trim current draw, with the low-power floor held at 80 MHz (40 MHz breaks I2C on the Max).\r\n- **Idle BLE power** -- the BLE controller now stays powered down until you first turn Bluetooth on, reclaiming its idle current in the standalone-first default. This applies to all ESP32 BLE builds, not just the Max.\r\n- **Minesweeper** -- grid alignment fixes and a larger 15x20 / 50-mine board sized to the Max e-ink panel.\r\n\r\n### Channel and repeater refinements -- all devices\r\n\r\n- **Region on incoming messages** -- the message path-detail view now shows the resolved region for scoped channel messages it recognises.\r\n- **Path detail** -- the route line now reports hop count and bytes-per-hop (e.g. \"2 hops (2-byte)\"), and the last-message age line shows hop/byte info.\r\n- **Repeater admin** -- two new configuration commands: Set Flood Max Unscoped (`flood.max.unscoped`) and Set Flood Adv Max (`flood.max.advert`).\r\n\r\n### Documentation\r\n\r\nThe README and the hyperlinked **Meck_README_v1.12.pdf** are updated for this release.\r\n\r\n## First-Time Flashing\r\n\r\nEach build comes in two forms:\r\n\r\n- **`<name>-merged.bin`** -- bootloader, partition table, and firmware in a single image. Flash at address `0x0`. Use this for a first-time flash, when coming from other firmware, **or if a device will not boot after an update**. \r\n\r\n- **`<name>.bin`** -- application firmware only. Use this to update an existing Meck install, including OTA updates from your phone (**Settings -> OTA Tools**).\r\n\r\nThe partition layout supports dual OTA slots, so the previous firmware remains on the inactive partition as an automatic rollback target if a new image fails to boot.\r\n\r\n## Build Files\r\n\r\nGrouped by device. Each variant ships as a merged (`-merged.bin`, first flash) and non-merged (`.bin`, \n…",
          "notesHtml": "<p>v1.12 is a polish-and-power release across all three companion devices. The headline addition is an on-device <strong>Rx Log</strong> packet sniffer -- a live view of every packet your radio hears -- available on every build. Alongside it: an unread badge for the SMS inbox, a batch of <strong>T-Deck Max</strong> power, wake, and GPS fixes, and a set of channel and repeater refinements. </p>\n<h2>What's New in v1.12</h2>\n<h3>Rx Log packet sniffer -- all devices</h3>\n<p>A new on-device packet sniffer, mirroring the Rx Log in the MeshCore companion app. Open it from <strong>Settings -&gt; Rx Log &gt;&gt;</strong>. It captures every packet the radio receives -- including relays destined for other nodes, since capture happens before filtering -- into a buffer of the most recent 100 packets, newest first. Each entry shows the route type (flood/direct) and payload type, the receive time and wire size, the packet hash, the hop path, and the channel hash/name (group messages) or the From/To node hashes (addressed packets). For channel messages your device can decrypt, the decoded \"sender: message\" line is attached too. The log is RAM-only and clears on reboot.</p>\n<p>A running <strong>RX packets</strong> count also appears on the radio details page on the home screen, just beneath the noise-floor reading. It counts flood and direct packets received since boot and resets on reboot or when you change radio parameters.</p>\n<h3>SMS Inbox unread badge -- 4G and Max</h3>\n<p>The SMS app's inbox entry now shows a count of unread received messages in brackets (e.g. <strong>SMS Inbox [3]</strong>), and the badge disappears once everything is read. Read state is stored per message on the SD card, so the count survives reboots and modem power-cycles. Opening a conversation marks it read.</p>\n<h3>T-Deck Max power, wake, and GPS fixes</h3>\n<ul>\n<li><strong>USB-C wake after shutdown</strong> -- after a full power-off, plugging in USB-C now reliably powers the Max back on. The Max uses the SY6970 charger (0x6A); its BATFET shutdown is now handled to match, so charger plug-in re-wakes the board.</li>\n<li><strong>GPS power</strong> -- GPS power on the Max is routed through the XL9555 I/O expander rather than a dedicated pin; powering it on and off now works correctly.</li>\n<li><strong>CPU frequency scaling</strong> -- idle / boost / low-power CPU management to trim current draw, with the low-power floor held at 80 MHz (40 MHz breaks I2C on the Max).</li>\n<li><strong>Idle BLE power</strong> -- the BLE controller now stays powered down until you first turn Bluetooth on, reclaiming its idle current in the standalone-first default. This applies to all ESP32 BLE builds, not just the Max.</li>\n<li><strong>Minesweeper</strong> -- grid alignment fixes and a larger 15x20 / 50-mine board sized to the Max e-ink panel.</li>\n</ul>\n<h3>Channel and repeater refinements -- all devices</h3>\n<ul>\n<li><strong>Region on incoming messages</strong> -- the message path-detail view now shows the resolved region for scoped channel messages it recognises.</li>\n<li><strong>Path detail</strong> -- the route line now reports hop count and bytes-per-hop (e.g. \"2 hops (2-byte)\"), and the last-message age line shows hop/byte info.</li>\n<li><strong>Repeater admin</strong> -- two new configuration commands: Set Flood Max Unscoped (<code>flood.max.unscoped</code>) and Set Flood Adv Max (<code>flood.max.advert</code>).</li>\n</ul>\n<h3>Documentation</h3>\n<p>The README and the hyperlinked <strong>Meck_README_v1.12.pdf</strong> are updated for this release.</p>\n<h2>First-Time Flashing</h2>\n<p>Each build comes in two forms:</p>\n<ul>\n<li><p><strong><code>&lt;name&gt;-merged.bin</code></strong> -- bootloader, partition table, and firmware in a single image. Flash at address <code>0x0</code>. Use this for a first-time flash, when coming from other firmware, <strong>or if a device will not boot after an update</strong>. </p>\n</li>\n<li><p><strong><code>&lt;name&gt;.bin</code></strong> -- application firmware only. Use this to update an existing Meck install, including OTA updates from your phone (<strong>Settings -&gt; OTA Tools</strong>).</p>\n</li>\n</ul>\n<p>The partition layout supports dual OTA slots, so the previous firmware remains on the inactive partition as an automatic rollback target if a new image fails to boot.</p>\n<h2>Build Files</h2>\n<p>Grouped by device. Each variant ships as a merged (<code>-merged.bin</code>, first flash) and non-merged (<code>.bin</code>, \n…</p>\n"
        },
        {
          "version": "maxv1.11",
          "name": "Meck v1.11 -- T-Deck Max Support",
          "datetime": "2026-06-04T18:56:49Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/maxv1.11",
          "prerelease": false,
          "notes": ">⚠️ Files from 2+hrs ago have now been patched with the correct bootloader. Please re-download fresh copies if you've been having trouble booting for the first time⚠️ \r\n\r\nThis release adds the **LilyGo T-Deck Max** as a supported device. It runs the full Meck [v1.11](https://github.com/pelgraine/Meck/releases/tag/v1.11) feature set with the same on-device UI, keyboard controls, and screens as the T-Deck Pro -- all of those apply unchanged. The firmware version stays at v1.11 because the core feature set is the same, but the Max has hardware the other boards don't, so this build exposes several capabilities the standard T-Deck Pro builds can't.\r\n\r\nIf you are on a standard T-Deck Pro, T-Deck Pro 4G, T-Deck Pro Audio, or T5S3, use the [v1.11 release](https://github.com/pelgraine/Meck/releases/tag/v1.11) builds instead.\r\n\r\n---\r\n\r\n## What the T-Deck Max Adds\r\n\r\nThe headline difference is hardware: the Max carries an **A7682E 4G modem and an ES8311 audio codec at the same time**, wired through an XL9555 I/O expander. On the T-Deck Pro the modem and the audio DAC share one hardware slot and are mutually exclusive; on the Max you get the SMS & Phone app, the audiobook player, the alarm clock, **and** cellular data on a single device. The Max also adds a CST328 capacitive touchscreen, three capacitive front buttons, a DRV2605 haptic motor for vibrate alerts, an e-ink frontlight, and a 1500 mAh battery with a BQ27220 fuel gauge.\r\n\r\n### 4G and Audio at the Same Time\r\n\r\nEvery Max build includes both the 4G modem and the audio codec -- there is no \"audio vs 4G\" split like the T-Deck Pro. The home screen carries the full app set: Audiobooks (**P**), Alarm (**K**), Phone & SMS (**T**), Browser & IRC (**B**), Discover (**F**), and Voice Messages (**Mic**). Audio output runs through a shared speaker mux that switches between the modem (calls, ringtones, modem tones) and the ES8311 codec (audiobooks, alarms, notification MP3s) automatically.\r\n\r\n> The Max records and plays voice notes through its ES8311 codec (the same output path that drives audiobooks and alarms). Sending a recorded note over the mesh is not yet verified -- see Known Limitations below.\r\n\r\n### Antenna (Internal / External)\r\n\r\nThe Max has both an on-board internal antenna and an external MMCX antenna connector, with a switch in **Settings** to select between them. **Internal is the default** -- if you want to use an external MMCX antenna, change the switch in Settings first.\r\n\r\n### E-Ink Frontlight with Adjustable Brightness\r\n\r\nThe Max has an e-ink frontlight -- a first for the T-Deck line. The on-level is set in **Settings → Backlight Brightness**, adjustable from **5% to 100% in 5% steps** (default 100%); this setting only appears on the Max. You can switch the frontlight on with the new **Heart capacitive button** (turns on at the configured brightness) or with **Alt + B** (turns on at minimum brightness).\r\n\r\n### Capacitive Touch Buttons\r\n\r\nThe Max adds a CST328 capacitive touchscreen plus **three capacitive buttons** along the front bezel, none of which the T-Deck Pro has:\r\n\r\n- **Heart** -- toggle the e-ink frontlight (see above)\r\n- **Speech bubble** -- jump straight to the channel picker (same as pressing **M**)\r\n- **Paper plane** -- jump straight to the DM inbox\r\n\r\n### Buzzer (Vibrate) Notifications\r\n\r\nThe Max's DRV2605 haptic motor can be used for silent alerts. In **Settings → Channels**, highlight a channel, press **T** to open the notification tone picker, and choose the new **Buzzer (vibrate)** entry (just below \"Default (silent)\"). Incoming messages on that channel pulse the motor instead of sounding a tone -- useful for silent alerts. The Max also supports custom MP3 tones from the `/alarms/` folder, like the T-Deck Pro audio variant.\r\n\r\n### Multi-Constellation GPS\r\n\r\nThe Max's GPS is configured for multi-constellation positioning -- **GPS, Galileo, and BeiDou** (via the `$PCAS04,7` command) -- for faster fixes and better coverage than single-constellation GPS.\r\n\r\n#\n…",
          "notesHtml": "<blockquote>\n<p>⚠️ Files from 2+hrs ago have now been patched with the correct bootloader. Please re-download fresh copies if you've been having trouble booting for the first time⚠️ </p>\n</blockquote>\n<p>This release adds the <strong>LilyGo T-Deck Max</strong> as a supported device. It runs the full Meck <a href=\"https://github.com/pelgraine/Meck/releases/tag/v1.11\" target=\"_blank\" rel=\"noopener noreferrer\">v1.11</a> feature set with the same on-device UI, keyboard controls, and screens as the T-Deck Pro -- all of those apply unchanged. The firmware version stays at v1.11 because the core feature set is the same, but the Max has hardware the other boards don't, so this build exposes several capabilities the standard T-Deck Pro builds can't.</p>\n<p>If you are on a standard T-Deck Pro, T-Deck Pro 4G, T-Deck Pro Audio, or T5S3, use the <a href=\"https://github.com/pelgraine/Meck/releases/tag/v1.11\" target=\"_blank\" rel=\"noopener noreferrer\">v1.11 release</a> builds instead.</p>\n<hr />\n<h2>What the T-Deck Max Adds</h2>\n<p>The headline difference is hardware: the Max carries an <strong>A7682E 4G modem and an ES8311 audio codec at the same time</strong>, wired through an XL9555 I/O expander. On the T-Deck Pro the modem and the audio DAC share one hardware slot and are mutually exclusive; on the Max you get the SMS &amp; Phone app, the audiobook player, the alarm clock, <strong>and</strong> cellular data on a single device. The Max also adds a CST328 capacitive touchscreen, three capacitive front buttons, a DRV2605 haptic motor for vibrate alerts, an e-ink frontlight, and a 1500 mAh battery with a BQ27220 fuel gauge.</p>\n<h3>4G and Audio at the Same Time</h3>\n<p>Every Max build includes both the 4G modem and the audio codec -- there is no \"audio vs 4G\" split like the T-Deck Pro. The home screen carries the full app set: Audiobooks (<strong>P</strong>), Alarm (<strong>K</strong>), Phone &amp; SMS (<strong>T</strong>), Browser &amp; IRC (<strong>B</strong>), Discover (<strong>F</strong>), and Voice Messages (<strong>Mic</strong>). Audio output runs through a shared speaker mux that switches between the modem (calls, ringtones, modem tones) and the ES8311 codec (audiobooks, alarms, notification MP3s) automatically.</p>\n<blockquote>\n<p>The Max records and plays voice notes through its ES8311 codec (the same output path that drives audiobooks and alarms). Sending a recorded note over the mesh is not yet verified -- see Known Limitations below.</p>\n</blockquote>\n<h3>Antenna (Internal / External)</h3>\n<p>The Max has both an on-board internal antenna and an external MMCX antenna connector, with a switch in <strong>Settings</strong> to select between them. <strong>Internal is the default</strong> -- if you want to use an external MMCX antenna, change the switch in Settings first.</p>\n<h3>E-Ink Frontlight with Adjustable Brightness</h3>\n<p>The Max has an e-ink frontlight -- a first for the T-Deck line. The on-level is set in <strong>Settings → Backlight Brightness</strong>, adjustable from <strong>5% to 100% in 5% steps</strong> (default 100%); this setting only appears on the Max. You can switch the frontlight on with the new <strong>Heart capacitive button</strong> (turns on at the configured brightness) or with <strong>Alt + B</strong> (turns on at minimum brightness).</p>\n<h3>Capacitive Touch Buttons</h3>\n<p>The Max adds a CST328 capacitive touchscreen plus <strong>three capacitive buttons</strong> along the front bezel, none of which the T-Deck Pro has:</p>\n<ul>\n<li><strong>Heart</strong> -- toggle the e-ink frontlight (see above)</li>\n<li><strong>Speech bubble</strong> -- jump straight to the channel picker (same as pressing <strong>M</strong>)</li>\n<li><strong>Paper plane</strong> -- jump straight to the DM inbox</li>\n</ul>\n<h3>Buzzer (Vibrate) Notifications</h3>\n<p>The Max's DRV2605 haptic motor can be used for silent alerts. In <strong>Settings → Channels</strong>, highlight a channel, press <strong>T</strong> to open the notification tone picker, and choose the new <strong>Buzzer (vibrate)</strong> entry (just below \"Default (silent)\"). Incoming messages on that channel pulse the motor instead of sounding a tone -- useful for silent alerts. The Max also supports custom MP3 tones from the <code>/alarms/</code> folder, like the T-Deck Pro audio variant.</p>\n<h3>Multi-Constellation GPS</h3>\n<p>The Max's GPS is configured for multi-constellation positioning -- <strong>GPS, Galileo, and BeiDou</strong> (via the <code>$PCAS04,7</code> command) -- for faster fixes and better coverage than single-constellation GPS.</p>\n<h1></h1>\n<p>…</p>\n"
        },
        {
          "version": "v1.11",
          "name": "Meck v1.11 -- Private Channels, Channel Sharing, Config Export/Import",
          "datetime": "2026-05-22T22:10:58Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.11",
          "prerelease": false,
          "notes": "This release adds private channel support, the ability to share channels with other Meck users via encrypted DM, and a full config export/import system for backing up and migrating device configurations. Also includes two new emoji, an expanded Minesweeper grid on the T5S3, and a fix for contacts with stuck clocks sinking in the recency-sorted contacts list.\r\n\r\n---\r\n\r\n## First-Time Flashing -- Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n- **`filename.bin`** -- the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n- **`filename-merged.bin`** -- includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.io/**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n\r\n---\r\n\r\n## What's New Since v1.10\r\n\r\n### Private Channels\r\n\r\nMeck now supports private channels alongside the existing public hashtag channels. The difference is in how the channel secret is generated:\r\n\r\n- **Public (hashtag) channels** — type a name starting with `#` (e.g. `#camping`). The 16-byte secret is derived deterministically from the name via SHA-256, so anyone on any MeshCore device who creates the same hashtag name gets the same key and can communicate on that channel.\r\n- **Private channels** — type a name **without** the `#` prefix (e.g. `team-alpha`). A cryptographically random 16-byte secret is generated, meaning only devices that have been explicitly given the key can participate.\r\n\r\n**How to create a private channel:**\r\n\r\n1. From the home screen, press **S** to open settings\r\n2. Scroll down to the **Channels >>** section and press Enter to open it\r\n3. Navigate to **+ Add Channel (# = public)** and press Enter\r\n4. Type the channel name **without** a `#` prefix, then press Enter\r\n\r\nThe channel is created with a random secret. To let other Meck users join, use channel sharing (see below).\r\n\r\n### Channel Sharing via DM\r\n\r\nYou can now share any channel — public or private — with another Meck user by sending them the channel name and secret as an encrypted direct message. This is particularly useful for private channels, where sharing the secret manually would mean typing 32 hex characters.\r\n\r\n**How to share a channel:**\r\n\r\n1. From the home screen, press **S** to open settings\r\n2. Scroll down to the **Channels >>** section and press Enter to open it\r\n3. Navigate to the channel you want to share\r\n4. Press **C** to open the contact picker\r\n5. Select a contact and press Enter to send\r\n\r\nThe recipient's device automatically adds the channel to their channel list (if it doesn't already exist and there's an empty slot). An alert confirms the channel was added. In the DM conversation, both sender and recipient see a sanitised message (\"Shared channel: name\") rather than the raw protocol data.\r\n\r\nOn the T5S3, channel sharing works the same way via the CardKB keyboard.\r\n\r\n### Config Export/Import\r\n\r\nA new **Export/Import >>** sub-screen in Settings lets you back up and restore your device configuration via JSON files on the SD card. This is useful for migrating settings to a new board, keeping a backup before reflashing, or cloning a configuration across multiple devices.\r\n\r\n**Exporting:**\r\n\r\n1. From the home screen, press **S** to open settings\r\n2. Scroll down to **Export/Import >>** and press Enter\r\n3. Select **Export to SD >>** and press Enter\r\n4. Toggle which sections t\n…",
          "notesHtml": "<p>This release adds private channel support, the ability to share channels with other Meck users via encrypted DM, and a full config export/import system for backing up and migrating device configurations. Also includes two new emoji, an expanded Minesweeper grid on the T5S3, and a fix for contacts with stuck clocks sinking in the recency-sorted contacts list.</p>\n<hr />\n<h2>First-Time Flashing -- Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> -- the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> -- includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.10</h2>\n<h3>Private Channels</h3>\n<p>Meck now supports private channels alongside the existing public hashtag channels. The difference is in how the channel secret is generated:</p>\n<ul>\n<li><strong>Public (hashtag) channels</strong> — type a name starting with <code>#</code> (e.g. <code>#camping</code>). The 16-byte secret is derived deterministically from the name via SHA-256, so anyone on any MeshCore device who creates the same hashtag name gets the same key and can communicate on that channel.</li>\n<li><strong>Private channels</strong> — type a name <strong>without</strong> the <code>#</code> prefix (e.g. <code>team-alpha</code>). A cryptographically random 16-byte secret is generated, meaning only devices that have been explicitly given the key can participate.</li>\n</ul>\n<p><strong>How to create a private channel:</strong></p>\n<ol>\n<li>From the home screen, press <strong>S</strong> to open settings</li>\n<li>Scroll down to the <strong>Channels &gt;&gt;</strong> section and press Enter to open it</li>\n<li>Navigate to <strong>+ Add Channel (# = public)</strong> and press Enter</li>\n<li>Type the channel name <strong>without</strong> a <code>#</code> prefix, then press Enter</li>\n</ol>\n<p>The channel is created with a random secret. To let other Meck users join, use channel sharing (see below).</p>\n<h3>Channel Sharing via DM</h3>\n<p>You can now share any channel — public or private — with another Meck user by sending them the channel name and secret as an encrypted direct message. This is particularly useful for private channels, where sharing the secret manually would mean typing 32 hex characters.</p>\n<p><strong>How to share a channel:</strong></p>\n<ol>\n<li>From the home screen, press <strong>S</strong> to open settings</li>\n<li>Scroll down to the <strong>Channels &gt;&gt;</strong> section and press Enter to open it</li>\n<li>Navigate to the channel you want to share</li>\n<li>Press <strong>C</strong> to open the contact picker</li>\n<li>Select a contact and press Enter to send</li>\n</ol>\n<p>The recipient's device automatically adds the channel to their channel list (if it doesn't already exist and there's an empty slot). An alert confirms the channel was added. In the DM conversation, both sender and recipient see a sanitised message (\"Shared channel: name\") rather than the raw protocol data.</p>\n<p>On the T5S3, channel sharing works the same way via the CardKB keyboard.</p>\n<h3>Config Export/Import</h3>\n<p>A new <strong>Export/Import &gt;&gt;</strong> sub-screen in Settings lets you back up and restore your device configuration via JSON files on the SD card. This is useful for migrating settings to a new board, keeping a backup before reflashing, or cloning a configuration across multiple devices.</p>\n<p><strong>Exporting:</strong></p>\n<ol>\n<li>From the home screen, press <strong>S</strong> to open settings</li>\n<li>Scroll down to <strong>Export/Import &gt;&gt;</strong> and press Enter</li>\n<li>Select <strong>Export to SD &gt;&gt;</strong> and press Enter</li>\n<li>Toggle which sections t\n…</li>\n</ol>\n"
        },
        {
          "version": "v1.10",
          "name": "Meck v1.10 -- Custom Channel Notification Tones, Per-Channel Notifications, Message History Deletion, Games",
          "datetime": "2026-05-14T23:37:31Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.10",
          "prerelease": true,
          "notes": "A feature-packed update for the **T-Deck Pro**. This release adds custom notification tones for both the Audio and 4G variants, per-channel notification preferences with @mention support, the ability to delete message history per channel, a games menu with Snake and Minesweeper, and expands the maximum group channel count to 40 across all builds.\r\n\r\n---\r\n\r\n## First-Time Flashing -- Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n- **`filename.bin`** -- the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n- **`filename-merged.bin`** -- includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.io/**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n\r\n---\r\n\r\n## What's New Since v1.9\r\n\r\n### Custom Notification Tones (Audio + 4G Variants)\r\n\r\nEach channel can now have its own notification tone instead of the default buzzer. When a message arrives on a channel with a custom tone assigned, that tone plays through the speaker and the buzzer is suppressed.\r\n\r\n**How to set a custom tone:**\r\n\r\n1. From the home screen, press **S** to open settings\r\n2. Scroll down to the **Channels >>** section and press Enter to open it\r\n3. Navigate to the channel you want to customise\r\n4. Press **T** to open the tone picker\r\n5. Use **W/S** to browse the available tones, then press **Enter** to select\r\n6. To remove a custom tone, select **Default (silent)** from the top of the list\r\n\r\n**Audio variant (PCM5102A DAC):** A selection of bundled tones are copied to the `/alarms/` folder on the SD card on first boot. You can also drop your own MP3 files into that folder -- they'll appear in the tone picker alongside the bundled options. This gives you complete flexibility to use any short MP3 as a notification sound.\r\n\r\n**4G variant (A7682E modem):** Seven bundled notification tones are embedded in the firmware as 8kHz mono WAV files. On first boot (with the 4G modem enabled in settings and the red LED on and blinking to indicate the modem is ready), the tones are transferred to the modem's internal filesystem. Playback goes through the modem's own speaker amplifier. Custom user-supplied tones are not supported on the 4G variant -- only the bundled set is available. The 4G modem must be switched on in settings for the notification tones to work, as all audio output on the 4G variant goes through the modem hardware.\r\n\r\n**Available bundled tones:** Bell, Ding, High Trill, Low Soft Ding (x2), Mid Trill, and Soft Notif. All are short, 1-2 second alert sounds.\r\n\r\n### Per-Channel Notification Preferences\r\n\r\nEach channel and the DM inbox can now be individually set to one of three notification levels:\r\n\r\n- **All** -- notify on every message (default)\r\n- **@ (Mentions)** -- only notify when someone tags you with `@YourNodeName` or `@[YourNodeName]` in their message\r\n- **Off** -- completely muted (no buzzer, no custom tone, no keyboard backlight flash, no screen wake, no toast popup)\r\n\r\nMessages are always stored in history regardless of the notification setting -- only the alerts and unread badges are suppressed. You won't miss anything; you just won't be interrupted.\r\n\r\n**How to set notification preferences:**\r\n\r\n1. From the home screen, press **S** to open settings\r\n2. Scroll down to the **Channels >>** section and press Enter to open it\r\n3. Navigate to the channel you w\n…",
          "notesHtml": "<p>A feature-packed update for the <strong>T-Deck Pro</strong>. This release adds custom notification tones for both the Audio and 4G variants, per-channel notification preferences with @mention support, the ability to delete message history per channel, a games menu with Snake and Minesweeper, and expands the maximum group channel count to 40 across all builds.</p>\n<hr />\n<h2>First-Time Flashing -- Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> -- the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> -- includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.9</h2>\n<h3>Custom Notification Tones (Audio + 4G Variants)</h3>\n<p>Each channel can now have its own notification tone instead of the default buzzer. When a message arrives on a channel with a custom tone assigned, that tone plays through the speaker and the buzzer is suppressed.</p>\n<p><strong>How to set a custom tone:</strong></p>\n<ol>\n<li>From the home screen, press <strong>S</strong> to open settings</li>\n<li>Scroll down to the <strong>Channels &gt;&gt;</strong> section and press Enter to open it</li>\n<li>Navigate to the channel you want to customise</li>\n<li>Press <strong>T</strong> to open the tone picker</li>\n<li>Use <strong>W/S</strong> to browse the available tones, then press <strong>Enter</strong> to select</li>\n<li>To remove a custom tone, select <strong>Default (silent)</strong> from the top of the list</li>\n</ol>\n<p><strong>Audio variant (PCM5102A DAC):</strong> A selection of bundled tones are copied to the <code>/alarms/</code> folder on the SD card on first boot. You can also drop your own MP3 files into that folder -- they'll appear in the tone picker alongside the bundled options. This gives you complete flexibility to use any short MP3 as a notification sound.</p>\n<p><strong>4G variant (A7682E modem):</strong> Seven bundled notification tones are embedded in the firmware as 8kHz mono WAV files. On first boot (with the 4G modem enabled in settings and the red LED on and blinking to indicate the modem is ready), the tones are transferred to the modem's internal filesystem. Playback goes through the modem's own speaker amplifier. Custom user-supplied tones are not supported on the 4G variant -- only the bundled set is available. The 4G modem must be switched on in settings for the notification tones to work, as all audio output on the 4G variant goes through the modem hardware.</p>\n<p><strong>Available bundled tones:</strong> Bell, Ding, High Trill, Low Soft Ding (x2), Mid Trill, and Soft Notif. All are short, 1-2 second alert sounds.</p>\n<h3>Per-Channel Notification Preferences</h3>\n<p>Each channel and the DM inbox can now be individually set to one of three notification levels:</p>\n<ul>\n<li><strong>All</strong> -- notify on every message (default)</li>\n<li><strong>@ (Mentions)</strong> -- only notify when someone tags you with <code>@YourNodeName</code> or <code>@[YourNodeName]</code> in their message</li>\n<li><strong>Off</strong> -- completely muted (no buzzer, no custom tone, no keyboard backlight flash, no screen wake, no toast popup)</li>\n</ul>\n<p>Messages are always stored in history regardless of the notification setting -- only the alerts and unread badges are suppressed. You won't miss anything; you just won't be interrupted.</p>\n<p><strong>How to set notification preferences:</strong></p>\n<ol>\n<li>From the home screen, press <strong>S</strong> to open settings</li>\n<li>Scroll down to the <strong>Channels &gt;&gt;</strong> section and press Enter to open it</li>\n<li>Navigate to the channel you w\n…</li>\n</ol>\n"
        },
        {
          "version": "v1.9",
          "name": "Meck v1.9 — Trace Route Screen, DM Persistence, Minor fixes",
          "datetime": "2026-05-07T10:35:12Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.9",
          "prerelease": true,
          "notes": "A small but meaningful update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds an on-device trace route screen, fixes DM message history loss across reboots, and patches a handful of settings that weren't being persisted properly.\r\n\r\n---\r\n\r\n## First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n- **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n- **`filename-merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **<https://flasher.meshcore.io/>**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n    esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n\r\n---\r\n\r\n## What's New Since v1.8\r\n\r\n### 🔍 Trace Route Screen (T-Deck Pro)\r\n\r\nMeck now has an on-device equivalent to the trace path feature in the MeshCore companion app. Press **R** from the home screen to open the trace screen, build a repeater chain, and run a trace — no BLE/WiFi pairing or phone needed.\r\n\r\nThe path can be built two ways:\r\n\r\n- **+ Add repeater** — opens a picker showing all known Repeater contacts. Press Enter on a repeater to append it to the path. Repeat to build multi-hop chains.\r\n- **Type Path** — opens an inline text editor for comma-separated decimal hash values (e.g. `3601,2198,1244,2198,3601`), matching the format the companion app uses. Useful when the repeater isn't in your contacts but you know its hash.\r\n\r\nOnce the path is built, select **Run Trace** and Meck sends a `PAYLOAD_TYPE_TRACE` packet direct-routed through the chain. Each repeater that recognises its hash appends its receive SNR before forwarding. When the packet completes the round-trip, the screen shows per-hop SNR results and the round-trip time.\r\n\r\nA few things worth knowing:\r\n\r\n- **The path must be symmetric for a round-trip.** To trace through repeaters A → B → C and back, type `A,B,C,B,A`. You also need to be able to hear the last repeater in the chain (the one that responds) directly.\r\n- **1-byte vs 2-byte hash mode** is selectable on the screen and follows your device's `path.hash.mode` setting by default. The companion app uses 2-byte mode in most regions.\r\n- **Up to 16 hops**, with a 30-second timeout per trace.\r\n\r\n| Key | Action |\r\n|-----|--------|\r\n| W / S | Navigate menu items |\r\n| Enter | Select / confirm / open editor |\r\n| A / D | Toggle hash mode (1-byte / 2-byte) on the mode row |\r\n| 0–9 , | Enter path values when the inline editor is open |\r\n| Q | Cancel edit / back to home screen |\r\n\r\nT5S3 users with a CardKB attached can also access the trace screen via the **R** key.\r\n\r\n### 📩 DM Message Persistence\r\n\r\nDM message history now survives reboots correctly. Previously, the in-memory `ChannelMessage` struct tracked which peer each DM belonged to, but the on-disk `MsgFileRecord` did not — so although the messages themselves were saved to SD, every DM lost its peer association on reload and ended up in a single muddled bucket.\r\n\r\nThe fix adds a `dm_peer_hash` field to the on-disk record and bumps `MSG_FILE_VERSION` from 3 to 4. New DMs received under v1.9 will persist correctly with their peer association intact.\r\n\r\n> ⚠️ **Existing v1.8 message history on the SD card will be discarded on first boot of v1.9** due to the version bump. Channel messages and DMs received under v1.8 will not migrate forward — only messages received from v1.9 onward will appear in your history. This is a one-time eve\n…",
          "notesHtml": "<p>A small but meaningful update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds an on-device trace route screen, fixes DM message history loss across reboots, and patches a handful of settings that weren't being persisted properly.</p>\n<hr />\n<h2>First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.8</h2>\n<h3>🔍 Trace Route Screen (T-Deck Pro)</h3>\n<p>Meck now has an on-device equivalent to the trace path feature in the MeshCore companion app. Press <strong>R</strong> from the home screen to open the trace screen, build a repeater chain, and run a trace — no BLE/WiFi pairing or phone needed.</p>\n<p>The path can be built two ways:</p>\n<ul>\n<li><strong>+ Add repeater</strong> — opens a picker showing all known Repeater contacts. Press Enter on a repeater to append it to the path. Repeat to build multi-hop chains.</li>\n<li><strong>Type Path</strong> — opens an inline text editor for comma-separated decimal hash values (e.g. <code>3601,2198,1244,2198,3601</code>), matching the format the companion app uses. Useful when the repeater isn't in your contacts but you know its hash.</li>\n</ul>\n<p>Once the path is built, select <strong>Run Trace</strong> and Meck sends a <code>PAYLOAD_TYPE_TRACE</code> packet direct-routed through the chain. Each repeater that recognises its hash appends its receive SNR before forwarding. When the packet completes the round-trip, the screen shows per-hop SNR results and the round-trip time.</p>\n<p>A few things worth knowing:</p>\n<ul>\n<li><strong>The path must be symmetric for a round-trip.</strong> To trace through repeaters A → B → C and back, type <code>A,B,C,B,A</code>. You also need to be able to hear the last repeater in the chain (the one that responds) directly.</li>\n<li><strong>1-byte vs 2-byte hash mode</strong> is selectable on the screen and follows your device's <code>path.hash.mode</code> setting by default. The companion app uses 2-byte mode in most regions.</li>\n<li><strong>Up to 16 hops</strong>, with a 30-second timeout per trace.</li>\n</ul>\n<table>\n<thead>\n<tr>\n<th>Key</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>W / S</td>\n<td>Navigate menu items</td>\n</tr>\n<tr>\n<td>Enter</td>\n<td>Select / confirm / open editor</td>\n</tr>\n<tr>\n<td>A / D</td>\n<td>Toggle hash mode (1-byte / 2-byte) on the mode row</td>\n</tr>\n<tr>\n<td>0–9 ,</td>\n<td>Enter path values when the inline editor is open</td>\n</tr>\n<tr>\n<td>Q</td>\n<td>Cancel edit / back to home screen</td>\n</tr>\n</tbody></table>\n<p>T5S3 users with a CardKB attached can also access the trace screen via the <strong>R</strong> key.</p>\n<h3>📩 DM Message Persistence</h3>\n<p>DM message history now survives reboots correctly. Previously, the in-memory <code>ChannelMessage</code> struct tracked which peer each DM belonged to, but the on-disk <code>MsgFileRecord</code> did not — so although the messages themselves were saved to SD, every DM lost its peer association on reload and ended up in a single muddled bucket.</p>\n<p>The fix adds a <code>dm_peer_hash</code> field to the on-disk record and bumps <code>MSG_FILE_VERSION</code> from 3 to 4. New DMs received under v1.9 will persist correctly with their peer association intact.</p>\n<blockquote>\n<p>⚠️ <strong>Existing v1.8 message history on the SD card will be discarded on first boot of v1.9</strong> due to the version bump. Channel messages and DMs received under v1.8 will not migrate forward — only messages received from v1.9 onward will appear in your history. This is a one-time eve\n…</p>\n</blockquote>\n"
        },
        {
          "version": "v1.8",
          "name": "Meck v1.8 — Diacritics, Faster Page Scroll, True Power Off, BLE Boost",
          "datetime": "2026-05-03T11:29:22Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.8",
          "prerelease": true,
          "notes": "An update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds accented character support for international users, page scroll on all list screens, true deep sleep power-off, BLE performance improvements, and numerous fixes. Ten firmware variants across both platforms.\r\n\r\n---\r\n\r\n## First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n* **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n* **`filename-merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.io/**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n\r\n---\r\n\r\n## What's New Since v1.7\r\n\r\n### 🇨🇿 Accented Character Support\r\n\r\nMeck now properly handles accented and diacritical characters throughout the UI — channel messages, contact names, and the e-book reader. Czech (ěščřžýáíé), Polish (ąćęłńóśźż), French (àâçéèêëïôùûü), German (äöüß), and all other Latin Extended characters are now supported.\r\n\r\nPreviously, non-ASCII characters in received messages would either disappear entirely or render as emoji sprite artifacts. All three font styles now display these characters correctly — no more missing letters where diacritics used to be.\r\n\r\n**Noto Sans at Larger text size** renders accented characters with their full diacritical marks (carons, accents, cedillas, etc.) thanks to regenerated font files with Latin Extended-A glyph coverage. All other font and size combinations fold accented characters to their ASCII base letter (ě→e, ž→z, ñ→n, etc.) — you won't see the diacritic marks, but the letter itself is always visible.\r\n<img width=\"400\" height=\"400\" alt=\"586669026-a3d22972-4b66-4b2c-b736-528f814b9ca4\" src=\"https://github.com/user-attachments/assets/5000e13a-420a-4d98-ade8-a6c5c31043cd\" />\r\n<img width=\"400\" height=\"400\" alt=\"586668415-a3c38456-b98c-47f6-8c41-6cbacb2901c4\" src=\"https://github.com/user-attachments/assets/bee79868-2e2a-453b-bafc-e81759644aa7\" />\r\n\r\n### Faster Page Scroll (T-Deck Pro)\r\n\r\n**Shift+W** and **Shift+S** now jump a full page at a time on all scrollable list screens: Contacts, Discovery, Last Heard, Notes (file list), Text Reader (file list), and Settings. The page size is calculated from the screen height and current font metrics, so it adapts automatically to your font and text size choices.\r\n\r\nSingle-press W/S still scrolls one item at a time.\r\n\r\n### True Power Off (T-Deck Pro)\r\n\r\nThe home screen now includes a **Shutdown** page. Selecting it enters ESP32-S3 deep sleep with no software wake sources — the CPU halts, peripheral power is cut (keyboard, fuel gauge, sensors), and the LoRa module is powered down with NSS held high to prevent parasitic current draw.\r\n\r\n**Only a hardware reset (reset button) or USB power-on will wake the device.** This replaces the previous hibernate behaviour which maintained wake-on-packet capability. The old hibernate (with wake-on-LoRa) remains available on the auto-lock timeout.\r\n\r\n### New Emoji\r\n\r\nBeer mug (🍺) added as emoji #77. The emoji picker now has 77 total sprites.\r\n\r\n<img width=\"400\" height=\"400\" alt=\"586668547-bd80ae7c-5d09-4016-b1ea-7d219a0d681c\" src=\"https://github.com/user-attachments/assets/d1de6416-de12-43ba-a84d-dee01bbc7bfe\" />\r\n<img width=\"400\" height=\"371\" alt=\"586668673-89009912-e1af-45ee-8923-8023b5bed023\" src=\"https://github.com/user\n…",
          "notesHtml": "<p>An update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds accented character support for international users, page scroll on all list screens, true deep sleep power-off, BLE performance improvements, and numerous fixes. Ten firmware variants across both platforms.</p>\n<hr />\n<h2>First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.7</h2>\n<h3>🇨🇿 Accented Character Support</h3>\n<p>Meck now properly handles accented and diacritical characters throughout the UI — channel messages, contact names, and the e-book reader. Czech (ěščřžýáíé), Polish (ąćęłńóśźż), French (àâçéèêëïôùûü), German (äöüß), and all other Latin Extended characters are now supported.</p>\n<p>Previously, non-ASCII characters in received messages would either disappear entirely or render as emoji sprite artifacts. All three font styles now display these characters correctly — no more missing letters where diacritics used to be.</p>\n<p><strong>Noto Sans at Larger text size</strong> renders accented characters with their full diacritical marks (carons, accents, cedillas, etc.) thanks to regenerated font files with Latin Extended-A glyph coverage. All other font and size combinations fold accented characters to their ASCII base letter (ě→e, ž→z, ñ→n, etc.) — you won't see the diacritic marks, but the letter itself is always visible.\n<img alt=\"586669026-a3d22972-4b66-4b2c-b736-528f814b9ca4\" src=\"https://github.com/user-attachments/assets/5000e13a-420a-4d98-ade8-a6c5c31043cd\" />\n<img alt=\"586668415-a3c38456-b98c-47f6-8c41-6cbacb2901c4\" src=\"https://github.com/user-attachments/assets/bee79868-2e2a-453b-bafc-e81759644aa7\" /></p>\n<h3>Faster Page Scroll (T-Deck Pro)</h3>\n<p><strong>Shift+W</strong> and <strong>Shift+S</strong> now jump a full page at a time on all scrollable list screens: Contacts, Discovery, Last Heard, Notes (file list), Text Reader (file list), and Settings. The page size is calculated from the screen height and current font metrics, so it adapts automatically to your font and text size choices.</p>\n<p>Single-press W/S still scrolls one item at a time.</p>\n<h3>True Power Off (T-Deck Pro)</h3>\n<p>The home screen now includes a <strong>Shutdown</strong> page. Selecting it enters ESP32-S3 deep sleep with no software wake sources — the CPU halts, peripheral power is cut (keyboard, fuel gauge, sensors), and the LoRa module is powered down with NSS held high to prevent parasitic current draw.</p>\n<p><strong>Only a hardware reset (reset button) or USB power-on will wake the device.</strong> This replaces the previous hibernate behaviour which maintained wake-on-packet capability. The old hibernate (with wake-on-LoRa) remains available on the auto-lock timeout.</p>\n<h3>New Emoji</h3>\n<p>Beer mug (🍺) added as emoji #77. The emoji picker now has 77 total sprites.</p>\n<img alt=\"586668547-bd80ae7c-5d09-4016-b1ea-7d219a0d681c\" src=\"https://github.com/user-attachments/assets/d1de6416-de12-43ba-a84d-dee01bbc7bfe\" />\n"
        },
        {
          "version": "v1.7",
          "name": "Meck v1.7 — Channel Picker, Region Scope, Custom Fonts",
          "datetime": "2026-04-19T11:28:41Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.7",
          "prerelease": true,
          "notes": "An update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds a channel picker screen for quick channel switching, MeshCore region scope support for controlling flood message propagation, selectable font styles (Classic, Noto Sans, Montserrat), an expanded emoji picker, and numerous bug fixes. Ten firmware variants across both platforms.\r\n\r\n> **📄 Meck_README_v1.7.pdf** is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for all platforms, provided in PDF form for convenience.\r\n\r\n---\r\n\r\n## ⚠️ First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n* **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n* **`filename-merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.io/**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n\r\n---\r\n\r\n## What's New Since v1.6\r\n\r\n### 📋 Channel Picker Screen (T-Deck Pro & T5S3)\r\n\r\nThe A and D keys (T-Deck Pro) and swipe left/right (T5S3 channel screen) now open a **channel picker** instead of cycling through channels one at a time. The picker shows all your channels and the DM inbox in a single view with unread message badges, so you can jump directly to any channel.\r\n\r\nOn the T5S3, the picker displays a **vertical bubble list** matching the Meck P4 aesthetic — full-width outlined bubbles with the channel name left-aligned and unread badge right-aligned. On the T-Deck Pro, it uses a compact **vertical list**. Select a channel and press Enter (or tap) to switch to it. Press Q or Boot to go back.\r\n\r\nThe previous A/D cycling behaviour on the channel messages screen has been replaced — A and D now both open the picker. The footer hints have been updated accordingly (`A/D:List` instead of `A/D:Ch`).\r\n\r\n### 🌏 Region Scope (MeshCore v1.15+ Compatibility)\r\n\r\nMeck now supports **region scoping** for flood messages, bringing it in line with MeshCore v1.15. Regions limit how far your flood messages propagate through the mesh — when you set a region, outgoing messages are tagged with a transport code that repeaters use to decide whether to forward them. Messages sent without a region reach all repeaters via the default wildcard, same as always.\r\n\r\n**Device-wide default region:** Set a default region in **Settings → Default Region** (e.g. `au-nsw`). This applies to all channels and DMs unless a channel has its own override.\r\n\r\n**Per-channel region:** Each channel can have its own region scope. In Settings → Channels, select a channel and press Enter to edit its region. Setting a per-channel region overrides the device default for that channel only.\r\n\r\n**Serial commands:** `set region au-nsw`, `get region`, `set channel.scope 2 au-syd`, `get channel.scope 2`, `get channels` (now shows region scope tags). See the [Serial Settings Guide](Serial_Settings_Guide.md) for full documentation.\r\n\r\n**Settings nudge:** When exiting settings, if no region is configured anywhere (no device default and no per-channel scopes), a prompt reminds you to consider setting one. You can dismiss it to stay unscoped.\r\n\r\nRegion names are determined by your local mesh community — check with your local group for the names in use. Common patterns follow ISO 3166 country/subdivision codes (e.g. `au` f\n…",
          "notesHtml": "<p>An update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds a channel picker screen for quick channel switching, MeshCore region scope support for controlling flood message propagation, selectable font styles (Classic, Noto Sans, Montserrat), an expanded emoji picker, and numerous bug fixes. Ten firmware variants across both platforms.</p>\n<blockquote>\n<p><strong>📄 Meck_README_v1.7.pdf</strong> is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for all platforms, provided in PDF form for convenience.</p>\n</blockquote>\n<hr />\n<h2>⚠️ First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.6</h2>\n<h3>📋 Channel Picker Screen (T-Deck Pro &amp; T5S3)</h3>\n<p>The A and D keys (T-Deck Pro) and swipe left/right (T5S3 channel screen) now open a <strong>channel picker</strong> instead of cycling through channels one at a time. The picker shows all your channels and the DM inbox in a single view with unread message badges, so you can jump directly to any channel.</p>\n<p>On the T5S3, the picker displays a <strong>vertical bubble list</strong> matching the Meck P4 aesthetic — full-width outlined bubbles with the channel name left-aligned and unread badge right-aligned. On the T-Deck Pro, it uses a compact <strong>vertical list</strong>. Select a channel and press Enter (or tap) to switch to it. Press Q or Boot to go back.</p>\n<p>The previous A/D cycling behaviour on the channel messages screen has been replaced — A and D now both open the picker. The footer hints have been updated accordingly (<code>A/D:List</code> instead of <code>A/D:Ch</code>).</p>\n<h3>🌏 Region Scope (MeshCore v1.15+ Compatibility)</h3>\n<p>Meck now supports <strong>region scoping</strong> for flood messages, bringing it in line with MeshCore v1.15. Regions limit how far your flood messages propagate through the mesh — when you set a region, outgoing messages are tagged with a transport code that repeaters use to decide whether to forward them. Messages sent without a region reach all repeaters via the default wildcard, same as always.</p>\n<p><strong>Device-wide default region:</strong> Set a default region in <strong>Settings → Default Region</strong> (e.g. <code>au-nsw</code>). This applies to all channels and DMs unless a channel has its own override.</p>\n<p><strong>Per-channel region:</strong> Each channel can have its own region scope. In Settings → Channels, select a channel and press Enter to edit its region. Setting a per-channel region overrides the device default for that channel only.</p>\n<p><strong>Serial commands:</strong> <code>set region au-nsw</code>, <code>get region</code>, <code>set channel.scope 2 au-syd</code>, <code>get channel.scope 2</code>, <code>get channels</code> (now shows region scope tags). See the <a href=\"https://github.com/pelgraine/Meck/blob/HEAD/Serial_Settings_Guide.md\" target=\"_blank\" rel=\"noopener noreferrer\">Serial Settings Guide</a> for full documentation.</p>\n<p><strong>Settings nudge:</strong> When exiting settings, if no region is configured anywhere (no device default and no per-channel scopes), a prompt reminds you to consider setting one. You can dismiss it to stay unscoped.</p>\n<p>Region names are determined by your local mesh community — check with your local group for the names in use. Common patterns follow ISO 3166 country/subdivision codes (e.g. <code>au</code> f\n…</p>\n"
        },
        {
          "version": "v1.6",
          "name": "Meck v1.6 — Voice Notes Over LoRa, Remote Repeater, Contact Management",
          "datetime": "2026-03-30T17:08:03Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.6",
          "prerelease": true,
          "notes": "An update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds voice note recording and playback over LoRa between Meck audio devices (or to any mesh device via the Meck-Mycelium web app), a new remote repeater firmware for managing a MeshCore repeater from anywhere in the world over cellular MQTT, and refined contact export with per-contact selection. Ten firmware variants across both platforms.\r\n\r\n> **📄 Meck_README_v1.6.pdf** is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms, provided in PDF form for convenience.\r\n\r\n---\r\n\r\n## ⚠️ First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n* **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n* **`filename-merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.co.uk/**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n\r\n---\r\n\r\n## What's New Since v1.5\r\n\r\n### 🎙️ Voice Notes Over LoRa (T-Deck Pro Audio Variant)\r\n\r\nRecord and send voice messages of up to 12 seconds over LoRa — no internet, no cellular, just the mesh. Audio is encoded on-device using Codec2 at 1200 bps, which compresses each second of speech into a single 150-byte LoRa packet. This means voice notes use very little airtime relative to what they deliver — a 5-second message is just 5 packets, and a full 12-second recording is 12 packets.\r\n\r\nVoice notes can be sent to:\r\n\r\n* **Another T-Deck Pro Audio device** — the message is decoded and plays automatically through the headphone jack on receipt. Headphones are recommended as the built-in speaker is very quiet.\r\n* **Any MeshCore companion device** — connect via BLE to the [Meck-Mycelium web app](https://pelgraine.github.io/Meck-Mycelium) in a Chrome browser on your phone. Voice messages appear as tappable playback bubbles in the DM view and play through your phone's speaker.\r\n\r\nVoice notes are sent as direct messages using a pre-set path (direct or multi-hop). The packets are sent with staggered 3-second delays between each one to avoid congesting the channel, so delivery time depends on recording length and your radio preset. For example, on a 62.5 kHz / SF7 preset (e.g. Australia Narrow), a 5-second voice note takes roughly 20 seconds to arrive, and a 12-second recording takes about 42 seconds.\r\n\r\n**How to send a voice note:**\r\n\r\n1. **Set a path for your contact first.** Go to **Contacts** (press **C** from the home screen), scroll to your contact, and press **P** to open the Path Editor. Press **Enter** to select 1-byte or 2-byte path encoding, then use **S** to scroll down and either add repeater hops or set the contact as direct (zero hops). Scroll to **Save & Exit** and press **Enter**.\r\n\r\n2. **Record your message.** Press the **Microphone key** (the zero key on the T-Deck Pro keyboard) to open the Voice Messages screen. Press and **hold** the Microphone key to start recording. **Release** the key to stop. You can record up to 12 seconds.\r\n\r\n3. **Choose a recipient and send.** Press **S** to open the contact picker. Contacts with a direct (zero-hop) path appear at the top of the list for convenience. Tap or scroll to highlight your contact, then press **Enter** to send. A \"Voice sent!\" confirmation will a\n…",
          "notesHtml": "<p>An update for the T-Deck Pro and T5S3 E-Paper Pro. This release adds voice note recording and playback over LoRa between Meck audio devices (or to any mesh device via the Meck-Mycelium web app), a new remote repeater firmware for managing a MeshCore repeater from anywhere in the world over cellular MQTT, and refined contact export with per-contact selection. Ten firmware variants across both platforms.</p>\n<blockquote>\n<p><strong>📄 Meck_README_v1.6.pdf</strong> is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms, provided in PDF form for convenience.</p>\n</blockquote>\n<hr />\n<h2>⚠️ First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.co.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.co.uk/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.5</h2>\n<h3>🎙️ Voice Notes Over LoRa (T-Deck Pro Audio Variant)</h3>\n<p>Record and send voice messages of up to 12 seconds over LoRa — no internet, no cellular, just the mesh. Audio is encoded on-device using Codec2 at 1200 bps, which compresses each second of speech into a single 150-byte LoRa packet. This means voice notes use very little airtime relative to what they deliver — a 5-second message is just 5 packets, and a full 12-second recording is 12 packets.</p>\n<p>Voice notes can be sent to:</p>\n<ul>\n<li><strong>Another T-Deck Pro Audio device</strong> — the message is decoded and plays automatically through the headphone jack on receipt. Headphones are recommended as the built-in speaker is very quiet.</li>\n<li><strong>Any MeshCore companion device</strong> — connect via BLE to the <a href=\"https://pelgraine.github.io/Meck-Mycelium\" target=\"_blank\" rel=\"noopener noreferrer\">Meck-Mycelium web app</a> in a Chrome browser on your phone. Voice messages appear as tappable playback bubbles in the DM view and play through your phone's speaker.</li>\n</ul>\n<p>Voice notes are sent as direct messages using a pre-set path (direct or multi-hop). The packets are sent with staggered 3-second delays between each one to avoid congesting the channel, so delivery time depends on recording length and your radio preset. For example, on a 62.5 kHz / SF7 preset (e.g. Australia Narrow), a 5-second voice note takes roughly 20 seconds to arrive, and a 12-second recording takes about 42 seconds.</p>\n<p><strong>How to send a voice note:</strong></p>\n<ol>\n<li><p><strong>Set a path for your contact first.</strong> Go to <strong>Contacts</strong> (press <strong>C</strong> from the home screen), scroll to your contact, and press <strong>P</strong> to open the Path Editor. Press <strong>Enter</strong> to select 1-byte or 2-byte path encoding, then use <strong>S</strong> to scroll down and either add repeater hops or set the contact as direct (zero hops). Scroll to <strong>Save &amp; Exit</strong> and press <strong>Enter</strong>.</p>\n</li>\n<li><p><strong>Record your message.</strong> Press the <strong>Microphone key</strong> (the zero key on the T-Deck Pro keyboard) to open the Voice Messages screen. Press and <strong>hold</strong> the Microphone key to start recording. <strong>Release</strong> the key to stop. You can record up to 12 seconds.</p>\n</li>\n<li><p><strong>Choose a recipient and send.</strong> Press <strong>S</strong> to open the contact picker. Contacts with a direct (zero-hop) path appear at the top of the list for convenience. Tap or scroll to highlight your contact, then press <strong>Enter</strong> to send. A \"Voice sent!\" confirmation will a\n…</p>\n</li>\n</ol>\n"
        },
        {
          "version": "v1.5",
          "name": "Meck v1.5 — Alarm Clock, Larger Fonts, BLE Speed Boost, OTA Tools & OTA SD File Manager",
          "datetime": "2026-03-27T14:52:16Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.5",
          "prerelease": true,
          "notes": "An update for both the T-Deck Pro and T5S3 E-Paper Pro. This release adds an alarm clock app for the audio variant, a user-selectable larger font mode, significantly faster BLE companion contact sync, an OTA SD-based firmware file manager, upstream MeshCore routing fixes, and several bug fixes. Nine firmware variants across both platforms.\r\n\r\n> **📄 Meck\\_README\\_v1.5\\_28\\_March\\_2026.pdf** is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms.\r\n\r\n---\r\n\r\n## ⚠️ First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n* **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n* **`filename-merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **<https://flasher.meshcore.co.uk/>**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n\r\n---\r\n\r\n## What's New Since v1.3\r\n\r\n### ⏰ Alarm Clock (T-Deck Pro Audio Variant)\r\n\r\nSet up to five daily alarms that play custom MP3 sounds through the PCM5102A DAC. Alarms trigger even when the device is on other screens or playing an audiobook. A bell icon displays in the home screen UI header bar when the alarm has been set to ON.\r\n\r\n**Setup:**\r\n\r\n1. Place MP3 files (44100 Hz sample rate) in `/alarms/` on the SD card\r\n2. Open the alarm clock from the home screen (press **K**)\r\n3. Select an alarm slot (1–5), set the time, and choose an MP3 file from the list\r\n\r\n**When an alarm fires:**\r\n\r\n* The selected MP3 plays through the headphone jack\r\n* Press **Z** to snooze for 5 minutes\r\n* Press **any other key** to dismiss\r\n\r\nAlarm configuration is stored in `/alarms/.alarmcfg` on the SD card. Alarms persist across reboots — if the RTC has valid time (via GPS or companion app sync), alarms will fire at the correct time after a restart.\r\n\r\n> **Note:** MP3 files should be encoded at **44100 Hz** sample rate. Lower sample rates may cause distortion due to ESP32-S3 I2S hardware limitations (same requirement as the audiobook player).\r\n\r\n<img width=\"300\" height=\"500\" alt=\"alarm_clock\" src=\"https://github.com/user-attachments/assets/5bfe1347-a6d1-4ff0-a29b-ea20318de49f\" />\r\n\r\n### 🔤 Larger Font Mode (T-Deck Pro & T5S3)\r\n\r\nA new display option that increases the text size across channel messages, contacts, the DM inbox, and repeater admin screens. Useful for improved readability, especially on the T-Deck Pro's compact 240×320 display.\r\n\r\nEnable it in **Settings → Larger Font** (toggle on/off). The setting persists across reboots.\r\n\r\n<img width=\"300\" height=\"500\" alt=\"IMG_1852\" src=\"https://github.com/user-attachments/assets/81e26b32-48c1-4e33-a6d0-183d6140e3f6\" />\r\n\r\n### ⚡ Faster BLE Companion Sync (T-Deck Pro & T5S3)\r\n\r\nBLE contact sync with the companion app is now approximately **twice as fast**. Loading 460 contacts previously took around 30 seconds — it now completes in roughly 15 seconds. The improvement applies to both the T-Deck Pro BLE and T5S3 BLE firmware variants.\r\n\r\n### 📂 OTA Tools: SD File Manager (T-Deck Pro & T5S3)\r\n\r\nThe Settings screen now has an **OTA Tools** submenu containing two utilities: the existing **Firmware Update** and a new **SD File Manager**. The file manager creates a WiFi access point (same as the firmware updater) and serves a browser-based interface where you can \n…",
          "notesHtml": "<p>An update for both the T-Deck Pro and T5S3 E-Paper Pro. This release adds an alarm clock app for the audio variant, a user-selectable larger font mode, significantly faster BLE companion contact sync, an OTA SD-based firmware file manager, upstream MeshCore routing fixes, and several bug fixes. Nine firmware variants across both platforms.</p>\n<blockquote>\n<p><strong>📄 Meck_README_v1.5_28_March_2026.pdf</strong> is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms.</p>\n</blockquote>\n<hr />\n<h2>⚠️ First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.co.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.co.uk/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.3</h2>\n<h3>⏰ Alarm Clock (T-Deck Pro Audio Variant)</h3>\n<p>Set up to five daily alarms that play custom MP3 sounds through the PCM5102A DAC. Alarms trigger even when the device is on other screens or playing an audiobook. A bell icon displays in the home screen UI header bar when the alarm has been set to ON.</p>\n<p><strong>Setup:</strong></p>\n<ol>\n<li>Place MP3 files (44100 Hz sample rate) in <code>/alarms/</code> on the SD card</li>\n<li>Open the alarm clock from the home screen (press <strong>K</strong>)</li>\n<li>Select an alarm slot (1–5), set the time, and choose an MP3 file from the list</li>\n</ol>\n<p><strong>When an alarm fires:</strong></p>\n<ul>\n<li>The selected MP3 plays through the headphone jack</li>\n<li>Press <strong>Z</strong> to snooze for 5 minutes</li>\n<li>Press <strong>any other key</strong> to dismiss</li>\n</ul>\n<p>Alarm configuration is stored in <code>/alarms/.alarmcfg</code> on the SD card. Alarms persist across reboots — if the RTC has valid time (via GPS or companion app sync), alarms will fire at the correct time after a restart.</p>\n<blockquote>\n<p><strong>Note:</strong> MP3 files should be encoded at <strong>44100 Hz</strong> sample rate. Lower sample rates may cause distortion due to ESP32-S3 I2S hardware limitations (same requirement as the audiobook player).</p>\n</blockquote>\n<img alt=\"alarm_clock\" src=\"https://github.com/user-attachments/assets/5bfe1347-a6d1-4ff0-a29b-ea20318de49f\" /><h3>🔤 Larger Font Mode (T-Deck Pro &amp; T5S3)</h3>\n<p>A new display option that increases the text size across channel messages, contacts, the DM inbox, and repeater admin screens. Useful for improved readability, especially on the T-Deck Pro's compact 240×320 display.</p>\n<p>Enable it in <strong>Settings → Larger Font</strong> (toggle on/off). The setting persists across reboots.</p>\n<img alt=\"IMG_1852\" src=\"https://github.com/user-attachments/assets/81e26b32-48c1-4e33-a6d0-183d6140e3f6\" /><h3>⚡ Faster BLE Companion Sync (T-Deck Pro &amp; T5S3)</h3>\n<p>BLE contact sync with the companion app is now approximately <strong>twice as fast</strong>. Loading 460 contacts previously took around 30 seconds — it now completes in roughly 15 seconds. The improvement applies to both the T-Deck Pro BLE and T5S3 BLE firmware variants.</p>\n<h3>📂 OTA Tools: SD File Manager (T-Deck Pro &amp; T5S3)</h3>\n<p>The Settings screen now has an <strong>OTA Tools</strong> submenu containing two utilities: the existing <strong>Firmware Update</strong> and a new <strong>SD File Manager</strong>. The file manager creates a WiFi access point (same as the firmware updater) and serves a browser-based interface where you can \n…</p>\n"
        },
        {
          "version": "ota-1.3",
          "name": "Meck v1.3 — T-Deck Pro & T5S3 OTA Updates, DM Inbox & Roomserver Fixes",
          "datetime": "2026-03-23T04:21:31Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/ota-1.3",
          "prerelease": true,
          "notes": "An update for both the T-Deck Pro and T5S3 E-Paper Pro. This release adds over-the-air firmware update capabilities from your phone or other device, a DM inbox for reading received direct messages, roomserver message handling, and per-contact unread indicators. Nine firmware variants across both platforms.\r\n\r\n> **📄 Meck\\_README\\_v1.3\\_23\\_March\\_2026.pdf** is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms.\r\n\r\n---\r\n\r\n## ⚠️ First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n* **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install (including OTA updates from your phone).\r\n* **`filename-merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n> **⚠️ Important:** The merged filename uses a **hyphen** (`-merged.bin`) not an underscore. The MeshCore web flasher uses this suffix to detect merged firmware and flash at the correct address (0x0). Files without `-merged.bin` in the name are written at 0x10000, which will fail on a clean device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **<https://flasher.meshcore.co.uk/>**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n---\r\n\r\n## What's New Since v1.2\r\n\r\n### 📲 OTA Firmware Update (T-Deck Pro & T5S3)\r\n\r\nUpdate your firmware directly from your phone — no computer or serial cable required. The device creates a temporary WiFi access point, and you upload the new firmware via your phone's browser.\r\n\r\n**How it works:**\r\n\r\n1. Download the new `.bin` file to your phone (from GitHub Releases, Discord, etc.)\r\n2. On the device: **Settings → Firmware Update → Enter** (T-Deck Pro) or **tap** (T5S3)\r\n3. The device starts a WiFi network called `Meck-Update-XXXX` and displays the connection details\r\n4. On your phone: connect to the `Meck-Update` WiFi network, open a browser, and go to `192.168.4.1`\r\n5. Tap **Choose File**, select the `.bin`, and tap **Upload**\r\n6. The device receives the file, saves it to SD, verifies the image, flashes it to the inactive partition, and reboots\r\n\r\nTotal time is under 2 minutes. The device's existing partition layout already supports dual OTA partitions — no initial USB reflash is needed. If the new firmware fails to boot, the ESP32 bootloader automatically rolls back to the previous working firmware.\r\n\r\n> **Note:** Use the **non-merged** `.bin` file for OTA updates, not the merged binary. The merged binary includes the bootloader and partition table, which are only needed for first-time USB flashing.\r\n\r\n### 💬 DM Inbox (T-Deck Pro & T5S3)\r\n\r\nReceived direct messages can now be viewed on-device. Previously, DMs were only visible as a brief toast notification and then disappeared — there was no way to go back and read them.\r\n\r\n* **T-Deck Pro:** Press **D** past the last channel on the Channel Messages screen to reach the DM inbox. Press **A** to return to group channels.\r\n* **T5S3:** Swipe left past the last channel on the Channel Messages screen to reach the DM inbox. Swipe right to return to group channels.\r\n\r\nThe DM inbox shows all received direct messages with sender name and timestamp, sorted by arrival order. Entering the DM inbox automatically marks all DM messages as read.\r\n\r\n### ✉️ Per-Contact DM Unread Indicator (T-Deck Pro & T5S3)\r\n\r\nContacts with unread direct messages now show a `*` marker next to their name i\n…",
          "notesHtml": "<p>An update for both the T-Deck Pro and T5S3 E-Paper Pro. This release adds over-the-air firmware update capabilities from your phone or other device, a DM inbox for reading received direct messages, roomserver message handling, and per-contact unread indicators. Nine firmware variants across both platforms.</p>\n<blockquote>\n<p><strong>📄 Meck_README_v1.3_23_March_2026.pdf</strong> is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms.</p>\n</blockquote>\n<hr />\n<h2>⚠️ First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install (including OTA updates from your phone).</li>\n<li><strong><code>filename-merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<blockquote>\n<p><strong>⚠️ Important:</strong> The merged filename uses a <strong>hyphen</strong> (<code>-merged.bin</code>) not an underscore. The MeshCore web flasher uses this suffix to detect merged firmware and flash at the correct address (0x0). Files without <code>-merged.bin</code> in the name are written at 0x10000, which will fail on a clean device.</p>\n</blockquote>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.co.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.co.uk/</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<hr />\n<h2>What's New Since v1.2</h2>\n<h3>📲 OTA Firmware Update (T-Deck Pro &amp; T5S3)</h3>\n<p>Update your firmware directly from your phone — no computer or serial cable required. The device creates a temporary WiFi access point, and you upload the new firmware via your phone's browser.</p>\n<p><strong>How it works:</strong></p>\n<ol>\n<li>Download the new <code>.bin</code> file to your phone (from GitHub Releases, Discord, etc.)</li>\n<li>On the device: <strong>Settings → Firmware Update → Enter</strong> (T-Deck Pro) or <strong>tap</strong> (T5S3)</li>\n<li>The device starts a WiFi network called <code>Meck-Update-XXXX</code> and displays the connection details</li>\n<li>On your phone: connect to the <code>Meck-Update</code> WiFi network, open a browser, and go to <code>192.168.4.1</code></li>\n<li>Tap <strong>Choose File</strong>, select the <code>.bin</code>, and tap <strong>Upload</strong></li>\n<li>The device receives the file, saves it to SD, verifies the image, flashes it to the inactive partition, and reboots</li>\n</ol>\n<p>Total time is under 2 minutes. The device's existing partition layout already supports dual OTA partitions — no initial USB reflash is needed. If the new firmware fails to boot, the ESP32 bootloader automatically rolls back to the previous working firmware.</p>\n<blockquote>\n<p><strong>Note:</strong> Use the <strong>non-merged</strong> <code>.bin</code> file for OTA updates, not the merged binary. The merged binary includes the bootloader and partition table, which are only needed for first-time USB flashing.</p>\n</blockquote>\n<h3>💬 DM Inbox (T-Deck Pro &amp; T5S3)</h3>\n<p>Received direct messages can now be viewed on-device. Previously, DMs were only visible as a brief toast notification and then disappeared — there was no way to go back and read them.</p>\n<ul>\n<li><strong>T-Deck Pro:</strong> Press <strong>D</strong> past the last channel on the Channel Messages screen to reach the DM inbox. Press <strong>A</strong> to return to group channels.</li>\n<li><strong>T5S3:</strong> Swipe left past the last channel on the Channel Messages screen to reach the DM inbox. Swipe right to return to group channels.</li>\n</ul>\n<p>The DM inbox shows all received direct messages with sender name and timestamp, sorted by arrival order. Entering the DM inbox automatically marks all DM messages as read.</p>\n<h3>✉️ Per-Contact DM Unread Indicator (T-Deck Pro &amp; T5S3)</h3>\n<p>Contacts with unread direct messages now show a <code>*</code> marker next to their name i\n…</p>\n"
        },
        {
          "version": "v1.2",
          "name": "Meck v1.2 — T-Deck Pro & T5S3 Update & Bugfixes",
          "datetime": "2026-03-20T10:41:27Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.2",
          "prerelease": true,
          "notes": "An update for both the T-Deck Pro and T5S3 E-Paper Pro. New features include a lock screen, last heard advert list, touch tap-to-select across all list screens, non-blocking contact saves, and CardKB external keyboard support for the T5S3. Nine firmware variants across both platforms.\r\n\r\n> **📄 Meck_README_v1.2_March_2026.pdf** is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms.\r\n\r\n---\r\n\r\n## ⚠️ First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n* **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install.\r\n* **`filename-merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `-merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n> **⚠️ Important:** The merged filename now uses a **hyphen** (`-merged.bin`) instead of an underscore. The MeshCore web flasher uses this suffix to detect merged firmware and flash at the correct address (0x0). Files without `-merged.bin` in the name are written at 0x10000, which will fail on a clean device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.co.uk**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `-merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\r\n```\r\n\r\n> **Note:** On first boot after a fresh flash (or after erasing flash), you may see a SPIFFS mount error in serial output — this is normal. The filesystem auto-formats on first boot and everything proceeds as expected.\r\n\r\n---\r\n\r\n## What's New Since v1.1\r\n\r\n### 🔒 Lock Screen (T-Deck Pro & T5S3)\r\n\r\nBoth platforms now have a lock screen that shows the current time, battery percentage, and unread message count.\r\n\r\n* **T-Deck Pro:** Double-click the Boot button to lock/unlock\r\n* **T5S3:** Long press the Boot button to lock/unlock\r\n\r\nAn auto-lock timer is available in **Settings → Auto Lock** with options for None, 2, 5, 10, 15, or 30 minutes of idle time. The CPU drops to 40 MHz while locked to reduce power consumption. The clock refreshes every 15 minutes while locked.\r\n\r\n### 📡 Last Heard Screen (T-Deck Pro & T5S3)\r\n\r\nA new passive advert list showing all recently heard nodes sorted by recency. Unlike Discovery (which does an active zero-hop scan), Last Heard is purely passive — it shows nodes whose adverts have been received over time.\r\n\r\n* Press **H** from the home screen (T-Deck Pro) or swipe to the Recent Adverts home page and tap \"Tap here for full Last Heard list\" (T5S3)\r\n* Shows node type, name, time since last heard, hop count\r\n* Nodes already in contacts are marked with `[+]`, favourites with `[★]`\r\n* Add or remove contacts directly from the list\r\n\r\n### 👆 Tap-to-Select (T-Deck Pro & T5S3)\r\n\r\nTap on any row in Contacts, Discovery, Last Heard, Settings, Text Reader file list, and Notes to select it. Tap the same row again (or press Enter) to activate. This brings touch interaction to the T-Deck Pro for the first time on list screens.\r\n\r\n### 💾 Non-Blocking Contact Save\r\n\r\nLarge contact lists previously blocked the main loop for 500ms+ during save. Contact saves now happen in chunks across multiple loop iterations (20 contacts per chunk, ~30ms each). A write-then-verify-then-rename pattern prevents corruption if the save is interrupted.\r\n\r\n### ⌨️ CardKB Support (T5S3)\r\n\r\nThe T5S3 now supports the M5Stack CardKB (or compatible I2C keyboard) connected via the QWIIC port. When detected at boot, the CardKB can be used for all text input — composing messages, entering URLs, editing \n…",
          "notesHtml": "<p>An update for both the T-Deck Pro and T5S3 E-Paper Pro. New features include a lock screen, last heard advert list, touch tap-to-select across all list screens, non-blocking contact saves, and CardKB external keyboard support for the T5S3. Nine firmware variants across both platforms.</p>\n<blockquote>\n<p><strong>📄 Meck_README_v1.2_March_2026.pdf</strong> is included in this release — it covers all keyboard controls, touch gestures, screen navigation, settings, and feature documentation for both platforms.</p>\n</blockquote>\n<hr />\n<h2>⚠️ First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install.</li>\n<li><strong><code>filename-merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>-merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<blockquote>\n<p><strong>⚠️ Important:</strong> The merged filename now uses a <strong>hyphen</strong> (<code>-merged.bin</code>) instead of an underscore. The MeshCore web flasher uses this suffix to detect merged firmware and flash at the correct address (0x0). Files without <code>-merged.bin</code> in the name are written at 0x10000, which will fail on a clean device.</p>\n</blockquote>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.co.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.co.uk</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>-merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware-merged.bin\n</code></pre>\n<blockquote>\n<p><strong>Note:</strong> On first boot after a fresh flash (or after erasing flash), you may see a SPIFFS mount error in serial output — this is normal. The filesystem auto-formats on first boot and everything proceeds as expected.</p>\n</blockquote>\n<hr />\n<h2>What's New Since v1.1</h2>\n<h3>🔒 Lock Screen (T-Deck Pro &amp; T5S3)</h3>\n<p>Both platforms now have a lock screen that shows the current time, battery percentage, and unread message count.</p>\n<ul>\n<li><strong>T-Deck Pro:</strong> Double-click the Boot button to lock/unlock</li>\n<li><strong>T5S3:</strong> Long press the Boot button to lock/unlock</li>\n</ul>\n<p>An auto-lock timer is available in <strong>Settings → Auto Lock</strong> with options for None, 2, 5, 10, 15, or 30 minutes of idle time. The CPU drops to 40 MHz while locked to reduce power consumption. The clock refreshes every 15 minutes while locked.</p>\n<h3>📡 Last Heard Screen (T-Deck Pro &amp; T5S3)</h3>\n<p>A new passive advert list showing all recently heard nodes sorted by recency. Unlike Discovery (which does an active zero-hop scan), Last Heard is purely passive — it shows nodes whose adverts have been received over time.</p>\n<ul>\n<li>Press <strong>H</strong> from the home screen (T-Deck Pro) or swipe to the Recent Adverts home page and tap \"Tap here for full Last Heard list\" (T5S3)</li>\n<li>Shows node type, name, time since last heard, hop count</li>\n<li>Nodes already in contacts are marked with <code>[+]</code>, favourites with <code>[★]</code></li>\n<li>Add or remove contacts directly from the list</li>\n</ul>\n<h3>👆 Tap-to-Select (T-Deck Pro &amp; T5S3)</h3>\n<p>Tap on any row in Contacts, Discovery, Last Heard, Settings, Text Reader file list, and Notes to select it. Tap the same row again (or press Enter) to activate. This brings touch interaction to the T-Deck Pro for the first time on list screens.</p>\n<h3>💾 Non-Blocking Contact Save</h3>\n<p>Large contact lists previously blocked the main loop for 500ms+ during save. Contact saves now happen in chunks across multiple loop iterations (20 contacts per chunk, ~30ms each). A write-then-verify-then-rename pattern prevents corruption if the save is interrupted.</p>\n<h3>⌨️ CardKB Support (T5S3)</h3>\n<p>The T5S3 now supports the M5Stack CardKB (or compatible I2C keyboard) connected via the QWIIC port. When detected at boot, the CardKB can be used for all text input — composing messages, entering URLs, editing \n…</p>\n"
        },
        {
          "version": "tdpro-v1.1",
          "name": "Meck v1.1 — T-Deck Pro Update",
          "datetime": "2026-03-15T04:46:27Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/tdpro-v1.1",
          "prerelease": true,
          "notes": "A T-Deck Pro–only update with settings screen improvements, GPS fixes, and a new 2000mAh 4G standalone variant. Eight firmware variants for the T-Deck Pro — the T5S3 E-Paper Pro remains on [v1.0](https://github.com/pelgraine/Meck/releases/tag/v1.0) for now.\r\n\r\n> **📄 Meck_Firmware_Guide — 15 March 2026.pdf** is included in this release for easy reference — it covers all keyboard controls, screen navigation, settings, and feature documentation for both platforms.\r\n\r\n> **📦 Convenience ZIP:** `v1.1-Meck-T-Deck-Pro-firmware.zip` bundles all T-Deck Pro variants into a single download.\r\n\r\n---\r\n\r\n## ⚠️ First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n* **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install.\r\n* **`filename_merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `_merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.co.uk**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `_merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\nIf you prefer the command line, `esptool.py` can be used to flash firmware directly. First-time users should use the `_merged.bin` which includes everything the device needs to boot:\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware_merged.bin\r\n```\r\n\r\n> **Note:** On first boot after a fresh flash (or after erasing flash), you may see a SPIFFS mount error in serial output — this is normal. The filesystem auto-formats on first boot and everything proceeds as expected.\r\n\r\n---\r\n\r\n## What's New Since v1.0\r\n\r\n### ⚙️ Settings Screen Reorganisation\r\n\r\nThe settings screen has been restructured for clarity. Contacts and Channels are now in their own sub-screens instead of being listed inline:\r\n\r\n* **Contacts >>** — opens a dedicated sub-screen for the contact auto-add mode picker (Auto All / Custom / Manual) and per-type toggles\r\n* **Channels >>** — opens a dedicated sub-screen for viewing, adding, and deleting channels\r\n\r\nPress **Enter** to open a sub-screen and **Q** to return to the top-level settings list. Your cursor position is remembered when navigating back.\r\n\r\n### 📡 GPS Baud Rate in Settings\r\n\r\nThe GPS baud rate can now be changed on-screen in Settings (previously serial-only). Cycle through options with **A / D** — available rates are Default (38400), 4800, 9600, 19200, 38400, 57600, and 115200. Requires a reboot to take effect.\r\n\r\n### 🔢 Frequency Text Entry\r\n\r\nThe frequency setting now uses direct text entry instead of increment/decrement. Type the exact value (e.g. `916.575`) and press **Enter** to confirm — much faster for precise tuning.\r\n\r\n### 🛰️ GPS Initialisation Fix\r\n\r\nFixed a bug where `Serial1` (used by the sensor library's GPS init) was not properly released before reinitialising `Serial2` for the GPS stream. This could cause GPS to silently fail to receive data on some boots. The fix ensures `Serial1.end()` is called before `Serial2.begin()`, cleanly handing the UART pins back to the GPS parser.\r\n\r\n### 🔧 Preferences Validation on Upgrade\r\n\r\nWhen upgrading from older firmware versions, stored preferences may contain garbage values in fields that didn't exist before. v1.1 now clamps invalid values on boot — `path_hash_mode`, `dark_mode`, `portrait_mode`, `autoadd_max_hops`, and `interference_threshold` are all validated and reset to safe defaults if out of range. This prevents unexpected behaviour after a firmware upgrade without erasing flash.\r\n\r\n---\r\n\r\n## T-Deck Pro Firmware Variants\r\n\r\nSix firmware variants for the LilyGo T-Deck Pro. Pi\n…",
          "notesHtml": "<p>A T-Deck Pro–only update with settings screen improvements, GPS fixes, and a new 2000mAh 4G standalone variant. Eight firmware variants for the T-Deck Pro — the T5S3 E-Paper Pro remains on <a href=\"https://github.com/pelgraine/Meck/releases/tag/v1.0\" target=\"_blank\" rel=\"noopener noreferrer\">v1.0</a> for now.</p>\n<blockquote>\n<p><strong>📄 Meck_Firmware_Guide — 15 March 2026.pdf</strong> is included in this release for easy reference — it covers all keyboard controls, screen navigation, settings, and feature documentation for both platforms.</p>\n</blockquote>\n<blockquote>\n<p><strong>📦 Convenience ZIP:</strong> <code>v1.1-Meck-T-Deck-Pro-firmware.zip</code> bundles all T-Deck Pro variants into a single download.</p>\n</blockquote>\n<hr />\n<h2>⚠️ First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install.</li>\n<li><strong><code>filename_merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>_merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.co.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.co.uk</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>_merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<p>If you prefer the command line, <code>esptool.py</code> can be used to flash firmware directly. First-time users should use the <code>_merged.bin</code> which includes everything the device needs to boot:</p>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware_merged.bin\n</code></pre>\n<blockquote>\n<p><strong>Note:</strong> On first boot after a fresh flash (or after erasing flash), you may see a SPIFFS mount error in serial output — this is normal. The filesystem auto-formats on first boot and everything proceeds as expected.</p>\n</blockquote>\n<hr />\n<h2>What's New Since v1.0</h2>\n<h3>⚙️ Settings Screen Reorganisation</h3>\n<p>The settings screen has been restructured for clarity. Contacts and Channels are now in their own sub-screens instead of being listed inline:</p>\n<ul>\n<li><strong>Contacts &gt;&gt;</strong> — opens a dedicated sub-screen for the contact auto-add mode picker (Auto All / Custom / Manual) and per-type toggles</li>\n<li><strong>Channels &gt;&gt;</strong> — opens a dedicated sub-screen for viewing, adding, and deleting channels</li>\n</ul>\n<p>Press <strong>Enter</strong> to open a sub-screen and <strong>Q</strong> to return to the top-level settings list. Your cursor position is remembered when navigating back.</p>\n<h3>📡 GPS Baud Rate in Settings</h3>\n<p>The GPS baud rate can now be changed on-screen in Settings (previously serial-only). Cycle through options with <strong>A / D</strong> — available rates are Default (38400), 4800, 9600, 19200, 38400, 57600, and 115200. Requires a reboot to take effect.</p>\n<h3>🔢 Frequency Text Entry</h3>\n<p>The frequency setting now uses direct text entry instead of increment/decrement. Type the exact value (e.g. <code>916.575</code>) and press <strong>Enter</strong> to confirm — much faster for precise tuning.</p>\n<h3>🛰️ GPS Initialisation Fix</h3>\n<p>Fixed a bug where <code>Serial1</code> (used by the sensor library's GPS init) was not properly released before reinitialising <code>Serial2</code> for the GPS stream. This could cause GPS to silently fail to receive data on some boots. The fix ensures <code>Serial1.end()</code> is called before <code>Serial2.begin()</code>, cleanly handing the UART pins back to the GPS parser.</p>\n<h3>🔧 Preferences Validation on Upgrade</h3>\n<p>When upgrading from older firmware versions, stored preferences may contain garbage values in fields that didn't exist before. v1.1 now clamps invalid values on boot — <code>path_hash_mode</code>, <code>dark_mode</code>, <code>portrait_mode</code>, <code>autoadd_max_hops</code>, and <code>interference_threshold</code> are all validated and reset to safe defaults if out of range. This prevents unexpected behaviour after a firmware upgrade without erasing flash.</p>\n<hr />\n<h2>T-Deck Pro Firmware Variants</h2>\n<p>Six firmware variants for the LilyGo T-Deck Pro. Pi\n…</p>\n"
        },
        {
          "version": "v1.0",
          "name": "Meck v1.0 — Unified Release for T-Deck Pro & T5S3 E-Paper Pro",
          "datetime": "2026-03-13T12:47:04Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v1.0",
          "prerelease": true,
          "notes": "The first combined release covering both supported hardware platforms. Ten firmware variants across two devices, one codebase.\r\n\r\n> **📄 Meck v1.0 Readme Guide - March 2026.pdf** is included in this release for easy reference — it covers all keyboard controls, screen navigation, settings, and feature documentation for both platforms.\r\n\r\n> **📦 Convenience ZIPs:** `v1.0-Meck-T-Deck-Pro-firmware.zip` and `v1.0-Meck-T5S3-firmware.zip` bundle all variants for each platform into a single download.\r\n\r\n---\r\n\r\n## ⚠️ First-Time Flashing — Read This First\r\n\r\nEach firmware is provided in two formats:\r\n\r\n- **`filename.bin`** — the application firmware only. Use this for **updating** an existing Meck install.\r\n- **`filename_merged.bin`** — includes the bootloader, partition table, and application firmware in a single image. **Use this if you are flashing Meck for the first time**, coming from a different firmware, or if your device is not booting correctly after an update.\r\n\r\n**If in doubt, use the `_merged.bin` file.** It will always work regardless of what was previously on the device.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to **https://flasher.meshcore.co.uk**\r\n2. Select **Custom Firmware**\r\n3. Load the `.bin` or `_merged.bin` file and click **Flash**\r\n4. Select your device in the popup and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\nIf you prefer the command line, `esptool.py` can be used to flash firmware directly. First-time users should use the `_merged.bin` which includes everything the device needs to boot:\r\n\r\n```\r\nesptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware_merged.bin\r\n```\r\n\r\n> **Note:** On first boot after a fresh flash (or after erasing flash), you may see a SPIFFS mount error in serial output — this is normal. The filesystem auto-formats on first boot and everything proceeds as expected.\r\n\r\n---\r\n\r\n## What's New Since v0.9.8 (T-Deck Pro)\r\n\r\n### 🔗 Multibyte Path Hash Support\r\n\r\nMeck now supports MeshCore v1.14's multibyte path hash mode, which significantly reduces hash collisions in larger networks. You can choose the path hash size in the Settings screen (press **S** from the home screen) or set it via USB serial with `set path.hash.mode {0,1,2}`.\r\n\r\n| Mode | Bytes/hop | Max hops | Notes |\r\n|------|-----------|----------|-------|\r\n| 0 | 1 | 64 | Legacy — prone to hash collisions in larger networks |\r\n| 1 | 2 | 32 | Recommended — effectively eliminates collisions |\r\n| 2 | 3 | 21 | Maximum precision, rarely needed |\r\n\r\nNodes with different modes coexist on the same network — the mode only affects packets your node originates. Read more about what this means in practice: https://buymeacoffee.com/ripplebiz/path-diagnostics-improvements\r\n\r\n### 🌑 Dark Mode (T-Deck Pro & T5S3)\r\n\r\nDark mode is now available on the T-Deck Pro as well as the T5S3. Toggle it in Settings to invert the display — white text on a black background. The setting persists across reboots.\r\n\r\n<img src=\"https://github.com/user-attachments/assets/084a72c5-4a6e-4e45-b17a-f01f3861bd3c\" alt=\"IMG_1649\" width=\"300\" height=\"650\">\r\n\r\n### 📡 Mesh Tuning via Serial CLI\r\n\r\nNew serial commands for advanced mesh tuning — all configurable over USB without needing to recompile:\r\n\r\n* **`rxdelay`** — SNR-based flood delay (0–20, 0=disabled). Stronger signals processed first; weaker copies delayed and typically discarded as duplicates. Values below 1.0 have no practical effect. See the [MeshSydney wiki](https://meshsydney.com/wiki) for tuning profiles.\r\n* **`af`** — Airtime factor (0–9, default 1.0). Adjusts internal timing windows. Keep consistent across nodes in your mesh.\r\n* **`multi.acks`** — Redundant ACKs for direct messages (0 or 1, **default changed to 1**). Sends two ACKs instead of one for improved delivery confirmation.\r\n* **`int.thresh`** — Interference threshold in dB (0=disabled, 14+=enabled). Scans channel activity before transmitting. Adds ~4s receive delay per packet — only recommended for high RF in\n…",
          "notesHtml": "<p>The first combined release covering both supported hardware platforms. Ten firmware variants across two devices, one codebase.</p>\n<blockquote>\n<p><strong>📄 Meck v1.0 Readme Guide - March 2026.pdf</strong> is included in this release for easy reference — it covers all keyboard controls, screen navigation, settings, and feature documentation for both platforms.</p>\n</blockquote>\n<blockquote>\n<p><strong>📦 Convenience ZIPs:</strong> <code>v1.0-Meck-T-Deck-Pro-firmware.zip</code> and <code>v1.0-Meck-T5S3-firmware.zip</code> bundle all variants for each platform into a single download.</p>\n</blockquote>\n<hr />\n<h2>⚠️ First-Time Flashing — Read This First</h2>\n<p>Each firmware is provided in two formats:</p>\n<ul>\n<li><strong><code>filename.bin</code></strong> — the application firmware only. Use this for <strong>updating</strong> an existing Meck install.</li>\n<li><strong><code>filename_merged.bin</code></strong> — includes the bootloader, partition table, and application firmware in a single image. <strong>Use this if you are flashing Meck for the first time</strong>, coming from a different firmware, or if your device is not booting correctly after an update.</li>\n</ul>\n<p><strong>If in doubt, use the <code>_merged.bin</code> file.</strong> It will always work regardless of what was previously on the device.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <strong><a href=\"https://flasher.meshcore.co.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.co.uk</a></strong></li>\n<li>Select <strong>Custom Firmware</strong></li>\n<li>Load the <code>.bin</code> or <code>_merged.bin</code> file and click <strong>Flash</strong></li>\n<li>Select your device in the popup and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<p>If you prefer the command line, <code>esptool.py</code> can be used to flash firmware directly. First-time users should use the <code>_merged.bin</code> which includes everything the device needs to boot:</p>\n<pre><code>esptool.py --port /dev/ttyACM0 --baud 921600 write_flash 0x0 firmware_merged.bin\n</code></pre>\n<blockquote>\n<p><strong>Note:</strong> On first boot after a fresh flash (or after erasing flash), you may see a SPIFFS mount error in serial output — this is normal. The filesystem auto-formats on first boot and everything proceeds as expected.</p>\n</blockquote>\n<hr />\n<h2>What's New Since v0.9.8 (T-Deck Pro)</h2>\n<h3>🔗 Multibyte Path Hash Support</h3>\n<p>Meck now supports MeshCore v1.14's multibyte path hash mode, which significantly reduces hash collisions in larger networks. You can choose the path hash size in the Settings screen (press <strong>S</strong> from the home screen) or set it via USB serial with <code>set path.hash.mode {0,1,2}</code>.</p>\n<table>\n<thead>\n<tr>\n<th>Mode</th>\n<th>Bytes/hop</th>\n<th>Max hops</th>\n<th>Notes</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>0</td>\n<td>1</td>\n<td>64</td>\n<td>Legacy — prone to hash collisions in larger networks</td>\n</tr>\n<tr>\n<td>1</td>\n<td>2</td>\n<td>32</td>\n<td>Recommended — effectively eliminates collisions</td>\n</tr>\n<tr>\n<td>2</td>\n<td>3</td>\n<td>21</td>\n<td>Maximum precision, rarely needed</td>\n</tr>\n</tbody></table>\n<p>Nodes with different modes coexist on the same network — the mode only affects packets your node originates. Read more about what this means in practice: <a href=\"https://buymeacoffee.com/ripplebiz/path-diagnostics-improvements\" target=\"_blank\" rel=\"noopener noreferrer\">https://buymeacoffee.com/ripplebiz/path-diagnostics-improvements</a></p>\n<h3>🌑 Dark Mode (T-Deck Pro &amp; T5S3)</h3>\n<p>Dark mode is now available on the T-Deck Pro as well as the T5S3. Toggle it in Settings to invert the display — white text on a black background. The setting persists across reboots.</p>\n<img src=\"https://github.com/user-attachments/assets/084a72c5-4a6e-4e45-b17a-f01f3861bd3c\" alt=\"IMG_1649\" /><h3>📡 Mesh Tuning via Serial CLI</h3>\n<p>New serial commands for advanced mesh tuning — all configurable over USB without needing to recompile:</p>\n<ul>\n<li><strong><code>rxdelay</code></strong> — SNR-based flood delay (0–20, 0=disabled). Stronger signals processed first; weaker copies delayed and typically discarded as duplicates. Values below 1.0 have no practical effect. See the <a href=\"https://meshsydney.com/wiki\" target=\"_blank\" rel=\"noopener noreferrer\">MeshSydney wiki</a> for tuning profiles.</li>\n<li><strong><code>af</code></strong> — Airtime factor (0–9, default 1.0). Adjusts internal timing windows. Keep consistent across nodes in your mesh.</li>\n<li><strong><code>multi.acks</code></strong> — Redundant ACKs for direct messages (0 or 1, <strong>default changed to 1</strong>). Sends two ACKs instead of one for improved delivery confirmation.</li>\n<li><strong><code>int.thresh</code></strong> — Interference threshold in dB (0=disabled, 14+=enabled). Scans channel activity before transmitting. Adds ~4s receive delay per packet — only recommended for high RF in\n…</li>\n</ul>\n"
        },
        {
          "version": "t5s3-1",
          "name": "Meck v1.0 - Community Firmware Builds for the LilyGo T5S3 E-Paper Pro H752-01B (NO GPS)",
          "datetime": "2026-03-12T12:59:32Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/t5s3-1",
          "prerelease": true,
          "notes": "### _*THIS FIRMWARE WILL NOT WORK IF YOUR LILYGO T5 E-PAPER S3 PRO HAS GPS*_\r\n\r\nMore details to follow on how to use it, but it's pretty self-explanatory once you flash the firmware. Takes a little bit to get used to the swipe-drag motion for scrolling through menu options.\r\n\r\nUsual Meck Wifi and BLE companion modes, now with Dark Mode and Portrait Mode for the T5S3. \r\n\r\n- Double click the Boot button to turn the backlight on or off. \r\n- Triple click the Boot button to turn on low-brightness backlight for night reading. \r\n- Hold down the boot button for a long press (3+ seconds) to activate the lock screen. \r\n\r\nNo maps in this one as there's no GPS. Time is set when you link to the Meshcore app on your phone or computer, either via wifi or BLE. The RTC will keep the time after that first pairing.",
          "notesHtml": "<h3><em><em>THIS FIRMWARE WILL NOT WORK IF YOUR LILYGO T5 E-PAPER S3 PRO HAS GPS</em></em></h3>\n<p>More details to follow on how to use it, but it's pretty self-explanatory once you flash the firmware. Takes a little bit to get used to the swipe-drag motion for scrolling through menu options.</p>\n<p>Usual Meck Wifi and BLE companion modes, now with Dark Mode and Portrait Mode for the T5S3. </p>\n<ul>\n<li>Double click the Boot button to turn the backlight on or off. </li>\n<li>Triple click the Boot button to turn on low-brightness backlight for night reading. </li>\n<li>Hold down the boot button for a long press (3+ seconds) to activate the lock screen.</li>\n</ul>\n<p>No maps in this one as there's no GPS. Time is set when you link to the Meshcore app on your phone or computer, either via wifi or BLE. The RTC will keep the time after that first pairing.</p>\n"
        },
        {
          "version": "multi-byte-1",
          "name": "Meck v0.9.9 - multibyte path hash support!",
          "datetime": "2026-03-06T18:26:10Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/multi-byte-1",
          "prerelease": true,
          "notes": "---\r\n\r\n## What's New Since v0.9.8\r\n\r\nMultibyte path hash support to bring Meck in line with recent updates in Meshcore firmware v1.14. You can now choose the path hash size in the T-Deck Pro device settings (via the S key from the home screen) or set it via serial over USB to your T-Deck Pro with `set path.hash.mode {0,1,2}`\r\n\r\nRead a run-down on what multibyte path hash implementation means: [https://buymeacoffee.com/ripplebiz/path-diagnostics-improvements](https://buymeacoffee.com/ripplebiz/path-diagnostics-improvements)\r\n\r\n---\r\n\r\nSix firmware variants, one codebase. Pick the right `.bin` for your hardware:\r\n\r\n---\r\n\r\n## Firmware Variants\r\n\r\n**`v0.9.9-Meck-4G-BLE.bin`**\r\nFor T-Deck Pro 4G boards. Full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, GPS, map viewer, BLE companion app support, SMS & Phone app, IRC client, and web browser. Up to 500 contacts and 20 channels.\r\n\r\n> Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.\r\n\r\n**`v0.9.9W-Meck-4G-WiFi.bin`**\r\nFor T-Deck Pro 4G boards. Same as the 4G-BLE build but with WiFi replacing BLE as the companion transport — connect via the MeshCore web app, iOS/Android app, meshcore.js, or Python CLI over your local network (TCP port 5000). WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to **1,500 contacts** and 20 channels.\r\n\r\nAlso available for those with a custom 2000mah battery build.\r\n\r\n**`v0.9.9-4G.SA-Meck-standalone.bin`**\r\nFor T-Deck Pro 4G boards. No BLE or WiFi companion — maximum battery life. The web browser, IRC client, and map viewer are all still available (they use WiFi independently, not as a companion transport). Up to 1,500 contacts and 20 channels.\r\n\r\n**`v0.9.9A-Meck-Audio-BLE.bin`**\r\nEverything in the 4G-BLE build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. BLE companion support included. Up to 500 contacts and 20 channels.\r\n\r\n> ⚠️ PCM5102A audio hardware only. The I2S audio pins (GPIO 7, 8, 9) conflict with the A7682E modem control lines — do not flash on 4G boards.\r\n\r\n> Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.\r\n\r\n**`v0.9.9AW-Meck-Audio-WiFi.bin`**\r\nSame as the Audio-BLE build but with WiFi replacing BLE as the companion transport. WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to **1,500 contacts** and 20 channels.\r\n\r\n> ⚠️ PCM5102A audio hardware only — same GPIO conflict applies. Do not flash on 4G boards.\r\n\r\n**`v0.9.9A-SA-Meck-standalone.bin`**\r\nSame as the Audio-BLE build but with Bluetooth and WiFi completely removed at compile time. The radio hardware is never initialised, giving a significant battery life improvement. The web browser, IRC client, and map viewer are not available on this variant. Up to 1,500 contacts and 20 channels.\r\n\r\n> Battery life: Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.\r\n\r\n> ⚠️ PCM5102A audio hardware only — do not flash on 4G boards.\r\n\r\n---\r\n\r\nSee all the features and updates that are available in Meck from v0.9.8 onwards here: [https://github.com/pelgraine/Meck/releases/tag/wifi-1](https://github.com/pelgraine/Meck/releases/tag/wifi-1)",
          "notesHtml": "<hr />\n<h2>What's New Since v0.9.8</h2>\n<p>Multibyte path hash support to bring Meck in line with recent updates in Meshcore firmware v1.14. You can now choose the path hash size in the T-Deck Pro device settings (via the S key from the home screen) or set it via serial over USB to your T-Deck Pro with <code>set path.hash.mode {0,1,2}</code></p>\n<p>Read a run-down on what multibyte path hash implementation means: <a href=\"https://buymeacoffee.com/ripplebiz/path-diagnostics-improvements\" target=\"_blank\" rel=\"noopener noreferrer\">https://buymeacoffee.com/ripplebiz/path-diagnostics-improvements</a></p>\n<hr />\n<p>Six firmware variants, one codebase. Pick the right <code>.bin</code> for your hardware:</p>\n<hr />\n<h2>Firmware Variants</h2>\n<p><strong><code>v0.9.9-Meck-4G-BLE.bin</code></strong>\nFor T-Deck Pro 4G boards. Full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, GPS, map viewer, BLE companion app support, SMS &amp; Phone app, IRC client, and web browser. Up to 500 contacts and 20 channels.</p>\n<blockquote>\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<p><strong><code>v0.9.9W-Meck-4G-WiFi.bin</code></strong>\nFor T-Deck Pro 4G boards. Same as the 4G-BLE build but with WiFi replacing BLE as the companion transport — connect via the MeshCore web app, iOS/Android app, meshcore.js, or Python CLI over your local network (TCP port 5000). WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\n<p>Also available for those with a custom 2000mah battery build.</p>\n<p><strong><code>v0.9.9-4G.SA-Meck-standalone.bin</code></strong>\nFor T-Deck Pro 4G boards. No BLE or WiFi companion — maximum battery life. The web browser, IRC client, and map viewer are all still available (they use WiFi independently, not as a companion transport). Up to 1,500 contacts and 20 channels.</p>\n<p><strong><code>v0.9.9A-Meck-Audio-BLE.bin</code></strong>\nEverything in the 4G-BLE build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. BLE companion support included. Up to 500 contacts and 20 channels.</p>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only. The I2S audio pins (GPIO 7, 8, 9) conflict with the A7682E modem control lines — do not flash on 4G boards.</p>\n</blockquote>\n<blockquote>\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<p><strong><code>v0.9.9AW-Meck-Audio-WiFi.bin</code></strong>\nSame as the Audio-BLE build but with WiFi replacing BLE as the companion transport. WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only — same GPIO conflict applies. Do not flash on 4G boards.</p>\n</blockquote>\n<p><strong><code>v0.9.9A-SA-Meck-standalone.bin</code></strong>\nSame as the Audio-BLE build but with Bluetooth and WiFi completely removed at compile time. The radio hardware is never initialised, giving a significant battery life improvement. The web browser, IRC client, and map viewer are not available on this variant. Up to 1,500 contacts and 20 channels.</p>\n<blockquote>\n<p>Battery life: Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.</p>\n</blockquote>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only — do not flash on 4G boards.</p>\n</blockquote>\n<hr />\n<p>See all the features and updates that are available in Meck from v0.9.8 onwards here: <a href=\"https://github.com/pelgraine/Meck/releases/tag/wifi-1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/pelgraine/Meck/releases/tag/wifi-1</a></p>\n"
        },
        {
          "version": "v0.9.8.1",
          "name": "Meck v0.9.8.1 - bugfixes for v0.9.8",
          "datetime": "2026-03-05T07:50:08Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v0.9.8.1",
          "prerelease": false,
          "notes": "<hr>\r\n<h2>What's New Since v0.9.8</h2>\r\n<p>Bugfixes: Discover nodes is back to working how it should, and repeater admin login fixes have been applied along with improvements on how login timeout responses behave depending on how many hops away the repeater is. Also have now fixed webreaderscreen missing code regression that popped up.</p>\r\n<hr>\r\n<p>Six firmware variants, one codebase. Pick the right <code>.bin</code> for your hardware:</p>\r\n<hr>\r\n<h2>Firmware Variants</h2>\r\n<p><strong><code>v0.9.8.1-Meck-4G-BLE.bin</code></strong>\r\nFor T-Deck Pro 4G boards. Full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, GPS, map viewer, BLE companion app support, SMS &amp; Phone app, IRC client, and web browser. Up to 500 contacts and 20 channels.</p>\r\n<blockquote>\r\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\r\n</blockquote>\r\n<p><strong><code>v0.9.8.1W-Meck-4G-WiFi.bin</code></strong>\r\nFor T-Deck Pro 4G boards. Same as the 4G-BLE build but with WiFi replacing BLE as the companion transport — connect via the MeshCore web app, iOS/Android app, meshcore.js, or Python CLI over your local network (TCP port 5000). WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\r\n<p>Also available for those with a custom 2000mah battery build.</p>\r\n<p><strong><code>v0.9.8.14G.SA-Meck-standalone.bin</code></strong>\r\nFor T-Deck Pro 4G boards. No BLE or WiFi companion — maximum battery life. The web browser, IRC client, and map viewer are all still available (they use WiFi independently, not as a companion transport). Up to 1,500 contacts and 20 channels.</p>\r\n<p><strong><code>v0.9.8.1A-Meck-Audio-BLE.bin</code></strong>\r\nEverything in the 4G-BLE build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. BLE companion support included. Up to 500 contacts and 20 channels.</p>\r\n<blockquote>\r\n<p>⚠️ PCM5102A audio hardware only. The I2S audio pins (GPIO 7, 8, 9) conflict with the A7682E modem control lines — do not flash on 4G boards.</p>\r\n</blockquote>\r\n<blockquote>\r\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\r\n</blockquote>\r\n<p><strong><code>v0.9.8.1AW-Meck-Audio-WiFi.bin</code></strong>\r\nSame as the Audio-BLE build but with WiFi replacing BLE as the companion transport. WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\r\n<blockquote>\r\n<p>⚠️ PCM5102A audio hardware only — same GPIO conflict applies. Do not flash on 4G boards.</p>\r\n</blockquote>\r\n<p><strong><code>v0.9.8.1A-SA-Meck-standalone.bin</code></strong>\r\nSame as the Audio-BLE build but with Bluetooth and WiFi completely removed at compile time. The radio hardware is never initialised, giving a significant battery life improvement. The web browser, IRC client, and map viewer are not available on this variant. Up to 1,500 contacts and 20 channels.</p>\r\n<blockquote>\r\n<p>Battery life: Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.</p>\r\n</blockquote>\r\n<blockquote>\r\n<p>⚠️ PCM5102A audio hardware only — do not flash on 4G boards.</p>\r\n</blockquote>\r\n<hr>\r\nSee all the features and updates available in Meck v0.9.8 here: https://github.com/pelgraine/Meck/releases/tag/wifi-1",
          "notesHtml": "<hr />\n<h2>What's New Since v0.9.8</h2>\n<p>Bugfixes: Discover nodes is back to working how it should, and repeater admin login fixes have been applied along with improvements on how login timeout responses behave depending on how many hops away the repeater is. Also have now fixed webreaderscreen missing code regression that popped up.</p>\n<hr />\n<p>Six firmware variants, one codebase. Pick the right <code>.bin</code> for your hardware:</p>\n<hr />\n<h2>Firmware Variants</h2>\n<p><strong><code>v0.9.8.1-Meck-4G-BLE.bin</code></strong>\nFor T-Deck Pro 4G boards. Full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, GPS, map viewer, BLE companion app support, SMS &amp; Phone app, IRC client, and web browser. Up to 500 contacts and 20 channels.</p>\n<blockquote>\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<p><strong><code>v0.9.8.1W-Meck-4G-WiFi.bin</code></strong>\nFor T-Deck Pro 4G boards. Same as the 4G-BLE build but with WiFi replacing BLE as the companion transport — connect via the MeshCore web app, iOS/Android app, meshcore.js, or Python CLI over your local network (TCP port 5000). WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\n<p>Also available for those with a custom 2000mah battery build.</p>\n<p><strong><code>v0.9.8.14G.SA-Meck-standalone.bin</code></strong>\nFor T-Deck Pro 4G boards. No BLE or WiFi companion — maximum battery life. The web browser, IRC client, and map viewer are all still available (they use WiFi independently, not as a companion transport). Up to 1,500 contacts and 20 channels.</p>\n<p><strong><code>v0.9.8.1A-Meck-Audio-BLE.bin</code></strong>\nEverything in the 4G-BLE build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. BLE companion support included. Up to 500 contacts and 20 channels.</p>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only. The I2S audio pins (GPIO 7, 8, 9) conflict with the A7682E modem control lines — do not flash on 4G boards.</p>\n</blockquote>\n<blockquote>\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<p><strong><code>v0.9.8.1AW-Meck-Audio-WiFi.bin</code></strong>\nSame as the Audio-BLE build but with WiFi replacing BLE as the companion transport. WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only — same GPIO conflict applies. Do not flash on 4G boards.</p>\n</blockquote>\n<p><strong><code>v0.9.8.1A-SA-Meck-standalone.bin</code></strong>\nSame as the Audio-BLE build but with Bluetooth and WiFi completely removed at compile time. The radio hardware is never initialised, giving a significant battery life improvement. The web browser, IRC client, and map viewer are not available on this variant. Up to 1,500 contacts and 20 channels.</p>\n<blockquote>\n<p>Battery life: Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.</p>\n</blockquote>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only — do not flash on 4G boards.</p>\n</blockquote>\n<hr />\nSee all the features and updates available in Meck v0.9.8 here: https://github.com/pelgraine/Meck/releases/tag/wifi-1"
        },
        {
          "version": "wifi-1",
          "name": "Meck v0.9.8 — Maps, WiFi Companion, Serial Config & More",
          "datetime": "2026-03-04T09:20:45Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/wifi-1",
          "prerelease": false,
          "notes": "<p>Six firmware variants, one codebase. Pick the right <code>.bin</code> for your hardware:</p>\r\n<hr>\r\n<h2>Firmware Variants</h2>\r\n<p><strong><code>v0.9.8-Meck-4G-BLE.bin</code></strong>\r\nFor T-Deck Pro 4G boards. Full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, GPS, map viewer, BLE companion app support, SMS &amp; Phone app, IRC client, and web browser. Up to 500 contacts and 20 channels.</p>\r\n<blockquote>\r\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\r\n</blockquote>\r\n<p><strong><code>v0.9.8W-Meck-4G-WiFi.bin</code></strong>\r\nFor T-Deck Pro 4G boards. Same as the 4G-BLE build but with WiFi replacing BLE as the companion transport — connect via the MeshCore web app, iOS/Android app, meshcore.js, or Python CLI over your local network (TCP port 5000). WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\r\n<p><strong><code>v0.9.8.4G.SA-Meck-standalone.bin</code></strong>\r\nFor T-Deck Pro 4G boards. No BLE or WiFi companion — maximum battery life. The web browser, IRC client, and map viewer are all still available (they use WiFi independently, not as a companion transport). Up to 1,500 contacts and 20 channels.</p>\r\n<p><strong><code>v0.9.8A-Meck-Audio-BLE.bin</code></strong>\r\nEverything in the 4G-BLE build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. BLE companion support included. Up to 500 contacts and 20 channels.</p>\r\n<blockquote>\r\n<p>⚠️ PCM5102A audio hardware only. The I2S audio pins (GPIO 7, 8, 9) conflict with the A7682E modem control lines — do not flash on 4G boards.</p>\r\n</blockquote>\r\n<blockquote>\r\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\r\n</blockquote>\r\n<p><strong><code>v0.9.8AW-Meck-Audio-WiFi.bin</code></strong>\r\nSame as the Audio-BLE build but with WiFi replacing BLE as the companion transport. WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\r\n<blockquote>\r\n<p>⚠️ PCM5102A audio hardware only — same GPIO conflict applies. Do not flash on 4G boards.</p>\r\n</blockquote>\r\n<p><strong><code>v0.9.8A-SA-Meck-standalone.bin</code></strong>\r\nSame as the Audio-BLE build but with Bluetooth and WiFi completely removed at compile time. The radio hardware is never initialised, giving a significant battery life improvement. The web browser, IRC client, and map viewer are not available on this variant. Up to 1,500 contacts and 20 channels.</p>\r\n<blockquote>\r\n<p>Battery life: Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.</p>\r\n</blockquote>\r\n<blockquote>\r\n<p>⚠️ PCM5102A audio hardware only — do not flash on 4G boards.</p>\r\n</blockquote>\r\n<hr>\r\n<h2>What's New Since v0.9.5</h2>\r\n<h3>🗺️ GPS Map Viewer (All variants except Audio Standalone)</h3>\r\n<p>Press <strong>G</strong> from the home screen to open the map. Renders standard OSM \"slippy map\" tiles from your SD card at native 240×320 resolution, with a GPS position marker and overlays for all mesh contacts that have GPS coordinates.</p>\r\n\r\nKey | Action\r\n-- | --\r\nW / A / S / D | Pan the map\r\n+ / - | Zoom in / out\r\nG | Re-centre on your GPS position\r\nQ | Back to home screen\r\n\r\n\r\n<hr>\r\n<h3>🔁 Repeater Admin Improvements</h3>\r\n<p>The repeater admin screen has been significantly expanded. Commands are now organised into a category menu, grouping related functions into logical sections rather than a single flat list — making it easier to navigate the full command set without scrolling past irrelevant options.</p>\r\n<p><strong>Telemetry</strong> is now fetched automatically on login — no \n…",
          "notesHtml": "<p>Six firmware variants, one codebase. Pick the right <code>.bin</code> for your hardware:</p>\n<hr />\n<h2>Firmware Variants</h2>\n<p><strong><code>v0.9.8-Meck-4G-BLE.bin</code></strong>\nFor T-Deck Pro 4G boards. Full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, GPS, map viewer, BLE companion app support, SMS &amp; Phone app, IRC client, and web browser. Up to 500 contacts and 20 channels.</p>\n<blockquote>\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<p><strong><code>v0.9.8W-Meck-4G-WiFi.bin</code></strong>\nFor T-Deck Pro 4G boards. Same as the 4G-BLE build but with WiFi replacing BLE as the companion transport — connect via the MeshCore web app, iOS/Android app, meshcore.js, or Python CLI over your local network (TCP port 5000). WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\n<p><strong><code>v0.9.8.4G.SA-Meck-standalone.bin</code></strong>\nFor T-Deck Pro 4G boards. No BLE or WiFi companion — maximum battery life. The web browser, IRC client, and map viewer are all still available (they use WiFi independently, not as a companion transport). Up to 1,500 contacts and 20 channels.</p>\n<p><strong><code>v0.9.8A-Meck-Audio-BLE.bin</code></strong>\nEverything in the 4G-BLE build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. BLE companion support included. Up to 500 contacts and 20 channels.</p>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only. The I2S audio pins (GPIO 7, 8, 9) conflict with the A7682E modem control lines — do not flash on 4G boards.</p>\n</blockquote>\n<blockquote>\n<p>Note: BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<p><strong><code>v0.9.8AW-Meck-Audio-WiFi.bin</code></strong>\nSame as the Audio-BLE build but with WiFi replacing BLE as the companion transport. WiFi is on by default at boot but can be toggled off in Settings to save power. No BLE companion app support. Up to <strong>1,500 contacts</strong> and 20 channels.</p>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only — same GPIO conflict applies. Do not flash on 4G boards.</p>\n</blockquote>\n<p><strong><code>v0.9.8A-SA-Meck-standalone.bin</code></strong>\nSame as the Audio-BLE build but with Bluetooth and WiFi completely removed at compile time. The radio hardware is never initialised, giving a significant battery life improvement. The web browser, IRC client, and map viewer are not available on this variant. Up to 1,500 contacts and 20 channels.</p>\n<blockquote>\n<p>Battery life: Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.</p>\n</blockquote>\n<blockquote>\n<p>⚠️ PCM5102A audio hardware only — do not flash on 4G boards.</p>\n</blockquote>\n<hr />\n<h2>What's New Since v0.9.5</h2>\n<h3>🗺️ GPS Map Viewer (All variants except Audio Standalone)</h3>\n<p>Press <strong>G</strong> from the home screen to open the map. Renders standard OSM \"slippy map\" tiles from your SD card at native 240×320 resolution, with a GPS position marker and overlays for all mesh contacts that have GPS coordinates.</p><table>\n<thead>\n<tr>\n<th>Key</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>W / A / S / D</td>\n<td>Pan the map</td>\n</tr>\n</tbody></table>\n<ul>\n<li>/ - | Zoom in / out\nG | Re-centre on your GPS position\nQ | Back to home screen</li>\n</ul>\n<hr />\n<h3>🔁 Repeater Admin Improvements</h3>\n<p>The repeater admin screen has been significantly expanded. Commands are now organised into a category menu, grouping related functions into logical sections rather than a single flat list — making it easier to navigate the full command set without scrolling past irrelevant options.</p>\n<p><strong>Telemetry</strong> is now fetched automatically on login — no \n…</p>"
        },
        {
          "version": "v0.9.5",
          "name": "Meck v0.9.5 — Phone App Overhaul, IRC, Web Browser & More",
          "datetime": "2026-02-27T09:09:11Z",
          "url": "https://github.com/pelgraine/Meck/releases/tag/v0.9.5",
          "prerelease": false,
          "notes": "Four firmware variants, one codebase. Pick the right `.bin` for your hardware:\r\n\r\n## Firmware Variants\r\n\r\n### v0.9.5-Meck-4G-BLE.bin\r\n\r\n**For T-Deck Pro 4G boards.** The full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, basic GPS, BLE companion app support, SMS & Phone app, and the **new IRC client, web browser, and DuckDuckGo search**. Limited to max 500 contacts and 20 channels.\r\n\r\n> **Note:** BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.\r\n\r\n### v0.9.5-4GSA-Meck-4G (1400mAh stock battery).bin\r\n\r\n**For T-Deck Pro 4G boards with the stock 1400mAh battery.** Same features as the 4G-BLE build but with Bluetooth removed at compile time — no BLE companion app support, but WiFi and the web browser/IRC remain available. Battery gauge calibrated for the stock 1400mAh cell. Limited to max 1500 contacts and 20 channels.\r\n\r\n### v0.9.5-4GSA-Meck-4G (2000mAh battery).bin\r\n\r\n**For T-Deck Pro 4G boards with an upgraded 2000mAh battery and custom case.** Identical to the 4G standalone variant above, but with the battery gauge calibrated for a 2000mAh cell. Limited to max 1500 contacts and 20 channels.\r\n\r\n### v0.9.5A-Meck-Audio-BLE (PCM5102A Audio only).bin\r\n\r\nEverything in the standard build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. Includes the new web browser, DuckDuckGo search, and IRC client over WiFi. Limited to max 500 contacts and 20 channels.\r\n\r\n> **⚠️ Do not flash this on the 4G variant** — the I2S audio pins (GPIO 7, 8, 9) conflict with the modem control lines. This firmware is only for T-Deck Pro boards with the PCM5102A DAC.\r\n\r\n> **Note:** BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.\r\n\r\n### v0.9.5A-SA-Meck-standalone-firmware (PCM5102A Audio only).bin\r\n\r\nSame as the Audio+BLE build but with Bluetooth and WiFi completely removed at compile time. The BLE/WiFi radio hardware is never initialised, giving a significant battery life improvement. The web browser and IRC client are not available on this variant. Limited to max 1500 contacts and 20 channels.\r\n\r\n> **Battery life:** Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.\r\n\r\n> **⚠️ PCM5102A audio hardware only** — same GPIO conflict applies as the Audio+BLE variant. Do not flash on 4G boards.\r\n\r\n---\r\n\r\n## What's New Since v0.9.3\r\n\r\n### 📱 Phone App Overhaul (4G variant only)\r\n\r\nThe Phone app has been redesigned with a new dedicated screen giving you the choice of making phone calls to non-contacts or jumping straight into the SMS inbox where you can also call saved contacts.\r\n\r\n* **New phone dialpad** with three text entry methods:\r\n  - **Direct key press** — press the keyboard letter mapped to each number (W for 1, E for 2, etc.)\r\n  - **Touchscreen tap** — tap the on-screen number buttons directly (note: requires fairly precise taps on the numbers themselves)\r\n  - **Sym+key** — the classic method from previous versions\r\n* **IMEI, carrier, and APN details** now displayed at the bottom of the Settings menu alongside your node ID and firmware version\r\n* **Favourites filter** added to the mesh Contacts screen\r\n* **Fixed regression** with dropped in-call screen\r\n* **Fixed 0 key recognition** on the dialpad\r\n\r\n### 🌐 Web Browser & Search (BLE and 4G variants)\r\n\r\nA brand-new set of connectivity features available on the 4G-BLE, 4G standalone, and Audio-BLE variants (not the standalone audio variant, which excludes WiFi to preserve lowest-battery-usage design):\r\n\r\n* **DuckDuckGo Lite search** — very basic web search directly from the device\r\n* **HTML web reader browser** — a text-centric web browser, still very much in development but already useful for reading text-heavy websites\r\n* **EPUB download support** — follow a link to an `.epub` file\n…",
          "notesHtml": "<p>Four firmware variants, one codebase. Pick the right <code>.bin</code> for your hardware:</p>\n<h2>Firmware Variants</h2>\n<h3>v0.9.5-Meck-4G-BLE.bin</h3>\n<p><strong>For T-Deck Pro 4G boards.</strong> The full-featured build — messaging, contacts, direct messages, repeater admin, e-book reader, notes, emoji, basic GPS, BLE companion app support, SMS &amp; Phone app, and the <strong>new IRC client, web browser, and DuckDuckGo search</strong>. Limited to max 500 contacts and 20 channels.</p>\n<blockquote>\n<p><strong>Note:</strong> BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<h3>v0.9.5-4GSA-Meck-4G (1400mAh stock battery).bin</h3>\n<p><strong>For T-Deck Pro 4G boards with the stock 1400mAh battery.</strong> Same features as the 4G-BLE build but with Bluetooth removed at compile time — no BLE companion app support, but WiFi and the web browser/IRC remain available. Battery gauge calibrated for the stock 1400mAh cell. Limited to max 1500 contacts and 20 channels.</p>\n<h3>v0.9.5-4GSA-Meck-4G (2000mAh battery).bin</h3>\n<p><strong>For T-Deck Pro 4G boards with an upgraded 2000mAh battery and custom case.</strong> Identical to the 4G standalone variant above, but with the battery gauge calibrated for a 2000mAh cell. Limited to max 1500 contacts and 20 channels.</p>\n<h3>v0.9.5A-Meck-Audio-BLE (PCM5102A Audio only).bin</h3>\n<p>Everything in the standard build plus the audiobook player, sleep timer, and auto-queuing — minus the 4G modem features. Includes the new web browser, DuckDuckGo search, and IRC client over WiFi. Limited to max 500 contacts and 20 channels.</p>\n<blockquote>\n<p><strong>⚠️ Do not flash this on the 4G variant</strong> — the I2S audio pins (GPIO 7, 8, 9) conflict with the modem control lines. This firmware is only for T-Deck Pro boards with the PCM5102A DAC.</p>\n</blockquote>\n<blockquote>\n<p><strong>Note:</strong> BLE is toggled off at boot to save battery. Navigate to the Bluetooth home page and press Enter to enable it when you want to connect to the app.</p>\n</blockquote>\n<h3>v0.9.5A-SA-Meck-standalone-firmware (PCM5102A Audio only).bin</h3>\n<p>Same as the Audio+BLE build but with Bluetooth and WiFi completely removed at compile time. The BLE/WiFi radio hardware is never initialised, giving a significant battery life improvement. The web browser and IRC client are not available on this variant. Limited to max 1500 contacts and 20 channels.</p>\n<blockquote>\n<p><strong>Battery life:</strong> Disabling Bluetooth extends estimated runtime from ~10.5 hours to ~20.5 hours on the 1400mAh cell.</p>\n</blockquote>\n<blockquote>\n<p><strong>⚠️ PCM5102A audio hardware only</strong> — same GPIO conflict applies as the Audio+BLE variant. Do not flash on 4G boards.</p>\n</blockquote>\n<hr />\n<h2>What's New Since v0.9.3</h2>\n<h3>📱 Phone App Overhaul (4G variant only)</h3>\n<p>The Phone app has been redesigned with a new dedicated screen giving you the choice of making phone calls to non-contacts or jumping straight into the SMS inbox where you can also call saved contacts.</p>\n<ul>\n<li><strong>New phone dialpad</strong> with three text entry methods:<ul>\n<li><strong>Direct key press</strong> — press the keyboard letter mapped to each number (W for 1, E for 2, etc.)</li>\n<li><strong>Touchscreen tap</strong> — tap the on-screen number buttons directly (note: requires fairly precise taps on the numbers themselves)</li>\n<li><strong>Sym+key</strong> — the classic method from previous versions</li>\n</ul>\n</li>\n<li><strong>IMEI, carrier, and APN details</strong> now displayed at the bottom of the Settings menu alongside your node ID and firmware version</li>\n<li><strong>Favourites filter</strong> added to the mesh Contacts screen</li>\n<li><strong>Fixed regression</strong> with dropped in-call screen</li>\n<li><strong>Fixed 0 key recognition</strong> on the dialpad</li>\n</ul>\n<h3>🌐 Web Browser &amp; Search (BLE and 4G variants)</h3>\n<p>A brand-new set of connectivity features available on the 4G-BLE, 4G standalone, and Audio-BLE variants (not the standalone audio variant, which excludes WiFi to preserve lowest-battery-usage design):</p>\n<ul>\n<li><strong>DuckDuckGo Lite search</strong> — very basic web search directly from the device</li>\n<li><strong>HTML web reader browser</strong> — a text-centric web browser, still very much in development but already useful for reading text-heavy websites</li>\n<li><strong>EPUB download support</strong> — follow a link to an <code>.epub</code> file\n…</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:31.295Z"
    },
    {
      "id": "meck-p4",
      "name": "Meck-P4",
      "type": "fork",
      "maintainer": "pelgraine",
      "description": "A port of Meck (a MeshCore fork) to the LilyGo T-Display P4, targeting the ESP32-P4 main MCU. The onboard ESP32-C6 provides WiFi companion connectivity to the MeshCore app; BLE is not yet enabled. Features a full touch UI with virtual keyboard, channel messaging, repeater admin, trace route, position adverts, and private channels.\n",
      "repository": "https://github.com/pelgraine/Meck-P4",
      "license": "GPL-3.0",
      "status": "active",
      "lifecycle": "active",
      "maturity": "alpha",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "features": [
        "ESP32-P4 main MCU with ESP32-C6 WiFi companion",
        "Touch UI with virtual keyboard",
        "Screen-off power saving",
        "Channel messaging and direct messages",
        "Repeater admin and room server",
        "Trace route and path view",
        "Position adverts and share position",
        "Private channels",
        "Per-contact path editor",
        "Region scope"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": false,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": false,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-tdisplay-p4",
          "status": "supported"
        }
      ],
      "popularity": {
        "githubStars": 9,
        "githubForks": 1,
        "githubWatchers": 1,
        "githubOpenIssues": 0,
        "githubContributors": 2,
        "releaseDownloads": 111,
        "latestReleaseDownloads": 17,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": false,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "0.6.2-patch",
      "released": "2026-06-14",
      "releases": [
        {
          "version": "v0.6.2-patch",
          "name": "Meck P4 v0.6.2 Pre-release (Patch): Trace and notification fixes",
          "datetime": "2026-06-14T19:48:10Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.6.2-patch",
          "prerelease": true,
          "notes": "# Meck P4 v0.6.2 Pre-release (Patch): Trace and notification fixes\r\n\r\nPoint release on top of [[v0.6.1](https://github.com/pelgraine/Meck-P4/releases/tag/v0.6.1-patch)](https://github.com/pelgraine/Meck-P4/releases/tag/v0.6.1-patch). Two bug fixes, no new features. Firmware identity is now 0.6.2.\r\n\r\n## Bug Fixes\r\n\r\n### Multi-byte trace path parsed as single-byte\r\n\r\nRunning a path trace in **2-byte mode** returned a wrong result. The response was parsed as if it were 1-byte, so it reported twice as many hops as actually existed, each one resolved to the wrong repeater. As an example, a two-hop 2-byte trace of `3601,2198` came back as four hops (`36`, `01`, `21`, `98`) matched against unrelated repeaters.\r\n\r\nThe cause was in the trace-response handler: the hop count and hash size were taken from the wrong source. The byte length handed up from the base layer was being read with the packet-header path encoding, which collapses to 1-byte mode for any short path. The real hash size is carried separately in the trace flags.\r\n\r\nThe handler now reads the hash size from the trace flags and computes the hop count as the path byte length divided by bytes-per-hop. 1-byte traces were already correct and are unchanged. 2-byte traces now report the right hop count and resolve to the correct repeaters.\r\n\r\n### Custom notification sounds not playing\r\n\r\nCustom per-channel notification tones stopped playing as of v0.6 (they worked in v0.5). A tone could be selected and would show as set, but nothing played when a message arrived on that channel.\r\n\r\nThe cause was the v0.6 audio rework, which split file preparation from playback start. The notification trigger prepared the tone file but never issued the start, so it sat ready and silent.\r\n\r\nThe notification path now starts playback after preparing. The same missing start also affected the tone-picker preview and voice-message playback, both fixed by the same change.\r\n\r\n## Files Changed\r\n\r\n3 files changed (`MeckMesh.h`, `MeckUI.cpp`, `meck.h`).\r\n\r\n## First-Time Flashing: Read This First\r\n\r\nMeck-P4 ships as a single **merged binary** (bootloader + partition table + application combined). One file, flash at offset `0x0`.\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting, channel message, DM, room post, and note is mirrored or stored on the card, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot, and the Reader, Notes, and notification sounds have no storage.\r\n\r\nEnsure you use the **right-side USB-C port** (the data port), not the high-speed charger port, to flash.\r\n<img width=\"377\" height=\"284\" alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/d3db41b5-0a93-47fb-9edc-c3271d7ac6af\" />\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to <https://flasher.meshcore.io/>\r\n2. Scroll to the bottom and select **Custom Firmware**\r\n3. Select the `meck-p4-0.6.2.bin` file you downloaded\r\n4. Click OK on the merged-binary warning\r\n5. Click **Flash**, pick your device in the popup, and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\npip install esptool\r\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.6.2.bin\r\n```\r\n\r\n(Replace `PORT` with `/dev/cu.usbmodemXXXX` on macOS, `/dev/ttyACM0` on Linux, or `COM3` on Windows.)\r\n\r\nUpgrading from v0.6.1 or v0.6 does not require `erase_flash`. This patch changes program logic only and adds no new settings, so existing prefs carry over unchanged.\r\n\r\n---\r\n\r\nFor the full feature list see the [[README](https://github.com/pelgraine/Meck-P4/blob/main/README.md)](https://github.com/pelgraine/Meck-P4/blob/main/README.md).\r\n\r\n## Reporting Issues\r\n\r\nThe Meck-P4 channel on the MeshCore Discord is the fastest path. GitHub Issues on the Meck-P4 repo also work for anything reproducible. Include the serial log if you can: Settings > Debug Logs > Start capt\n…",
          "notesHtml": "<h1>Meck P4 v0.6.2 Pre-release (Patch): Trace and notification fixes</h1>\n<p>Point release on top of <a href=\"https://github.com/pelgraine/Meck-P4/releases/tag/v0.6.1-patch\" target=\"_blank\" rel=\"noopener noreferrer\"><a href=\"https://github.com/pelgraine/Meck-P4/releases/tag/v0.6.1-patch\" target=\"_blank\" rel=\"noopener noreferrer\">v0.6.1</a></a>. Two bug fixes, no new features. Firmware identity is now 0.6.2.</p>\n<h2>Bug Fixes</h2>\n<h3>Multi-byte trace path parsed as single-byte</h3>\n<p>Running a path trace in <strong>2-byte mode</strong> returned a wrong result. The response was parsed as if it were 1-byte, so it reported twice as many hops as actually existed, each one resolved to the wrong repeater. As an example, a two-hop 2-byte trace of <code>3601,2198</code> came back as four hops (<code>36</code>, <code>01</code>, <code>21</code>, <code>98</code>) matched against unrelated repeaters.</p>\n<p>The cause was in the trace-response handler: the hop count and hash size were taken from the wrong source. The byte length handed up from the base layer was being read with the packet-header path encoding, which collapses to 1-byte mode for any short path. The real hash size is carried separately in the trace flags.</p>\n<p>The handler now reads the hash size from the trace flags and computes the hop count as the path byte length divided by bytes-per-hop. 1-byte traces were already correct and are unchanged. 2-byte traces now report the right hop count and resolve to the correct repeaters.</p>\n<h3>Custom notification sounds not playing</h3>\n<p>Custom per-channel notification tones stopped playing as of v0.6 (they worked in v0.5). A tone could be selected and would show as set, but nothing played when a message arrived on that channel.</p>\n<p>The cause was the v0.6 audio rework, which split file preparation from playback start. The notification trigger prepared the tone file but never issued the start, so it sat ready and silent.</p>\n<p>The notification path now starts playback after preparing. The same missing start also affected the tone-picker preview and voice-message playback, both fixed by the same change.</p>\n<h2>Files Changed</h2>\n<p>3 files changed (<code>MeckMesh.h</code>, <code>MeckUI.cpp</code>, <code>meck.h</code>).</p>\n<h2>First-Time Flashing: Read This First</h2>\n<p>Meck-P4 ships as a single <strong>merged binary</strong> (bootloader + partition table + application combined). One file, flash at offset <code>0x0</code>.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting, channel message, DM, room post, and note is mirrored or stored on the card, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot, and the Reader, Notes, and notification sounds have no storage.</p>\n</blockquote>\n<p>Ensure you use the <strong>right-side USB-C port</strong> (the data port), not the high-speed charger port, to flash.\n<img alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/d3db41b5-0a93-47fb-9edc-c3271d7ac6af\" /></p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n<li>Scroll to the bottom and select <strong>Custom Firmware</strong></li>\n<li>Select the <code>meck-p4-0.6.2.bin</code> file you downloaded</li>\n<li>Click OK on the merged-binary warning</li>\n<li>Click <strong>Flash</strong>, pick your device in the popup, and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>pip install esptool\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.6.2.bin\n</code></pre>\n<p>(Replace <code>PORT</code> with <code>/dev/cu.usbmodemXXXX</code> on macOS, <code>/dev/ttyACM0</code> on Linux, or <code>COM3</code> on Windows.)</p>\n<p>Upgrading from v0.6.1 or v0.6 does not require <code>erase_flash</code>. This patch changes program logic only and adds no new settings, so existing prefs carry over unchanged.</p>\n<hr />\n<p>For the full feature list see the <a href=\"https://github.com/pelgraine/Meck-P4/blob/main/README.md\" target=\"_blank\" rel=\"noopener noreferrer\"><a href=\"https://github.com/pelgraine/Meck-P4/blob/main/README.md\" target=\"_blank\" rel=\"noopener noreferrer\">README</a></a>.</p>\n<h2>Reporting Issues</h2>\n<p>The Meck-P4 channel on the MeshCore Discord is the fastest path. GitHub Issues on the Meck-P4 repo also work for anything reproducible. Include the serial log if you can: Settings &gt; Debug Logs &gt; Start capt\n…</p>\n"
        },
        {
          "version": "v0.6.1-patch",
          "name": "Meck P4 v0.6.1 Pre-release (Patch): Antenna switch",
          "datetime": "2026-06-10T03:42:22Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.6.1-patch",
          "prerelease": true,
          "notes": "Point release on top of [v0.6](https://github.com/pelgraine/Meck-P4/releases/tag/v0.6), adding a software LoRa antenna selector in Settings. No other functional changes. Firmware identity is now 0.6.1.\r\n\r\n## Antenna Switch\r\n\r\nA new **Antenna (tap to toggle)** row at the top of **Settings**, switching the SX1262 between the two ports on the SKY13453 RF switch (XL9535 IO1 / VCTL).\r\n\r\n- **Internal (RF1)** is the default and corresponds to VCTL HIGH; **External (RF2)** is VCTL LOW. The internal antenna is the one in use when no external antenna is attached, so the device works out of the box without changing this.\r\n- The choice persists via prefs (NVS, mirrored to SD) and is re-applied at boot, so the selected port survives a reboot.\r\n- Tap applies live: the pin is driven immediately and the row label updates to show the active port.\r\n\r\n## Bug Fixes\r\n\r\nNone.\r\n\r\n## Files Changed\r\n\r\n5 files changed.\r\n\r\n## First-Time Flashing: Read This First\r\n\r\nMeck-P4 ships as a single **merged binary** (bootloader + partition table + application combined). One file, flash at offset `0x0`.\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting, channel message, DM, room post, and note is mirrored or stored on the card, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot, and the Reader, Notes, and notification sounds have no storage.\r\n\r\nEnsure you use the **right-side USB-C port** (the data port), not the high-speed charger port, to flash.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to <https://flasher.meshcore.io/>\r\n2. Scroll to the bottom and select **Custom Firmware**\r\n3. Select the `meck-p4-0.6.1.bin` file you downloaded\r\n4. Click OK on the merged-binary warning\r\n5. Click **Flash**, pick your device in the popup, and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\npip install esptool\r\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.6.1.bin\r\n```\r\n\r\n(Replace `PORT` with `/dev/cu.usbmodemXXXX` on macOS, `/dev/ttyACM0` on Linux, or `COM3` on Windows.)\r\n\r\nUpgrading from v0.6 does not require `erase_flash`. The prefs loader tolerates the older layout, and the new antenna field comes up at its default (Internal).\r\n\r\n---\r\n\r\nFor the full feature list see the [[README](https://github.com/pelgraine/Meck-P4/blob/main/README.md)](https://github.com/pelgraine/Meck-P4/blob/main/README.md).\r\n\r\n## Reporting Issues\r\n\r\nThe Meck-P4 channel on the MeshCore Discord is the fastest path. GitHub Issues on the Meck-P4 repo also work for anything reproducible. Include the serial log if you can: Settings > Debug Logs > Start captures it to SD if a serial monitor isn't practical.\r\n\r\n## License\r\n\r\nMIT for Meck-specific code. The combined firmware binary links libraries with mixed licensing including GPL-3.0 and LGPL-2.1 (Codec2) and is effectively GPL-3.0 when distributed.",
          "notesHtml": "<p>Point release on top of <a href=\"https://github.com/pelgraine/Meck-P4/releases/tag/v0.6\" target=\"_blank\" rel=\"noopener noreferrer\">v0.6</a>, adding a software LoRa antenna selector in Settings. No other functional changes. Firmware identity is now 0.6.1.</p>\n<h2>Antenna Switch</h2>\n<p>A new <strong>Antenna (tap to toggle)</strong> row at the top of <strong>Settings</strong>, switching the SX1262 between the two ports on the SKY13453 RF switch (XL9535 IO1 / VCTL).</p>\n<ul>\n<li><strong>Internal (RF1)</strong> is the default and corresponds to VCTL HIGH; <strong>External (RF2)</strong> is VCTL LOW. The internal antenna is the one in use when no external antenna is attached, so the device works out of the box without changing this.</li>\n<li>The choice persists via prefs (NVS, mirrored to SD) and is re-applied at boot, so the selected port survives a reboot.</li>\n<li>Tap applies live: the pin is driven immediately and the row label updates to show the active port.</li>\n</ul>\n<h2>Bug Fixes</h2>\n<p>None.</p>\n<h2>Files Changed</h2>\n<p>5 files changed.</p>\n<h2>First-Time Flashing: Read This First</h2>\n<p>Meck-P4 ships as a single <strong>merged binary</strong> (bootloader + partition table + application combined). One file, flash at offset <code>0x0</code>.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting, channel message, DM, room post, and note is mirrored or stored on the card, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot, and the Reader, Notes, and notification sounds have no storage.</p>\n</blockquote>\n<p>Ensure you use the <strong>right-side USB-C port</strong> (the data port), not the high-speed charger port, to flash.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n<li>Scroll to the bottom and select <strong>Custom Firmware</strong></li>\n<li>Select the <code>meck-p4-0.6.1.bin</code> file you downloaded</li>\n<li>Click OK on the merged-binary warning</li>\n<li>Click <strong>Flash</strong>, pick your device in the popup, and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>pip install esptool\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.6.1.bin\n</code></pre>\n<p>(Replace <code>PORT</code> with <code>/dev/cu.usbmodemXXXX</code> on macOS, <code>/dev/ttyACM0</code> on Linux, or <code>COM3</code> on Windows.)</p>\n<p>Upgrading from v0.6 does not require <code>erase_flash</code>. The prefs loader tolerates the older layout, and the new antenna field comes up at its default (Internal).</p>\n<hr />\n<p>For the full feature list see the <a href=\"https://github.com/pelgraine/Meck-P4/blob/main/README.md\" target=\"_blank\" rel=\"noopener noreferrer\"><a href=\"https://github.com/pelgraine/Meck-P4/blob/main/README.md\" target=\"_blank\" rel=\"noopener noreferrer\">README</a></a>.</p>\n<h2>Reporting Issues</h2>\n<p>The Meck-P4 channel on the MeshCore Discord is the fastest path. GitHub Issues on the Meck-P4 repo also work for anything reproducible. Include the serial log if you can: Settings &gt; Debug Logs &gt; Start captures it to SD if a serial monitor isn't practical.</p>\n<h2>License</h2>\n<p>MIT for Meck-specific code. The combined firmware binary links libraries with mixed licensing including GPL-3.0 and LGPL-2.1 (Codec2) and is effectively GPL-3.0 when distributed.</p>\n"
        },
        {
          "version": "v0.6",
          "name": "Meck P4 v0.6 Pre-release: Web reader, Notes, and EPUB books",
          "datetime": "2026-06-09T22:14:40Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.6",
          "prerelease": true,
          "notes": "Feature release building on v0.5, adding a reader-mode web browser over the ESP32-C6, a Notes app, EPUB book support in the reader, a Cyrillic keyboard layout, optional M5Stack CardKB hardware-keyboard support, and a portrait/landscape orientation toggle, alongside several bug fixes. Firmware identity is now 0.6.\r\n\r\n## Web Reader\r\n\r\nA lightweight reader-mode web browser on the new **Web** home tile, running over the onboard ESP32-C6. It drives the C6 directly over ESP-AT, building its HTTP and TLS requests by hand, so it shares the WiFi companion's C6 link but uses its own request path. The C6 must be connected to WiFi for it to fetch anything.\r\n\r\n- Landing menu with **Enter URL**, a **DuckDuckGo Lite** search, **Bookmarks**, and **History**.\r\n- Reader view: pages are parsed to readable text with a status line. Headings render in dark red; link markers show as a muted grey `[N]` and are followed from the **Links** panel.\r\n- HTTPS support, confirmed against DuckDuckGo Lite.\r\n- GET form fill: an orange **Forms (N)** button opens a picker (duplicate forms collapsed), then a fill modal with a labelled field per text or password input. Submitting builds the `action?name=value&...` query and loads it through the normal page path, so history and status stay correct.\r\n- Bookmarks (added from the reader view with a confirmation toast) and History.\r\n- This is a **work in progress**: an amber notice appears for a few seconds each time the Web tile is opened. See Known Limitations below and the README for the full list.\r\n\r\n## EPUB Reading\r\n\r\nThe reader now opens **EPUB (`.epub`)** files in addition to plain text. The file list shows folders, `.txt`, and `.epub` items.\r\n\r\n- Tapping an EPUB converts it to plain text the first time it is opened. A *Converting ... to txt* screen is shown while the book is decoded.\r\n- The result is cached as a `.txt` in a hidden `.epub_cache` subfolder, so re-opening the same EPUB later loads straight from the cache and the conversion only runs once.\r\n- You only ever see and tap the `.epub` itself; the cached text stays hidden from the browser.\r\n\r\n## Notes\r\n\r\nA Notes app on the **Notes** home tile. Notes are plain UTF-8 `.txt` files stored under `/sdcard/notes`, so they live on the removable card, survive a reflash, and can be read or edited on a computer. The folder is created automatically on first run.\r\n\r\n- Browser modelled on the reader's: folder navigation, an up-one-level button, and a breadcrumb, rooted at `/sdcard/notes`. A green **+ New Note** row sits at the top of every folder.\r\n- Create and edit with the on-screen keyboard (which honours the KB Theme and KB Layout settings). New notes are named by date and time when the clock is synced (`note_YYYYMMDD_HHMM.txt`), or sequentially (`note_NNN.txt`) otherwise.\r\n- Read view reuses the reader's paging: left third of the screen turns back, right two-thirds turns forward, with a progress percentage and a saved-position bookmark.\r\n- Long-press a note for an action menu with **Rename**, **Delete** (with confirmation), and **Cancel**.\r\n\r\n## Cyrillic Keyboard\r\n\r\nA fourth on-screen keyboard layout, **ЙЦУКЕН** (Cyrillic), added to the **Settings > KB Layout** cycle alongside QWERTY, AZERTY, and QWERTZ.\r\n\r\n- Standard Russian arrangement, also commonly used by Bulgarian users. The top three rows carry twelve letters each, with ё on the third row.\r\n- The control keys keep their Latin labels (ABC / abc / 1#) so case and number switching still work.\r\n- Ukrainian and Serbian letter sets are not included. The Settings row shows \"ЙЦУКЕН\" when this layout is active.\r\n\r\n## Physical Keyboard (M5Stack CardKB)\r\n\r\nOptional support for the **M5Stack CardKB**, a small I2C QWERTY keyboard, as an alternative to the on-screen keyboard for typing messages. Gated behind the `MECK_CARDKB` build flag (a build-from-source option).\r\n\r\n- Connects to the board's **P1 connector** (the 1x4 header) as a software-I2C bus on SDA = GPIO 48 and SCL = GPIO 47, at 10 kHz, address 0x5F. Probed for \n…",
          "notesHtml": "<p>Feature release building on v0.5, adding a reader-mode web browser over the ESP32-C6, a Notes app, EPUB book support in the reader, a Cyrillic keyboard layout, optional M5Stack CardKB hardware-keyboard support, and a portrait/landscape orientation toggle, alongside several bug fixes. Firmware identity is now 0.6.</p>\n<h2>Web Reader</h2>\n<p>A lightweight reader-mode web browser on the new <strong>Web</strong> home tile, running over the onboard ESP32-C6. It drives the C6 directly over ESP-AT, building its HTTP and TLS requests by hand, so it shares the WiFi companion's C6 link but uses its own request path. The C6 must be connected to WiFi for it to fetch anything.</p>\n<ul>\n<li>Landing menu with <strong>Enter URL</strong>, a <strong>DuckDuckGo Lite</strong> search, <strong>Bookmarks</strong>, and <strong>History</strong>.</li>\n<li>Reader view: pages are parsed to readable text with a status line. Headings render in dark red; link markers show as a muted grey <code>[N]</code> and are followed from the <strong>Links</strong> panel.</li>\n<li>HTTPS support, confirmed against DuckDuckGo Lite.</li>\n<li>GET form fill: an orange <strong>Forms (N)</strong> button opens a picker (duplicate forms collapsed), then a fill modal with a labelled field per text or password input. Submitting builds the <code>action?name=value&amp;...</code> query and loads it through the normal page path, so history and status stay correct.</li>\n<li>Bookmarks (added from the reader view with a confirmation toast) and History.</li>\n<li>This is a <strong>work in progress</strong>: an amber notice appears for a few seconds each time the Web tile is opened. See Known Limitations below and the README for the full list.</li>\n</ul>\n<h2>EPUB Reading</h2>\n<p>The reader now opens <strong>EPUB (<code>.epub</code>)</strong> files in addition to plain text. The file list shows folders, <code>.txt</code>, and <code>.epub</code> items.</p>\n<ul>\n<li>Tapping an EPUB converts it to plain text the first time it is opened. A <em>Converting ... to txt</em> screen is shown while the book is decoded.</li>\n<li>The result is cached as a <code>.txt</code> in a hidden <code>.epub_cache</code> subfolder, so re-opening the same EPUB later loads straight from the cache and the conversion only runs once.</li>\n<li>You only ever see and tap the <code>.epub</code> itself; the cached text stays hidden from the browser.</li>\n</ul>\n<h2>Notes</h2>\n<p>A Notes app on the <strong>Notes</strong> home tile. Notes are plain UTF-8 <code>.txt</code> files stored under <code>/sdcard/notes</code>, so they live on the removable card, survive a reflash, and can be read or edited on a computer. The folder is created automatically on first run.</p>\n<ul>\n<li>Browser modelled on the reader's: folder navigation, an up-one-level button, and a breadcrumb, rooted at <code>/sdcard/notes</code>. A green <strong>+ New Note</strong> row sits at the top of every folder.</li>\n<li>Create and edit with the on-screen keyboard (which honours the KB Theme and KB Layout settings). New notes are named by date and time when the clock is synced (<code>note_YYYYMMDD_HHMM.txt</code>), or sequentially (<code>note_NNN.txt</code>) otherwise.</li>\n<li>Read view reuses the reader's paging: left third of the screen turns back, right two-thirds turns forward, with a progress percentage and a saved-position bookmark.</li>\n<li>Long-press a note for an action menu with <strong>Rename</strong>, <strong>Delete</strong> (with confirmation), and <strong>Cancel</strong>.</li>\n</ul>\n<h2>Cyrillic Keyboard</h2>\n<p>A fourth on-screen keyboard layout, <strong>ЙЦУКЕН</strong> (Cyrillic), added to the <strong>Settings &gt; KB Layout</strong> cycle alongside QWERTY, AZERTY, and QWERTZ.</p>\n<ul>\n<li>Standard Russian arrangement, also commonly used by Bulgarian users. The top three rows carry twelve letters each, with ё on the third row.</li>\n<li>The control keys keep their Latin labels (ABC / abc / 1#) so case and number switching still work.</li>\n<li>Ukrainian and Serbian letter sets are not included. The Settings row shows \"ЙЦУКЕН\" when this layout is active.</li>\n</ul>\n<h2>Physical Keyboard (M5Stack CardKB)</h2>\n<p>Optional support for the <strong>M5Stack CardKB</strong>, a small I2C QWERTY keyboard, as an alternative to the on-screen keyboard for typing messages. Gated behind the <code>MECK_CARDKB</code> build flag (a build-from-source option).</p>\n<ul>\n<li>Connects to the board's <strong>P1 connector</strong> (the 1x4 header) as a software-I2C bus on SDA = GPIO 48 and SCL = GPIO 47, at 10 kHz, address 0x5F. Probed for \n…</li>\n</ul>\n"
        },
        {
          "version": "v0.5",
          "name": "Meck P4 v0.5 Pre-release: Text reader, inline emoji, and repeater admin",
          "datetime": "2026-05-29T09:24:01Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.5",
          "prerelease": true,
          "notes": "Feature release building on v0.4, adding a plain-text reader, inline colour emoji with a picker, over-the-mesh repeater administration from the companion app, audio player fixes, and draft message saving. Firmware identity is now 0.5.\r\n\r\n## Text Reader\r\n\r\n- New plain-text (.txt) reader, opened from the home grid's Reader tile. Folder browser rooted at `/sdcard/books` with subfolder navigation, a breadcrumb, and an up-one-level button.\r\n- Windowed, page-at-a-time rendering: the reader never loads the whole book, so memory and layout cost stay fixed to one screen regardless of file size. LVGL's own layout finds each page boundary at a clean line break.\r\n- Per-book resume across reboots via a `.pos` sidecar, plus page-back through the pages visited in the current session.\r\n- Percentage progress through the file.\r\n- Reading-view taps: the left third turns back a page, the right two-thirds turns forward. Back returns to the browser; the browser's Back goes up a folder, or home at the `/sdcard/books` root.\r\n- Honours the Settings font-size preference.\r\n\r\n## Inline Emoji\r\n\r\n\r\n<img width=\"270\" height=\"550\" alt=\"IMG_3256\" src=\"https://github.com/user-attachments/assets/0f1d6060-ec01-4973-bad8-0f28f027e80a\" />\r\n<img width=\"270\" height=\"550\" alt=\"IMG_3255\" src=\"https://github.com/user-attachments/assets/b62b299d-8f70-4d18-b8e4-4887b4c5efae\" />\r\n\r\n- Inline colour emoji across the UI. A per-size LVGL image-font (`lv_imgfont`) is attached as the fallback of each `meck_montserrat_*` font, so emoji codepoints the text font can't draw are rendered from baked-in Twemoji images instead of a missing-glyph box. Requires `CONFIG_LV_USE_IMGFONT=y`.\r\n- Emoji picker: a modal scrollable grid opened from the emoji key on the message-composer keyboards, inserting the chosen emoji as UTF-8. Dark-theme aware.\r\n- Expanded emoji set.\r\n- The emoji key moved to the right side of the space bar on the composer keyboards.\r\n- VS-16 presentation selector and the AU-flag regional indicators are handled so trailing combiners don't render as boxes.\r\n\r\n## Repeater Admin (Companion App)\r\n\r\nOver-the-mesh repeater administration from the MeshCore app. The app's session state is kept separate from the on-device Repeater Admin screen, so the two can't capture each other's responses.\r\n\r\n- **CMD_SEND_LOGIN (26)**: log in to a repeater from the app (force-flood for the login itself, `out_path` restored afterwards, `sync_since` reset for room contacts).\r\n- **CMD_SEND_STATUS_REQ (27)**: request a repeater's status block; matched back to the app by tag.\r\n- **CMD_HAS_CONNECTION (28)**: query whether a keep-alive session is active for a contact.\r\n- **CMD_LOGOUT (29)**: end the keep-alive session for a contact.\r\n- **CMD_SEND_BINARY_REQ (50)**: generic binary request (GET_NEIGHBOURS, ACL queries, owner info, and so on), forwarded verbatim and matched by tag. This is the path behind the app's neighbours command.\r\n- **Push notifications**: login success (0x85), login fail (0x86), status response (0x87), and binary response (0x8C). CLI text replies are queued to the app through the existing offline-message path (`TXT_TYPE_CLI_DATA`). Frame layouts mirror upstream byte-for-byte, so the app parses them with no protocol-version negotiation.\r\n- Pushes are delivered to both the BLE and WiFi companions.\r\n\r\n## Audio Player\r\n\r\n- **Track-skip fix**: fixed a cascade where an entire album would skip through in under a second. The end-of-track flag was being set on every player IDLE event, including the internal stop that fires when advancing to the next track, so each advance immediately triggered another. The flag is now set only on a genuine track completion.\r\n- **Bookmarks scoped to audiobooks**: resume bookmarks are kept only for files under `/sdcard/audio/audiobooks`. Music and other audio always start from the beginning, so finishing a short track no longer leaves a near-end position that made it skip on reopen, and no stray bookmark files are written for music.\r\n- **Tappable now-playing ind\n…",
          "notesHtml": "<p>Feature release building on v0.4, adding a plain-text reader, inline colour emoji with a picker, over-the-mesh repeater administration from the companion app, audio player fixes, and draft message saving. Firmware identity is now 0.5.</p>\n<h2>Text Reader</h2>\n<ul>\n<li>New plain-text (.txt) reader, opened from the home grid's Reader tile. Folder browser rooted at <code>/sdcard/books</code> with subfolder navigation, a breadcrumb, and an up-one-level button.</li>\n<li>Windowed, page-at-a-time rendering: the reader never loads the whole book, so memory and layout cost stay fixed to one screen regardless of file size. LVGL's own layout finds each page boundary at a clean line break.</li>\n<li>Per-book resume across reboots via a <code>.pos</code> sidecar, plus page-back through the pages visited in the current session.</li>\n<li>Percentage progress through the file.</li>\n<li>Reading-view taps: the left third turns back a page, the right two-thirds turns forward. Back returns to the browser; the browser's Back goes up a folder, or home at the <code>/sdcard/books</code> root.</li>\n<li>Honours the Settings font-size preference.</li>\n</ul>\n<h2>Inline Emoji</h2>\n<img alt=\"IMG_3256\" src=\"https://github.com/user-attachments/assets/0f1d6060-ec01-4973-bad8-0f28f027e80a\" />\n<img alt=\"IMG_3255\" src=\"https://github.com/user-attachments/assets/b62b299d-8f70-4d18-b8e4-4887b4c5efae\" /><ul>\n<li>Inline colour emoji across the UI. A per-size LVGL image-font (<code>lv_imgfont</code>) is attached as the fallback of each <code>meck_montserrat_*</code> font, so emoji codepoints the text font can't draw are rendered from baked-in Twemoji images instead of a missing-glyph box. Requires <code>CONFIG_LV_USE_IMGFONT=y</code>.</li>\n<li>Emoji picker: a modal scrollable grid opened from the emoji key on the message-composer keyboards, inserting the chosen emoji as UTF-8. Dark-theme aware.</li>\n<li>Expanded emoji set.</li>\n<li>The emoji key moved to the right side of the space bar on the composer keyboards.</li>\n<li>VS-16 presentation selector and the AU-flag regional indicators are handled so trailing combiners don't render as boxes.</li>\n</ul>\n<h2>Repeater Admin (Companion App)</h2>\n<p>Over-the-mesh repeater administration from the MeshCore app. The app's session state is kept separate from the on-device Repeater Admin screen, so the two can't capture each other's responses.</p>\n<ul>\n<li><strong>CMD_SEND_LOGIN (26)</strong>: log in to a repeater from the app (force-flood for the login itself, <code>out_path</code> restored afterwards, <code>sync_since</code> reset for room contacts).</li>\n<li><strong>CMD_SEND_STATUS_REQ (27)</strong>: request a repeater's status block; matched back to the app by tag.</li>\n<li><strong>CMD_HAS_CONNECTION (28)</strong>: query whether a keep-alive session is active for a contact.</li>\n<li><strong>CMD_LOGOUT (29)</strong>: end the keep-alive session for a contact.</li>\n<li><strong>CMD_SEND_BINARY_REQ (50)</strong>: generic binary request (GET_NEIGHBOURS, ACL queries, owner info, and so on), forwarded verbatim and matched by tag. This is the path behind the app's neighbours command.</li>\n<li><strong>Push notifications</strong>: login success (0x85), login fail (0x86), status response (0x87), and binary response (0x8C). CLI text replies are queued to the app through the existing offline-message path (<code>TXT_TYPE_CLI_DATA</code>). Frame layouts mirror upstream byte-for-byte, so the app parses them with no protocol-version negotiation.</li>\n<li>Pushes are delivered to both the BLE and WiFi companions.</li>\n</ul>\n<h2>Audio Player</h2>\n<ul>\n<li><strong>Track-skip fix</strong>: fixed a cascade where an entire album would skip through in under a second. The end-of-track flag was being set on every player IDLE event, including the internal stop that fires when advancing to the next track, so each advance immediately triggered another. The flag is now set only on a genuine track completion.</li>\n<li><strong>Bookmarks scoped to audiobooks</strong>: resume bookmarks are kept only for files under <code>/sdcard/audio/audiobooks</code>. Music and other audio always start from the beginning, so finishing a short track no longer leaves a near-end position that made it skip on reopen, and no stray bookmark files are written for music.</li>\n<li>**Tappable now-playing ind\n…</li>\n</ul>\n"
        },
        {
          "version": "v0.4",
          "name": "Meck P4 v0.4 Pre-release: WiFi companion app support",
          "datetime": "2026-05-28T08:09:22Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.4",
          "prerelease": true,
          "notes": "Feature release building on v0.3.8, adding WiFi companion app support, companion protocol compatibility, power optimisation, and stability improvements.\r\n\r\n## WiFi Companion Support\r\n\r\n- Full WiFi companion transport via ESP32-C6 AT commands over SDIO. Connect the MeshCore app to your T-Display P4 over your local WiFi network (TCP port 5000).\r\n- WiFi SSID and password configuration from the device Settings screen.\r\n- WiFi IP address displayed on the home screen and settings page with live refresh.\r\n- WiFi-aware sleep: when WiFi is active, the display dims to zero brightness instead of entering light sleep (which would kill the SDIO bus and TCP connection). Touch or boot button wakes the screen.\r\n\r\n## Companion Protocol\r\n\r\nExtensive companion protocol implementation for MeshCore app compatibility:\r\n\r\n- **CMD_DEVICE_QUERY (22)**: Full device info response including firmware version, build date, model, path hash mode.\r\n- **CMD_APP_START (1)**: Identity, radio params, and position shared with the app on connection.\r\n- **CMD_GET_CONTACTS (4)**: Full contact iteration with streaming and incremental sync (since timestamp).\r\n- **CMD_SEND_CHANNEL_TXT_MSG (3)**: Send channel messages from the app, with own-echo detection so the app shows \"Heard X Repeats\".\r\n- **CMD_SET_ADVERT_NAME (8)**: Set node name from the app.\r\n- **CMD_SET_RADIO_PARAMS (11)**: Set frequency, bandwidth, spreading factor, coding rate (reboot to apply).\r\n- **CMD_SET_RADIO_TX_POWER (12)**: Set TX power.\r\n- **CMD_SET_ADVERT_LATLON (14)**: Set position for adverts.\r\n- **CMD_REMOVE_CONTACT (15)**: Delete contacts from the app.\r\n- **CMD_EXPORT_PRIVATE_KEY (23)**: Export identity for config backup.\r\n- **CMD_IMPORT_PRIVATE_KEY (24)**: Import identity for config restore.\r\n- **CMD_GET_CONTACT_BY_KEY (30)**: Look up contact by public key (required for app-side delete).\r\n- **CMD_SET_CHANNEL (32)**: Import/update channel name and secret from the app.\r\n- **CMD_SET_OTHER_PARAMS (38)**: Set manual add, advert location policy, multi-acks.\r\n- **CMD_GET_CUSTOM_VARS (40)**: Returns GPS state, interval, latitude, longitude for the app's Position Settings page.\r\n- **CMD_SET_CUSTOM_VAR (41)**: Toggle GPS on/off, set latitude/longitude from the app.\r\n- **CMD_GET_ADVERT_PATH (42)**: Returns cached advert path hashes so the app can display route details with repeater names.\r\n- **CMD_SET_FLOOD_SCOPE_KEY (54)**: Acknowledged (stub).\r\n- **CMD_SET_PATH_HASH_MODE (61)**: Set path hash size (1-byte, 2-byte, or 3-byte) from the app's Experimental Settings.\r\n- **CMD_SET_DEFAULT_FLOOD_SCOPE (63)**: Set/clear default region scope from the app.\r\n- **CMD_GET_DEFAULT_FLOOD_SCOPE (64)**: Returns current scope name and key.\r\n- **Push notifications**: Channel messages, DM messages, send confirmations (acks), new adverts, and path updates are all pushed to the app in real time.\r\n\r\n## Channel Expansion\r\n\r\n- Channel support expanded from 12 to 40 (`MAX_GROUP_CHANNELS`).\r\n- Channel notification preferences array expanded to match (41 slots: 40 channels + 1 DM).\r\n- Channel picker UI updated to support all 40 channels.\r\n- Stack-local channel record arrays moved to heap allocation to prevent stack overflow.\r\n\r\n## Power Optimisation\r\n\r\n- **ICM20948 IMU**: Put to sleep after init (~3mA saved).\r\n- **ES8311 audio codec**: DAC, ADC, and PGA powered down after init. I2S channels disabled to release APB_FREQ_MAX PM locks. Woken on demand before playback, slept after stop (~5-10mA saved).\r\n- **I2S PM lock management**: Added `disable_channels()` / `enable_channels()` to Hardware_Iis class so I2S driver PM locks are only held during active audio playback.\r\n- **DFS investigation**: PM stats task added (enable via sdkconfig). Confirmed DSI display driver holds CPU_FREQ_MAX lock 97% of the time while screen is on, making CPU frequency reduction ineffective. ~172mA baseline is the hardware floor with display active.\r\n\r\n## UI Improvements\r\n\r\n- **Path display**: Incoming message routes and outgoing heard-by lists reformatted as n\n…",
          "notesHtml": "<p>Feature release building on v0.3.8, adding WiFi companion app support, companion protocol compatibility, power optimisation, and stability improvements.</p>\n<h2>WiFi Companion Support</h2>\n<ul>\n<li>Full WiFi companion transport via ESP32-C6 AT commands over SDIO. Connect the MeshCore app to your T-Display P4 over your local WiFi network (TCP port 5000).</li>\n<li>WiFi SSID and password configuration from the device Settings screen.</li>\n<li>WiFi IP address displayed on the home screen and settings page with live refresh.</li>\n<li>WiFi-aware sleep: when WiFi is active, the display dims to zero brightness instead of entering light sleep (which would kill the SDIO bus and TCP connection). Touch or boot button wakes the screen.</li>\n</ul>\n<h2>Companion Protocol</h2>\n<p>Extensive companion protocol implementation for MeshCore app compatibility:</p>\n<ul>\n<li><strong>CMD_DEVICE_QUERY (22)</strong>: Full device info response including firmware version, build date, model, path hash mode.</li>\n<li><strong>CMD_APP_START (1)</strong>: Identity, radio params, and position shared with the app on connection.</li>\n<li><strong>CMD_GET_CONTACTS (4)</strong>: Full contact iteration with streaming and incremental sync (since timestamp).</li>\n<li><strong>CMD_SEND_CHANNEL_TXT_MSG (3)</strong>: Send channel messages from the app, with own-echo detection so the app shows \"Heard X Repeats\".</li>\n<li><strong>CMD_SET_ADVERT_NAME (8)</strong>: Set node name from the app.</li>\n<li><strong>CMD_SET_RADIO_PARAMS (11)</strong>: Set frequency, bandwidth, spreading factor, coding rate (reboot to apply).</li>\n<li><strong>CMD_SET_RADIO_TX_POWER (12)</strong>: Set TX power.</li>\n<li><strong>CMD_SET_ADVERT_LATLON (14)</strong>: Set position for adverts.</li>\n<li><strong>CMD_REMOVE_CONTACT (15)</strong>: Delete contacts from the app.</li>\n<li><strong>CMD_EXPORT_PRIVATE_KEY (23)</strong>: Export identity for config backup.</li>\n<li><strong>CMD_IMPORT_PRIVATE_KEY (24)</strong>: Import identity for config restore.</li>\n<li><strong>CMD_GET_CONTACT_BY_KEY (30)</strong>: Look up contact by public key (required for app-side delete).</li>\n<li><strong>CMD_SET_CHANNEL (32)</strong>: Import/update channel name and secret from the app.</li>\n<li><strong>CMD_SET_OTHER_PARAMS (38)</strong>: Set manual add, advert location policy, multi-acks.</li>\n<li><strong>CMD_GET_CUSTOM_VARS (40)</strong>: Returns GPS state, interval, latitude, longitude for the app's Position Settings page.</li>\n<li><strong>CMD_SET_CUSTOM_VAR (41)</strong>: Toggle GPS on/off, set latitude/longitude from the app.</li>\n<li><strong>CMD_GET_ADVERT_PATH (42)</strong>: Returns cached advert path hashes so the app can display route details with repeater names.</li>\n<li><strong>CMD_SET_FLOOD_SCOPE_KEY (54)</strong>: Acknowledged (stub).</li>\n<li><strong>CMD_SET_PATH_HASH_MODE (61)</strong>: Set path hash size (1-byte, 2-byte, or 3-byte) from the app's Experimental Settings.</li>\n<li><strong>CMD_SET_DEFAULT_FLOOD_SCOPE (63)</strong>: Set/clear default region scope from the app.</li>\n<li><strong>CMD_GET_DEFAULT_FLOOD_SCOPE (64)</strong>: Returns current scope name and key.</li>\n<li><strong>Push notifications</strong>: Channel messages, DM messages, send confirmations (acks), new adverts, and path updates are all pushed to the app in real time.</li>\n</ul>\n<h2>Channel Expansion</h2>\n<ul>\n<li>Channel support expanded from 12 to 40 (<code>MAX_GROUP_CHANNELS</code>).</li>\n<li>Channel notification preferences array expanded to match (41 slots: 40 channels + 1 DM).</li>\n<li>Channel picker UI updated to support all 40 channels.</li>\n<li>Stack-local channel record arrays moved to heap allocation to prevent stack overflow.</li>\n</ul>\n<h2>Power Optimisation</h2>\n<ul>\n<li><strong>ICM20948 IMU</strong>: Put to sleep after init (~3mA saved).</li>\n<li><strong>ES8311 audio codec</strong>: DAC, ADC, and PGA powered down after init. I2S channels disabled to release APB_FREQ_MAX PM locks. Woken on demand before playback, slept after stop (~5-10mA saved).</li>\n<li><strong>I2S PM lock management</strong>: Added <code>disable_channels()</code> / <code>enable_channels()</code> to Hardware_Iis class so I2S driver PM locks are only held during active audio playback.</li>\n<li><strong>DFS investigation</strong>: PM stats task added (enable via sdkconfig). Confirmed DSI display driver holds CPU_FREQ_MAX lock 97% of the time while screen is on, making CPU frequency reduction ineffective. ~172mA baseline is the hardware floor with display active.</li>\n</ul>\n<h2>UI Improvements</h2>\n<ul>\n<li><strong>Path display</strong>: Incoming message routes and outgoing heard-by lists reformatted as n\n…</li>\n</ul>\n"
        },
        {
          "version": "v0.3.8",
          "name": "v0.3.8",
          "datetime": "2026-05-27T02:36:17Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.3.8",
          "prerelease": true,
          "notes": "Pre-release.\r\n\r\nFeature release building on v0.3.6, adding position adverts, share position, path view, private channels, and voice/picture over LoRa infrastructure (disabled pending final integration).\r\n\r\n---\r\n\r\n## What's New\r\n\r\n### Position Adverts\r\n\r\nYour GPS position can now be encoded into outgoing adverts, allowing other nodes on the mesh to see your location on their Maps screen. Position is configured via a new **Settings > Position** sub-screen with three fields:\r\n\r\n- **Latitude / Longitude** (tap to edit) for manual entry in decimal degrees\r\n- **Share Position** (tap to cycle): Off / Manual / Auto-GPS\r\n\r\nIn Auto-GPS mode, the L76K GPS snapshot is polled every 15 minutes and the stored position is updated automatically whenever the fix changes. A **Copy Position** button is also available on the sub-screen.\r\n\r\n### Share Position\r\n\r\nThe **+** button on the channel messages and DM compose screens now includes a **Share Position** option. Tapping it sends your current lat/lon as a message to the active channel or conversation.\r\n\r\n### Path View and Message Actions\r\n\r\nLong-pressing an incoming message now opens **Path View**, which displays the routing path that message took through the mesh, showing each hop in the route.\r\n\r\nLong-pressing an outgoing message gives you the option to **Retry Send** if the message failed, or to see which repeaters acknowledged the message.\r\n\r\n### Private Channels\r\n\r\nChannels can now be public or private:\r\n\r\n- **Public channels** start with `#` (e.g. `#test`). The secret is derived via SHA-256 from the name, matching the standard MeshCore convention.\r\n- **Private channels** have no `#` prefix. A random 16-byte secret is generated at creation, so only invited users can join.\r\n\r\n**Sharing:** open **Settings > Channels**, tap the channel, then tap **Share Channel**. This opens a contact picker and sends the channel name and secret as a DM invitation. Recipients see a pending invite they can accept (tap) or dismiss (long-press).\r\n\r\n---\r\n\r\n### Voice over LoRa Infrastructure (Not Yet Enabled)\r\n\r\nThe full infrastructure for Codec2 1200bps voice messaging has been added to the firmware:\r\n\r\n- Codec2 ESP-IDF component (`components/codec2/`) wrapping drowe67/codec2 with only the core 1200bps mode compiled in\r\n- ES8311 microphone capture at native 44100 Hz I2S rate\r\n- VE3 protocol for chunked voice packet transfer\r\n- Recording buffer in PSRAM, staggered send timing\r\n- Voice UI: inbox with metadata persistence, record screen with Play/Discard/Send, previous recordings list, contact picker (favourites first), send status tracking\r\n- Playback at 85% volume via meck_audio_play_file\r\n\r\nVoice and Picture tiles are present on the home screen as placeholders but the features are disabled in this release pending final integration and testing.\r\n\r\n### Picture over LoRa Infrastructure (Not Yet Enabled)\r\n\r\nChunked image transfer protocol infrastructure has been added but is disabled in this release.\r\n\r\n### UI Changes\r\n\r\n- **Splash screen** updated with new design and progress bar\r\n- **Maps and Trace tile colours** swapped so there are no longer two adjacent red tiles on the home screen\r\n- **Home screen** expanded from seven tiles to nine (Voice and Camera placeholders added)\r\n- **MAX_GROUP_CHANNELS** bumped from 8 to 12\r\n\r\n---\r\n\r\n## First-Time Flashing: Read This First\r\n\r\nMeck-P4 ships as a single **merged binary** (bootloader + partition table + application combined). One file, flash at offset `0x0`.\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot and notification sounds won't be available.\r\n\r\nEnsure you use the **right-side USB-C port** (the data port), not the high-speed charger port, to flash.\r\n<img width=\"377\" height=\"284\" alt=\"correct \n…",
          "notesHtml": "<p>Pre-release.</p>\n<p>Feature release building on v0.3.6, adding position adverts, share position, path view, private channels, and voice/picture over LoRa infrastructure (disabled pending final integration).</p>\n<hr />\n<h2>What's New</h2>\n<h3>Position Adverts</h3>\n<p>Your GPS position can now be encoded into outgoing adverts, allowing other nodes on the mesh to see your location on their Maps screen. Position is configured via a new <strong>Settings &gt; Position</strong> sub-screen with three fields:</p>\n<ul>\n<li><strong>Latitude / Longitude</strong> (tap to edit) for manual entry in decimal degrees</li>\n<li><strong>Share Position</strong> (tap to cycle): Off / Manual / Auto-GPS</li>\n</ul>\n<p>In Auto-GPS mode, the L76K GPS snapshot is polled every 15 minutes and the stored position is updated automatically whenever the fix changes. A <strong>Copy Position</strong> button is also available on the sub-screen.</p>\n<h3>Share Position</h3>\n<p>The <strong>+</strong> button on the channel messages and DM compose screens now includes a <strong>Share Position</strong> option. Tapping it sends your current lat/lon as a message to the active channel or conversation.</p>\n<h3>Path View and Message Actions</h3>\n<p>Long-pressing an incoming message now opens <strong>Path View</strong>, which displays the routing path that message took through the mesh, showing each hop in the route.</p>\n<p>Long-pressing an outgoing message gives you the option to <strong>Retry Send</strong> if the message failed, or to see which repeaters acknowledged the message.</p>\n<h3>Private Channels</h3>\n<p>Channels can now be public or private:</p>\n<ul>\n<li><strong>Public channels</strong> start with <code>#</code> (e.g. <code>#test</code>). The secret is derived via SHA-256 from the name, matching the standard MeshCore convention.</li>\n<li><strong>Private channels</strong> have no <code>#</code> prefix. A random 16-byte secret is generated at creation, so only invited users can join.</li>\n</ul>\n<p><strong>Sharing:</strong> open <strong>Settings &gt; Channels</strong>, tap the channel, then tap <strong>Share Channel</strong>. This opens a contact picker and sends the channel name and secret as a DM invitation. Recipients see a pending invite they can accept (tap) or dismiss (long-press).</p>\n<hr />\n<h3>Voice over LoRa Infrastructure (Not Yet Enabled)</h3>\n<p>The full infrastructure for Codec2 1200bps voice messaging has been added to the firmware:</p>\n<ul>\n<li>Codec2 ESP-IDF component (<code>components/codec2/</code>) wrapping drowe67/codec2 with only the core 1200bps mode compiled in</li>\n<li>ES8311 microphone capture at native 44100 Hz I2S rate</li>\n<li>VE3 protocol for chunked voice packet transfer</li>\n<li>Recording buffer in PSRAM, staggered send timing</li>\n<li>Voice UI: inbox with metadata persistence, record screen with Play/Discard/Send, previous recordings list, contact picker (favourites first), send status tracking</li>\n<li>Playback at 85% volume via meck_audio_play_file</li>\n</ul>\n<p>Voice and Picture tiles are present on the home screen as placeholders but the features are disabled in this release pending final integration and testing.</p>\n<h3>Picture over LoRa Infrastructure (Not Yet Enabled)</h3>\n<p>Chunked image transfer protocol infrastructure has been added but is disabled in this release.</p>\n<h3>UI Changes</h3>\n<ul>\n<li><strong>Splash screen</strong> updated with new design and progress bar</li>\n<li><strong>Maps and Trace tile colours</strong> swapped so there are no longer two adjacent red tiles on the home screen</li>\n<li><strong>Home screen</strong> expanded from seven tiles to nine (Voice and Camera placeholders added)</li>\n<li><strong>MAX_GROUP_CHANNELS</strong> bumped from 8 to 12</li>\n</ul>\n<hr />\n<h2>First-Time Flashing: Read This First</h2>\n<p>Meck-P4 ships as a single <strong>merged binary</strong> (bootloader + partition table + application combined). One file, flash at offset <code>0x0</code>.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, notification tones have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot and notification sounds won't be available.</p>\n</blockquote>\n<p>Ensure you use the <strong>right-side USB-C port</strong> (the data port), not the high-speed charger port, to flash.\n&lt;img width=\"377\" height=\"284\" alt=\"correct \n…</p>\n"
        },
        {
          "version": "v0.3.6",
          "name": "Meck-P4 v0.3.6: Custom Radio, Region Scope, Channels, Notification Sounds",
          "datetime": "2026-05-24T23:38:02Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.3.6",
          "prerelease": true,
          "notes": "Pre-release.\r\n\r\nFeature release building on v0.3.5.1, adding custom radio parameters, region scope support, a Channels settings sub-screen, and per-channel notification sounds.\r\n\r\n---\r\n\r\n## What's New\r\n\r\n### Custom Radio Parameters\r\n\r\nFrequency, Bandwidth, and Spreading Factor are now individually editable via text entry in Settings (tap the row, type the value, tap Confirm). Coding Rate cycles on tap (4/5 through 4/8). The Radio Preset row remains available and shows \"Custom\" whenever the current values don't match any of the 17 built-in presets. Selecting a preset populates all four fields; you can then tweak individual values without losing the rest.\r\n\r\nThis is primarily useful for users in regions where the community presets don't cover the exact parameters in use, such as parts of Europe running SR 5/6 with 32.5 kHz bandwidth, or anyone wanting to customise the coding rate independently.\r\n\r\n### Region Scope (MeshCore v1.15+ Compatibility)\r\n\r\nRegions limit how far your flood messages propagate through the mesh. When you set a region, outgoing messages are tagged with a transport code that repeaters use to decide whether to forward them. Messages sent without a region reach all repeaters via the default wildcard, same as always.\r\n\r\n**Setting your device region:**\r\n- Open **Settings**, tap **Default Region**, enter your region name (e.g. `au-nsw`), tap **Confirm**\r\n- Leave empty for unscoped (legacy behaviour, reaches all repeaters)\r\n\r\n**Per-channel region:** Open **Settings > Channels**, tap a channel, then tap **Region Scope** to set an override for that specific channel. Empty uses the device default.\r\n\r\n**Finding your region name:** Region names are determined by your local mesh community. Check with your local group, or browse the community region registry at [regions.meshcore.nz](https://regions.meshcore.nz/) for names already in use. Common patterns follow ISO 3166 codes (e.g. `au` for Australia, `au-nsw`, `gb-eng`, `us-ca`), but communities may also use custom names. Names must be lowercase alphanumeric characters and hyphens, max 30 characters. You can also create your own custom regions on repeaters you manage (see Repeater Admin below).\r\n\r\n**Note:** Region scoping requires repeaters in your area to be running MeshCore v1.10+ with the appropriate regions configured. If no repeaters have region filtering enabled, scoped and unscoped messages behave identically.\r\n\r\n### Repeater Admin: Region Management via CLI\r\n\r\nRepeaters running MeshCore v1.10+ support full region management through the Cmd Line screen in Repeater Admin. Log in to a repeater, tap **Cmd Line**, and use the following commands:\r\n\r\n| Command | Description |\r\n| --- | --- |\r\n| `region put <name> [parent]` | Create a new region (optional parent for nesting) |\r\n| `region remove <name>` | Remove a region (remove children first) |\r\n| `region allowf <name>` | Allow flooding for a region |\r\n| `region denyf <name>` | Block flooding for a region |\r\n| `region get <name>` | Show info for a region |\r\n| `region home` / `region home <name>` | View or set the repeater's home region |\r\n| `region default` / `region default <name>` | View or set the repeater's default scope |\r\n| `region save` | Persist region changes to the repeater's flash |\r\n| `region list allowed` / `region list denied` | View regions (repeater firmware 1.12+) |\r\n| `region load <name> [F]` | Single-line region load (append `F` to allow flooding) |\r\n\r\n**Not supported:** The interactive multi-line `region load` (without parameters) requires a serial terminal and is not available on the P4, which does not currently support serial CLI commands. Use individual `region put` and `region allowf` commands instead.\r\n\r\n**Quick start example** (setting up a repeater for the `au-nsw` region):\r\n```\r\nregion put au-nsw\r\nregion allowf au-nsw\r\nregion home au-nsw\r\nregion save\r\n```\r\n\r\nFor full documentation and nested region examples, see the [MeshCore CLI docs](https://docs.meshcore.io/cli_commands/#region-management-v1\n…",
          "notesHtml": "<p>Pre-release.</p>\n<p>Feature release building on v0.3.5.1, adding custom radio parameters, region scope support, a Channels settings sub-screen, and per-channel notification sounds.</p>\n<hr />\n<h2>What's New</h2>\n<h3>Custom Radio Parameters</h3>\n<p>Frequency, Bandwidth, and Spreading Factor are now individually editable via text entry in Settings (tap the row, type the value, tap Confirm). Coding Rate cycles on tap (4/5 through 4/8). The Radio Preset row remains available and shows \"Custom\" whenever the current values don't match any of the 17 built-in presets. Selecting a preset populates all four fields; you can then tweak individual values without losing the rest.</p>\n<p>This is primarily useful for users in regions where the community presets don't cover the exact parameters in use, such as parts of Europe running SR 5/6 with 32.5 kHz bandwidth, or anyone wanting to customise the coding rate independently.</p>\n<h3>Region Scope (MeshCore v1.15+ Compatibility)</h3>\n<p>Regions limit how far your flood messages propagate through the mesh. When you set a region, outgoing messages are tagged with a transport code that repeaters use to decide whether to forward them. Messages sent without a region reach all repeaters via the default wildcard, same as always.</p>\n<p><strong>Setting your device region:</strong></p>\n<ul>\n<li>Open <strong>Settings</strong>, tap <strong>Default Region</strong>, enter your region name (e.g. <code>au-nsw</code>), tap <strong>Confirm</strong></li>\n<li>Leave empty for unscoped (legacy behaviour, reaches all repeaters)</li>\n</ul>\n<p><strong>Per-channel region:</strong> Open <strong>Settings &gt; Channels</strong>, tap a channel, then tap <strong>Region Scope</strong> to set an override for that specific channel. Empty uses the device default.</p>\n<p><strong>Finding your region name:</strong> Region names are determined by your local mesh community. Check with your local group, or browse the community region registry at <a href=\"https://regions.meshcore.nz/\" target=\"_blank\" rel=\"noopener noreferrer\">regions.meshcore.nz</a> for names already in use. Common patterns follow ISO 3166 codes (e.g. <code>au</code> for Australia, <code>au-nsw</code>, <code>gb-eng</code>, <code>us-ca</code>), but communities may also use custom names. Names must be lowercase alphanumeric characters and hyphens, max 30 characters. You can also create your own custom regions on repeaters you manage (see Repeater Admin below).</p>\n<p><strong>Note:</strong> Region scoping requires repeaters in your area to be running MeshCore v1.10+ with the appropriate regions configured. If no repeaters have region filtering enabled, scoped and unscoped messages behave identically.</p>\n<h3>Repeater Admin: Region Management via CLI</h3>\n<p>Repeaters running MeshCore v1.10+ support full region management through the Cmd Line screen in Repeater Admin. Log in to a repeater, tap <strong>Cmd Line</strong>, and use the following commands:</p>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>region put &lt;name&gt; [parent]</code></td>\n<td>Create a new region (optional parent for nesting)</td>\n</tr>\n<tr>\n<td><code>region remove &lt;name&gt;</code></td>\n<td>Remove a region (remove children first)</td>\n</tr>\n<tr>\n<td><code>region allowf &lt;name&gt;</code></td>\n<td>Allow flooding for a region</td>\n</tr>\n<tr>\n<td><code>region denyf &lt;name&gt;</code></td>\n<td>Block flooding for a region</td>\n</tr>\n<tr>\n<td><code>region get &lt;name&gt;</code></td>\n<td>Show info for a region</td>\n</tr>\n<tr>\n<td><code>region home</code> / <code>region home &lt;name&gt;</code></td>\n<td>View or set the repeater's home region</td>\n</tr>\n<tr>\n<td><code>region default</code> / <code>region default &lt;name&gt;</code></td>\n<td>View or set the repeater's default scope</td>\n</tr>\n<tr>\n<td><code>region save</code></td>\n<td>Persist region changes to the repeater's flash</td>\n</tr>\n<tr>\n<td><code>region list allowed</code> / <code>region list denied</code></td>\n<td>View regions (repeater firmware 1.12+)</td>\n</tr>\n<tr>\n<td><code>region load &lt;name&gt; [F]</code></td>\n<td>Single-line region load (append <code>F</code> to allow flooding)</td>\n</tr>\n</tbody></table>\n<p><strong>Not supported:</strong> The interactive multi-line <code>region load</code> (without parameters) requires a serial terminal and is not available on the P4, which does not currently support serial CLI commands. Use individual <code>region put</code> and <code>region allowf</code> commands instead.</p>\n<p><strong>Quick start example</strong> (setting up a repeater for the <code>au-nsw</code> region):</p>\n<pre><code>region put au-nsw\nregion allowf au-nsw\nregion home au-nsw\nregion save\n</code></pre>\n<p>For full documentation and nested region examples, see the [MeshCore CLI docs](<a href=\"https://docs.meshcore.io/cli_commands/#region-management-v1\" target=\"_blank\" rel=\"noopener noreferrer\">https://docs.meshcore.io/cli_commands/#region-management-v1</a>\n…</p>\n"
        },
        {
          "version": "v0.3.5.1",
          "name": "Meck-P4 v0.3.5.1: Contacts list fixes",
          "datetime": "2026-05-22T19:34:27Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.3.5.1",
          "prerelease": true,
          "notes": "Pre-release.\r\n\r\nPatch release on top of v0.3.5, fixing three bugs in the Contacts screen:\r\n\r\n- **200-row cap removed.** The contacts list previously stopped rendering after 200 matched rows. With 200+ contacts this hid recently-added repeaters from the list entirely (including, in one reproducible case, a freshly-added Repeater that Discover claimed to have added but which was nowhere to be seen). The list now displays every matching contact.\r\n- **Sorted by recency.** Contacts now appear newest-first instead of in creation order. The sort key is local activity time (advert receipt, message send, or message receive), so the most recently active contacts sit at the top of the list regardless of which filter is active.\r\n- **Sort key corrected.** Initial attempt used `last_advert_timestamp`, which is the *sender's claimed clock* embedded in the advert payload rather than our reception time. That gave nonsense ordering: nodes with forward-dated clocks (stale build epoch, mis-set NTP, etc.) sat permanently at the top, and nodes whose clocks were stuck or behind had their adverts silently dropped by the upstream replay-attack guard and sank to the bottom. The fix sorts by `lastmod` (our local RTC time at last contact activity) with an override in `onAdvertRecv` so `lastmod` is updated on every advert receipt regardless of whether the upstream replay guard early-returned.\r\n\r\nNo other behavioural changes from v0.3.5.\r\n\r\n## First-Time Flashing: Read This First\r\n\r\n(Same as v0.3.5 — skip this section if you've already flashed v0.3.5; the contacts fixes carry over via the usual upgrade path.)\r\n\r\nMeck-P4 ships as a single **merged binary** (bootloader + partition table + application combined). One file, flash at offset `0x0`.\r\n\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.\r\n\r\nEnsure you use the **right-side USB-C port** (the data port), not the high-speed charger port, to flash.\r\n<img width=\"377\" height=\"284\" alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/b6634315-9f7b-4b63-a944-1c52508a101c\" />\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to <https://flasher.meshcore.io/>\r\n2. Scroll to the bottom and select **Custom Firmware**\r\n3. Select the `meck-p4-0.3.5.1-version-merged.bin` file you downloaded\r\n4. Click OK on the merged-binary warning\r\n5. Click **Flash**, pick your device in the popup, and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\npip install esptool\r\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.5.1-version-merged.bin\r\n```\r\n\r\n(Replace `PORT` with `/dev/cu.usbmodemXXXX` on macOS, `/dev/ttyACM0` on Linux, or `COM3` on Windows.)\r\n\r\nUpgrading from v0.3.5 or v0.3.3 does not require `erase_flash`. The prefs loader continues to tolerate older shorter-blob layouts, so any new fields come up at default rather than wiping existing settings.\r\n\r\n> ⚠️ **AMOLED variant remains untested by the maintainer.** The `-amoled.bin` is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.\r\n\r\n## Known Limitations\r\n\r\nCarried over unchanged from v0.3.5:\r\n\r\n- **Background audio playback has known issues — not recommended for general use yet.** A blue `>>` glyph was added to the top bar to indicate when the audio player is actively playing, mirrored across every home tile and full screen. However, the broader background-playback experience has a number of unresolved bugs: tapping the Audio tile while a track is playing doesn't jump back to the Now Playing screen (so pausing requires navigating back to the file manually), and starting a second \n…",
          "notesHtml": "<p>Pre-release.</p>\n<p>Patch release on top of v0.3.5, fixing three bugs in the Contacts screen:</p>\n<ul>\n<li><strong>200-row cap removed.</strong> The contacts list previously stopped rendering after 200 matched rows. With 200+ contacts this hid recently-added repeaters from the list entirely (including, in one reproducible case, a freshly-added Repeater that Discover claimed to have added but which was nowhere to be seen). The list now displays every matching contact.</li>\n<li><strong>Sorted by recency.</strong> Contacts now appear newest-first instead of in creation order. The sort key is local activity time (advert receipt, message send, or message receive), so the most recently active contacts sit at the top of the list regardless of which filter is active.</li>\n<li><strong>Sort key corrected.</strong> Initial attempt used <code>last_advert_timestamp</code>, which is the <em>sender's claimed clock</em> embedded in the advert payload rather than our reception time. That gave nonsense ordering: nodes with forward-dated clocks (stale build epoch, mis-set NTP, etc.) sat permanently at the top, and nodes whose clocks were stuck or behind had their adverts silently dropped by the upstream replay-attack guard and sank to the bottom. The fix sorts by <code>lastmod</code> (our local RTC time at last contact activity) with an override in <code>onAdvertRecv</code> so <code>lastmod</code> is updated on every advert receipt regardless of whether the upstream replay guard early-returned.</li>\n</ul>\n<p>No other behavioural changes from v0.3.5.</p>\n<h2>First-Time Flashing: Read This First</h2>\n<p>(Same as v0.3.5 — skip this section if you've already flashed v0.3.5; the contacts fixes carry over via the usual upgrade path.)</p>\n<p>Meck-P4 ships as a single <strong>merged binary</strong> (bootloader + partition table + application combined). One file, flash at offset <code>0x0</code>.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.</p>\n</blockquote>\n<p>Ensure you use the <strong>right-side USB-C port</strong> (the data port), not the high-speed charger port, to flash.\n<img alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/b6634315-9f7b-4b63-a944-1c52508a101c\" /></p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n<li>Scroll to the bottom and select <strong>Custom Firmware</strong></li>\n<li>Select the <code>meck-p4-0.3.5.1-version-merged.bin</code> file you downloaded</li>\n<li>Click OK on the merged-binary warning</li>\n<li>Click <strong>Flash</strong>, pick your device in the popup, and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>pip install esptool\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.5.1-version-merged.bin\n</code></pre>\n<p>(Replace <code>PORT</code> with <code>/dev/cu.usbmodemXXXX</code> on macOS, <code>/dev/ttyACM0</code> on Linux, or <code>COM3</code> on Windows.)</p>\n<p>Upgrading from v0.3.5 or v0.3.3 does not require <code>erase_flash</code>. The prefs loader continues to tolerate older shorter-blob layouts, so any new fields come up at default rather than wiping existing settings.</p>\n<blockquote>\n<p>⚠️ <strong>AMOLED variant remains untested by the maintainer.</strong> The <code>-amoled.bin</code> is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.</p>\n</blockquote>\n<h2>Known Limitations</h2>\n<p>Carried over unchanged from v0.3.5:</p>\n<ul>\n<li><strong>Background audio playback has known issues — not recommended for general use yet.</strong> A blue <code>&gt;&gt;</code> glyph was added to the top bar to indicate when the audio player is actively playing, mirrored across every home tile and full screen. However, the broader background-playback experience has a number of unresolved bugs: tapping the Audio tile while a track is playing doesn't jump back to the Now Playing screen (so pausing requires navigating back to the file manually), and starting a second \n…</li>\n</ul>\n"
        },
        {
          "version": "v0.3.5",
          "name": "Meck-P4 v0.3.5: Direct Messaging, Repeater Admin, Room servers & Maps",
          "datetime": "2026-05-21T09:56:27Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.3.5",
          "prerelease": true,
          "notes": "Direct messaging arrives in v0.3.5 — compose, send, receive, and persist DMs from any companion contact, with unread badges viewable in the channel list. Room server support and repeater admin land alongside, giving you logged-in access to room post history and the full status/CLI/settings interface for remote repeater management. A new map screen renders OSM slippy tiles from the SD card with a GPS dot, contact markers, and pan/zoom. Plus a per-contact path editor, a standalone trace route screen, a keyboard layout overhaul, a GPS time-sync fix, debug logs to SD, and config export to a MeshCore-app-compatible JSON file.\r\n\r\n> ⚠️ **Still a pre-release.** ⚠️ Web browser, IRC, and the BLE/WiFi companion path are still not in this build. See What's Not Yet Implemented for the full pending list.\r\n\r\n## First-Time Flashing: Read This First\r\n\r\nMeck-P4 ships as a single **merged binary** (bootloader + partition table + application combined). One file, flash at offset `0x0`.\r\n\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.\r\n\r\nEnsure you use the **right-side USB-C port** (the data port), not the high-speed charger port, to flash.\r\n<img width=\"377\" height=\"284\" alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/d3a7e17d-5efa-46c3-af5e-61f97f125569\" />\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to <https://flasher.meshcore.io/>\r\n2. Scroll to the bottom and select **Custom Firmware**\r\n3. Select the `meck-p4-0.3.5-version-merged.bin` file you downloaded\r\n4. Click OK on the merged-binary warning\r\n5. Click **Flash**, pick your device in the popup, and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\npip install esptool\r\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.5-version-merged.bin\r\n```\r\n\r\n(Replace `PORT` with `/dev/cu.usbmodemXXXX` on macOS, `/dev/ttyACM0` on Linux, or `COM3` on Windows.)\r\n\r\nUpgrading from v0.3.3 does not require `erase_flash`. The prefs loader continues to tolerate older shorter-blob layouts, so any new fields come up at default rather than wiping existing settings.\r\n\r\n> ⚠️ **AMOLED variant remains untested by the maintainer.** The `-amoled.bin` is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.\r\n\r\n## What's New Since v0.3.3\r\n\r\n### Direct Messaging\r\n\r\nOpen a companion contact's detail screen (from the Contacts menu tile on the home screen) and tap the cyan **Send DM** button (stacked above the red Delete button) to compose. The DM conversation view uses the standard chat layout — keyboard on the bottom half, message bubbles scrolling above.\r\n\r\n- Per-contact 20-message ring buffers in PSRAM, lazy-allocated so unused contacts cost nothing\r\n- Per-contact DM history persisted to SD and reloaded on boot\r\n- DM Inbox row in the channel picker shows a per-contact unread badge, refreshed every tick\r\n- Send-side ACK tracking — outgoing bubbles update from \"Sending...\" through to \"Delivered\" or \"Failed\" as the ACK round-trip completes\r\n\r\n### Room Server Support\r\n\r\nTap a Room-type contact to open the same admin login flow as repeaters. On successful login, the room's post timeline appears as a scrollable bubble list, left-aligned, with the author name above each bubble and a timestamp and hop count footer below.\r\n\r\n- Post history persisted per-room to SD and loaded on boot, so you don't need to re-login to see what's already been received\r\n- Live re-render: posts arriving while you're sitting on the room view land in the bubble list without leaving the screen\r\n- Author resolution walks your contacts looking for a matc\n…",
          "notesHtml": "<p>Direct messaging arrives in v0.3.5 — compose, send, receive, and persist DMs from any companion contact, with unread badges viewable in the channel list. Room server support and repeater admin land alongside, giving you logged-in access to room post history and the full status/CLI/settings interface for remote repeater management. A new map screen renders OSM slippy tiles from the SD card with a GPS dot, contact markers, and pan/zoom. Plus a per-contact path editor, a standalone trace route screen, a keyboard layout overhaul, a GPS time-sync fix, debug logs to SD, and config export to a MeshCore-app-compatible JSON file.</p>\n<blockquote>\n<p>⚠️ <strong>Still a pre-release.</strong> ⚠️ Web browser, IRC, and the BLE/WiFi companion path are still not in this build. See What's Not Yet Implemented for the full pending list.</p>\n</blockquote>\n<h2>First-Time Flashing: Read This First</h2>\n<p>Meck-P4 ships as a single <strong>merged binary</strong> (bootloader + partition table + application combined). One file, flash at offset <code>0x0</code>.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting, channel message, DM, and room post is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.</p>\n</blockquote>\n<p>Ensure you use the <strong>right-side USB-C port</strong> (the data port), not the high-speed charger port, to flash.\n<img alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/d3a7e17d-5efa-46c3-af5e-61f97f125569\" /></p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n<li>Scroll to the bottom and select <strong>Custom Firmware</strong></li>\n<li>Select the <code>meck-p4-0.3.5-version-merged.bin</code> file you downloaded</li>\n<li>Click OK on the merged-binary warning</li>\n<li>Click <strong>Flash</strong>, pick your device in the popup, and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>pip install esptool\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.5-version-merged.bin\n</code></pre>\n<p>(Replace <code>PORT</code> with <code>/dev/cu.usbmodemXXXX</code> on macOS, <code>/dev/ttyACM0</code> on Linux, or <code>COM3</code> on Windows.)</p>\n<p>Upgrading from v0.3.3 does not require <code>erase_flash</code>. The prefs loader continues to tolerate older shorter-blob layouts, so any new fields come up at default rather than wiping existing settings.</p>\n<blockquote>\n<p>⚠️ <strong>AMOLED variant remains untested by the maintainer.</strong> The <code>-amoled.bin</code> is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.</p>\n</blockquote>\n<h2>What's New Since v0.3.3</h2>\n<h3>Direct Messaging</h3>\n<p>Open a companion contact's detail screen (from the Contacts menu tile on the home screen) and tap the cyan <strong>Send DM</strong> button (stacked above the red Delete button) to compose. The DM conversation view uses the standard chat layout — keyboard on the bottom half, message bubbles scrolling above.</p>\n<ul>\n<li>Per-contact 20-message ring buffers in PSRAM, lazy-allocated so unused contacts cost nothing</li>\n<li>Per-contact DM history persisted to SD and reloaded on boot</li>\n<li>DM Inbox row in the channel picker shows a per-contact unread badge, refreshed every tick</li>\n<li>Send-side ACK tracking — outgoing bubbles update from \"Sending...\" through to \"Delivered\" or \"Failed\" as the ACK round-trip completes</li>\n</ul>\n<h3>Room Server Support</h3>\n<p>Tap a Room-type contact to open the same admin login flow as repeaters. On successful login, the room's post timeline appears as a scrollable bubble list, left-aligned, with the author name above each bubble and a timestamp and hop count footer below.</p>\n<ul>\n<li>Post history persisted per-room to SD and loaded on boot, so you don't need to re-login to see what's already been received</li>\n<li>Live re-render: posts arriving while you're sitting on the room view land in the bubble list without leaving the screen</li>\n<li>Author resolution walks your contacts looking for a matc\n…</li>\n</ul>\n"
        },
        {
          "version": "v0.3.3",
          "name": "Meck-P4 v0.3.3: MeshCore Config Import, BQ27220 Calibration, UI Polish",
          "datetime": "2026-05-18T02:47:07Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.3.3",
          "prerelease": true,
          "notes": "One-step config import from the MeshCore mobile app so existing users can move to a P4 without re-entering everything, a firmware-side fix for the BQ27220 fuel gauge calibration so the battery percentage matches reality, and substantial UI work on the home screen, Settings, and tile layouts. Plus a small power-savings pass that trims about 38 mA off idle draw.\r\n\r\n> ⚠️ **Still a pre-release.** ⚠️ Direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, and the BLE companion path are still not in this build. See What's Not Yet Implemented for the full pending list.\r\n\r\n## First-Time Flashing: Read This First\r\n\r\nMeck-P4 ships as a single **merged binary** (bootloader + partition table + application combined). One file, flash at offset `0x0`.\r\n\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.\r\n\r\nEnsure you use the **right-side USB-C port** (the data port), not the high-speed charger port, to flash.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to https://flasher.meshcore.io/\r\n2. Scroll to the bottom and select **Custom Firmware**\r\n3. Select the `meck-p4-0.3.3-version-merged.bin` file you downloaded\r\n4. Click OK on the merged-binary warning\r\n5. Click **Flash**, pick your device in the popup, and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\npip install esptool\r\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.3-version-merged.bin\r\n```\r\n\r\n(Replace `PORT` with `/dev/cu.usbmodemXXXX` on macOS, `/dev/ttyACM0` on Linux, or `COM3` on Windows.)\r\n\r\nUpgrading from v0.3 does not require `erase_flash`. The prefs loader has been made tolerant of older shorter-blob layouts, so any new fields added in v0.3.3 (such as Font Size) come up at default rather than wiping existing settings.\r\n\r\n> ⚠️ **AMOLED variant remains untested by the maintainer.** The `-amoled.bin` is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.\r\n\r\n## What's New Since v0.3\r\n\r\n### MeshCore App Config Import\r\n\r\nDrop your MeshCore mobile or desktop app config export onto the SD card, reboot, and your identity, channels, contacts, node name, and radio settings come across in one step. No more re-entering contacts or generating a fresh keypair when moving to the P4.\r\n\r\nHow to use:\r\n\r\n1. In the MeshCore mobile or desktop app, export your config as JSON\r\n2. Rename to `import.json` and copy to `/sdcard/meshcore/import.json` on the P4's SD card\r\n3. Reboot the device\r\n\r\nOn boot, Meck reads the file and applies it:\r\n\r\n| Field | Behaviour |\r\n|---|---|\r\n| Identity (private + public key) | Replaces `_main.id` atomically (tmp + rename). Existing identity is overwritten. |\r\n| Channels | Merged by 16-byte secret. Existing channels kept; new ones appended to free slots; duplicates skipped. |\r\n| Contacts | Merged by public key. Existing kept; new ones appended. Lat/lon converted from string-decimal to int32 e7. `custom_name` preferred over `name`. |\r\n| Node name | Replaces `prefs.node_name`. |\r\n| Radio settings | Replaces freq, BW, SF, CR, TX power on `P4NodePrefs`. Freq converted kHz to MHz, BW Hz to kHz. |\r\n\r\nOn success the file is moved to `/sdcard/meshcore/import.history/import-<unix_epoch>.json` so it doesn't re-apply on subsequent boots and leaves an audit trail. On parse failure (bad JSON, missing identity keys, wrong-length hex) a warning is logged and the file is left in place for inspection.\r\n\r\nImported names (node, channels, contacts) are stripped to printable ASCII before being stored. Meck-P4's Montserrat fonts cover Latin-1 only, so emoji codepoints would otherwise render as tofu boxes. Leading an\n…",
          "notesHtml": "<p>One-step config import from the MeshCore mobile app so existing users can move to a P4 without re-entering everything, a firmware-side fix for the BQ27220 fuel gauge calibration so the battery percentage matches reality, and substantial UI work on the home screen, Settings, and tile layouts. Plus a small power-savings pass that trims about 38 mA off idle draw.</p>\n<blockquote>\n<p>⚠️ <strong>Still a pre-release.</strong> ⚠️ Direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, and the BLE companion path are still not in this build. See What's Not Yet Implemented for the full pending list.</p>\n</blockquote>\n<h2>First-Time Flashing: Read This First</h2>\n<p>Meck-P4 ships as a single <strong>merged binary</strong> (bootloader + partition table + application combined). One file, flash at offset <code>0x0</code>.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.</p>\n</blockquote>\n<p>Ensure you use the <strong>right-side USB-C port</strong> (the data port), not the high-speed charger port, to flash.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n<li>Scroll to the bottom and select <strong>Custom Firmware</strong></li>\n<li>Select the <code>meck-p4-0.3.3-version-merged.bin</code> file you downloaded</li>\n<li>Click OK on the merged-binary warning</li>\n<li>Click <strong>Flash</strong>, pick your device in the popup, and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>pip install esptool\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3.3-version-merged.bin\n</code></pre>\n<p>(Replace <code>PORT</code> with <code>/dev/cu.usbmodemXXXX</code> on macOS, <code>/dev/ttyACM0</code> on Linux, or <code>COM3</code> on Windows.)</p>\n<p>Upgrading from v0.3 does not require <code>erase_flash</code>. The prefs loader has been made tolerant of older shorter-blob layouts, so any new fields added in v0.3.3 (such as Font Size) come up at default rather than wiping existing settings.</p>\n<blockquote>\n<p>⚠️ <strong>AMOLED variant remains untested by the maintainer.</strong> The <code>-amoled.bin</code> is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand. The TFT variant is the tested and known-working build.</p>\n</blockquote>\n<h2>What's New Since v0.3</h2>\n<h3>MeshCore App Config Import</h3>\n<p>Drop your MeshCore mobile or desktop app config export onto the SD card, reboot, and your identity, channels, contacts, node name, and radio settings come across in one step. No more re-entering contacts or generating a fresh keypair when moving to the P4.</p>\n<p>How to use:</p>\n<ol>\n<li>In the MeshCore mobile or desktop app, export your config as JSON</li>\n<li>Rename to <code>import.json</code> and copy to <code>/sdcard/meshcore/import.json</code> on the P4's SD card</li>\n<li>Reboot the device</li>\n</ol>\n<p>On boot, Meck reads the file and applies it:</p>\n<table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Behaviour</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Identity (private + public key)</td>\n<td>Replaces <code>_main.id</code> atomically (tmp + rename). Existing identity is overwritten.</td>\n</tr>\n<tr>\n<td>Channels</td>\n<td>Merged by 16-byte secret. Existing channels kept; new ones appended to free slots; duplicates skipped.</td>\n</tr>\n<tr>\n<td>Contacts</td>\n<td>Merged by public key. Existing kept; new ones appended. Lat/lon converted from string-decimal to int32 e7. <code>custom_name</code> preferred over <code>name</code>.</td>\n</tr>\n<tr>\n<td>Node name</td>\n<td>Replaces <code>prefs.node_name</code>.</td>\n</tr>\n<tr>\n<td>Radio settings</td>\n<td>Replaces freq, BW, SF, CR, TX power on <code>P4NodePrefs</code>. Freq converted kHz to MHz, BW Hz to kHz.</td>\n</tr>\n</tbody></table>\n<p>On success the file is moved to <code>/sdcard/meshcore/import.history/import-&lt;unix_epoch&gt;.json</code> so it doesn't re-apply on subsequent boots and leaves an audit trail. On parse failure (bad JSON, missing identity keys, wrong-length hex) a warning is logged and the file is left in place for inspection.</p>\n<p>Imported names (node, channels, contacts) are stripped to printable ASCII before being stored. Meck-P4's Montserrat fonts cover Latin-1 only, so emoji codepoints would otherwise render as tofu boxes. Leading an\n…</p>\n"
        },
        {
          "version": "v0.3",
          "name": "Meck-P4 v0.3 -- Audio Player, Active Discovery, Internationalised Keyboard",
          "datetime": "2026-05-16T03:53:52Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.3",
          "prerelease": true,
          "notes": "The third Meck-P4 pre-release. Audio playback from SD, active zero-hop neighbour discovery with one-tap contact add, and a substantially upgraded virtual keyboard with light/dark theme, three physical layouts, and long-press accent input for French and Czech. Plus per-message hop and ACK metadata, and a fix for the battery cell capacity (which had been wrong since v0.1).\r\n\r\n> **⚠️ Still a pre-release.⚠️ ** Direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, and the BLE companion path are still not in this build. See [What's Not Yet Implemented](#whats-not-yet-implemented) for the full pending list.\r\n\r\n---\r\n\r\n## First-Time Flashing -- Read This First\r\n\r\nMeck-P4 ships as a single **merged binary** (bootloader + partition table + application combined). One file, flash at offset `0x0`.\r\n\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.\r\n<img width=\"377\" height=\"284\" alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/c9b670d7-53ca-4da3-8506-03ad83590387\" />\r\n\r\nEnsure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash.\r\n\r\n### Flashing with the MeshCore Web Flasher (recommended)\r\n\r\n1. Go to <https://flasher.meshcore.io/>\r\n2. Scroll to the bottom and select **Custom Firmware**\r\n3. Select the `meck-p4-0.3-version-merged.bin` file you downloaded\r\n4. Click OK on the merged-binary warning\r\n5. Click **Flash**, pick your device in the popup, and click **Connect**\r\n\r\n### Flashing with esptool.py\r\n\r\n```\r\npip install esptool\r\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3-version-merged.bin\r\n```\r\n\r\n(Replace `PORT` with `/dev/cu.usbmodemXXXX` on macOS, `/dev/ttyACM0` on Linux, or `COM3` on Windows.)\r\n\r\nIf you're upgrading from v0.1 and want to start with clean defaults, run `esptool.py --chip esp32p4 -p PORT erase_flash` before the write. Your contacts and prefs will be restored from the SD card mirror on first boot.\r\n\r\n> ⚠️ AMOLED variant is untested. The -amoled.bin is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand and hasn't been able to flash or run it. Community members are currently testing it. If you have an AMOLED board, please report back via the [MeshCore Discord](https://discord.com/channels/1495203904898728149/1500323702859104457) or a GitHub issue with whether it boots, the display works, and touch works. The TFT variant is the tested and known-working build.\r\n\r\n---\r\n\r\n## What's New Since v0.1\r\n\r\n### Audio Player\r\n\r\nMP3 playback directly from the SD card. Two top-level subtrees give the player different defaults so music and audiobooks behave appropriately:\r\n\r\n| Subtree | Defaults |\r\n| --- | --- |\r\n| `/sdcard/audio/music/` | Standard playback. Resume bookmark off. |\r\n| `/sdcard/audio/audiobooks/` | Audiobook mode. Resume bookmark on, sleep timer available, position tracked through the playlist. |\r\n\r\n**How to use the audio player:**\r\n\r\n1. Drop your `music/` and `audiobooks/` folders into `/sdcard/audio/` on the SD card (the firmware creates the subtree automatically on first boot if it doesn't exist)\r\n2. Insert the card and power on\r\n3. Tap the **Audio** tile on the home grid to open the browser\r\n4. Navigate to a track and tap to play\r\n5. Use the transport row on the Now Playing screen for skip / play-pause / volume\r\n\r\n> **Read the [audio player guide](https://github.com/pelgraine/Meck-P4/blob/main/information/Meck%20Docs/audioplayerguide.md) before copying files to your SD card.** MP3s with large embedded album art can starve the IDLE task on first decode and trigger a watchdog reboot. The guide walks through the `tools/mp3_clean.py` script that strip\n…",
          "notesHtml": "<p>The third Meck-P4 pre-release. Audio playback from SD, active zero-hop neighbour discovery with one-tap contact add, and a substantially upgraded virtual keyboard with light/dark theme, three physical layouts, and long-press accent input for French and Czech. Plus per-message hop and ACK metadata, and a fix for the battery cell capacity (which had been wrong since v0.1).</p>\n<blockquote>\n<p>**⚠️ Still a pre-release.⚠️ ** Direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, and the BLE companion path are still not in this build. See <a href=\"#whats-not-yet-implemented\" target=\"_blank\" rel=\"noopener noreferrer\">What's Not Yet Implemented</a> for the full pending list.</p>\n</blockquote>\n<hr />\n<h2>First-Time Flashing -- Read This First</h2>\n<p>Meck-P4 ships as a single <strong>merged binary</strong> (bootloader + partition table + application combined). One file, flash at offset <code>0x0</code>.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically, audio files have somewhere to live, and the device recovers gracefully from a wiped NVS. Without an SD card the device still works but loses message history on reboot.</p>\n<img alt=\"correct port usage for flashing\" src=\"https://github.com/user-attachments/assets/c9b670d7-53ca-4da3-8506-03ad83590387\" /></blockquote>\n<p>Ensure you use the right-side USB-C port (the data port), not the high-speed charger port, to flash.</p>\n<h3>Flashing with the MeshCore Web Flasher (recommended)</h3>\n<ol>\n<li>Go to <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io/</a></li>\n<li>Scroll to the bottom and select <strong>Custom Firmware</strong></li>\n<li>Select the <code>meck-p4-0.3-version-merged.bin</code> file you downloaded</li>\n<li>Click OK on the merged-binary warning</li>\n<li>Click <strong>Flash</strong>, pick your device in the popup, and click <strong>Connect</strong></li>\n</ol>\n<h3>Flashing with esptool.py</h3>\n<pre><code>pip install esptool\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.3-version-merged.bin\n</code></pre>\n<p>(Replace <code>PORT</code> with <code>/dev/cu.usbmodemXXXX</code> on macOS, <code>/dev/ttyACM0</code> on Linux, or <code>COM3</code> on Windows.)</p>\n<p>If you're upgrading from v0.1 and want to start with clean defaults, run <code>esptool.py --chip esp32p4 -p PORT erase_flash</code> before the write. Your contacts and prefs will be restored from the SD card mirror on first boot.</p>\n<blockquote>\n<p>⚠️ AMOLED variant is untested. The -amoled.bin is built from the same source tree with the AMOLED display option selected in menuconfig, but the project maintainer doesn't have the AMOLED hardware on hand and hasn't been able to flash or run it. Community members are currently testing it. If you have an AMOLED board, please report back via the <a href=\"https://discord.com/channels/1495203904898728149/1500323702859104457\" target=\"_blank\" rel=\"noopener noreferrer\">MeshCore Discord</a> or a GitHub issue with whether it boots, the display works, and touch works. The TFT variant is the tested and known-working build.</p>\n</blockquote>\n<hr />\n<h2>What's New Since v0.1</h2>\n<h3>Audio Player</h3>\n<p>MP3 playback directly from the SD card. Two top-level subtrees give the player different defaults so music and audiobooks behave appropriately:</p>\n<table>\n<thead>\n<tr>\n<th>Subtree</th>\n<th>Defaults</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>/sdcard/audio/music/</code></td>\n<td>Standard playback. Resume bookmark off.</td>\n</tr>\n<tr>\n<td><code>/sdcard/audio/audiobooks/</code></td>\n<td>Audiobook mode. Resume bookmark on, sleep timer available, position tracked through the playlist.</td>\n</tr>\n</tbody></table>\n<p><strong>How to use the audio player:</strong></p>\n<ol>\n<li>Drop your <code>music/</code> and <code>audiobooks/</code> folders into <code>/sdcard/audio/</code> on the SD card (the firmware creates the subtree automatically on first boot if it doesn't exist)</li>\n<li>Insert the card and power on</li>\n<li>Tap the <strong>Audio</strong> tile on the home grid to open the browser</li>\n<li>Navigate to a track and tap to play</li>\n<li>Use the transport row on the Now Playing screen for skip / play-pause / volume</li>\n</ol>\n<blockquote>\n<p><strong>Read the <a href=\"https://github.com/pelgraine/Meck-P4/blob/main/information/Meck%20Docs/audioplayerguide.md\" target=\"_blank\" rel=\"noopener noreferrer\">audio player guide</a> before copying files to your SD card.</strong> MP3s with large embedded album art can starve the IDLE task on first decode and trigger a watchdog reboot. The guide walks through the <code>tools/mp3_clean.py</code> script that strip\n…</p>\n</blockquote>\n"
        },
        {
          "version": "v0.1",
          "name": "Meck-P4 v0.1 — First Pre-Release for the LilyGo T-Display P4",
          "datetime": "2026-05-09T08:14:03Z",
          "url": "https://github.com/pelgraine/Meck-P4/releases/tag/v0.1",
          "prerelease": true,
          "notes": "The first publicly flashable Meck firmware for the LilyGo T-Display P4. One\r\nfile, one offset, you're on the mesh.\r\n\r\n> **⚠️ This is a pre-release, not a finished product.** Many of the features people associate with Meck on the T-Deck Pro and T5S3 — direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, audio player — are **not yet implemented** on the P4. What's here is the foundation: a fully functional MeshCore node with channel messaging, contacts, persistent storage, GPS, and battery monitoring. See the [full feature list and roadmap](https://github.com/pelgraine/Meck-P4#road-map--to-do).\r\n\r\n---\r\n\r\n## Hardware\r\n\r\n⚠️ LilyGo T-Display P4 (TFT version)⚠️  **The AMOLED variant has not been tested** but should be close — adjust the display init in\r\n`main/examples/lvgl_9_ui/main.cpp` if you want to try it.\r\n\r\n## Flashing\r\n<img width=\"377\" height=\"284\" alt=\"IMG_2838\" src=\"https://github.com/user-attachments/assets/0ed6126c-d51d-46b6-b71a-e51161ac9c40\" />\r\n\r\n\r\nEnsure you use the right-usb C port, ie **not** the high-speed charger port to flash.\r\n\r\nThe release file `meck-p4-0.1-merged.bin` is a **merged binary** containing the bootloader, partition table, and application combined into a single image — flash it at address `0x0`.\r\n\r\n**Using the MeshCore Flasher (web-based):**\r\n\r\n1. Go to <https://flasher.meshcore.io>\r\n2. Scroll to the bottom and select **Custom Firmware**\r\n3. Select the `meck-p4-0.1.bin` file you downloaded\r\n4. Click OK for the warning about erase files because it's a merged binary.\r\n5. Click **Flash**, choose your device in the popup, and click **Connect**\r\n\r\n**Using esptool.py:**\r\n\r\n```\r\npip install esptool\r\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.1.bin\r\n```\r\n\r\n(Replace `PORT` with `/dev/cu.usbmodemXXXX` on macOS, `/dev/ttyACM0` on Linux, or `COM3` on Windows.)\r\n\r\nIf you've previously had something else on the device, run `esptool.py --chip esp32p4 -p PORT erase_flash` first to clear NVS so Meck starts with clean defaults.\r\n\r\n> **An SD card is recommended.** With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically. The device works without one but loses message history on reboot.\r\n\r\n---\r\n\r\n## What's Working\r\n\r\n### 📡 Mesh networking\r\n\r\n- Channel messaging — send and receive on Public, #test, #sydney\r\n- 17-preset radio picker (AU, US, EU, CN regions). Boots on Australia Narrow by default (916.575 MHz / SF7 / BW 62.5 kHz / CR 4/8)\r\n- Adverts go out automatically; received adverts populate Recent Heard and (subject to your auto-add policy) the contact list\r\n- **Self-healing public-channel migration** — earlier dev builds derived the Public channel secret from a hash, which didn't match the rest of the network. v0.1 detects this on every boot and repairs it automatically, without disturbing your custom channels\r\n\r\n### 📱 UI\r\n\r\nA horizontal seven-tile home layout. Swipe left/right to switch tiles.\r\n\r\n| Tile | What it shows |\r\n| --- | --- |\r\n| 0 Home | Node name, freq/SF/RSSI/RX counters, six-button nav grid |\r\n| 1 Recent Heard | Live list of nodes whose adverts you've received |\r\n| 2 Radio Details | Current freq / BW / SF / CR / TX / sync word |\r\n| 3 Advert | Long-press to send a manual advert |\r\n| 4 GPS | Fix status, satellites, position, altitude, sentence rate |\r\n| 5 Battery | Voltage, charge%, current, chip temp, remaining mAh |\r\n| 6 Shutdown | Long-press to power down |\r\n\r\n### 👥 Contacts\r\n\r\n- Filter chip bar at the top: All / Chat / Rptr / Room / Sens / Fav. Swipe left/right to cycle, or tap a chip directly\r\n- Per-row colour-coded type pill (C / R / RS / S) and 4-byte pubkey prefix for disambiguation\r\n- **Long-press a contact** to toggle favourite (a star appears, the contact rises to the top)\r\n- Tap a contact to open the detail screen, with a red **Hold** button that long-press-deletes (single tap is unbound to prevent accidents)\r\n- Auto-add policies in Settings → Contacts: Auto All / Custom (per-type toggles) / Manu\n…",
          "notesHtml": "<p>The first publicly flashable Meck firmware for the LilyGo T-Display P4. One\nfile, one offset, you're on the mesh.</p>\n<blockquote>\n<p><strong>⚠️ This is a pre-release, not a finished product.</strong> Many of the features people associate with Meck on the T-Deck Pro and T5S3 — direct messaging, roomserver access, repeater admin, trace route, web browser, IRC, audio player — are <strong>not yet implemented</strong> on the P4. What's here is the foundation: a fully functional MeshCore node with channel messaging, contacts, persistent storage, GPS, and battery monitoring. See the <a href=\"https://github.com/pelgraine/Meck-P4#road-map--to-do\" target=\"_blank\" rel=\"noopener noreferrer\">full feature list and roadmap</a>.</p>\n</blockquote>\n<hr />\n<h2>Hardware</h2>\n<p>⚠️ LilyGo T-Display P4 (TFT version)⚠️  <strong>The AMOLED variant has not been tested</strong> but should be close — adjust the display init in\n<code>main/examples/lvgl_9_ui/main.cpp</code> if you want to try it.</p>\n<h2>Flashing</h2>\n<img alt=\"IMG_2838\" src=\"https://github.com/user-attachments/assets/0ed6126c-d51d-46b6-b71a-e51161ac9c40\" /><p>Ensure you use the right-usb C port, ie <strong>not</strong> the high-speed charger port to flash.</p>\n<p>The release file <code>meck-p4-0.1-merged.bin</code> is a <strong>merged binary</strong> containing the bootloader, partition table, and application combined into a single image — flash it at address <code>0x0</code>.</p>\n<p><strong>Using the MeshCore Flasher (web-based):</strong></p>\n<ol>\n<li>Go to <a href=\"https://flasher.meshcore.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.meshcore.io</a></li>\n<li>Scroll to the bottom and select <strong>Custom Firmware</strong></li>\n<li>Select the <code>meck-p4-0.1.bin</code> file you downloaded</li>\n<li>Click OK for the warning about erase files because it's a merged binary.</li>\n<li>Click <strong>Flash</strong>, choose your device in the popup, and click <strong>Connect</strong></li>\n</ol>\n<p><strong>Using esptool.py:</strong></p>\n<pre><code>pip install esptool\nesptool.py --chip esp32p4 -p PORT write_flash 0x0 meck-p4-0.1.bin\n</code></pre>\n<p>(Replace <code>PORT</code> with <code>/dev/cu.usbmodemXXXX</code> on macOS, <code>/dev/ttyACM0</code> on Linux, or <code>COM3</code> on Windows.)</p>\n<p>If you've previously had something else on the device, run <code>esptool.py --chip esp32p4 -p PORT erase_flash</code> first to clear NVS so Meck starts with clean defaults.</p>\n<blockquote>\n<p><strong>An SD card is recommended.</strong> With a FAT32-formatted card inserted, every saved setting and channel message is mirrored automatically. The device works without one but loses message history on reboot.</p>\n</blockquote>\n<hr />\n<h2>What's Working</h2>\n<h3>📡 Mesh networking</h3>\n<ul>\n<li>Channel messaging — send and receive on Public, #test, #sydney</li>\n<li>17-preset radio picker (AU, US, EU, CN regions). Boots on Australia Narrow by default (916.575 MHz / SF7 / BW 62.5 kHz / CR 4/8)</li>\n<li>Adverts go out automatically; received adverts populate Recent Heard and (subject to your auto-add policy) the contact list</li>\n<li><strong>Self-healing public-channel migration</strong> — earlier dev builds derived the Public channel secret from a hash, which didn't match the rest of the network. v0.1 detects this on every boot and repairs it automatically, without disturbing your custom channels</li>\n</ul>\n<h3>📱 UI</h3>\n<p>A horizontal seven-tile home layout. Swipe left/right to switch tiles.</p>\n<table>\n<thead>\n<tr>\n<th>Tile</th>\n<th>What it shows</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>0 Home</td>\n<td>Node name, freq/SF/RSSI/RX counters, six-button nav grid</td>\n</tr>\n<tr>\n<td>1 Recent Heard</td>\n<td>Live list of nodes whose adverts you've received</td>\n</tr>\n<tr>\n<td>2 Radio Details</td>\n<td>Current freq / BW / SF / CR / TX / sync word</td>\n</tr>\n<tr>\n<td>3 Advert</td>\n<td>Long-press to send a manual advert</td>\n</tr>\n<tr>\n<td>4 GPS</td>\n<td>Fix status, satellites, position, altitude, sentence rate</td>\n</tr>\n<tr>\n<td>5 Battery</td>\n<td>Voltage, charge%, current, chip temp, remaining mAh</td>\n</tr>\n<tr>\n<td>6 Shutdown</td>\n<td>Long-press to power down</td>\n</tr>\n</tbody></table>\n<h3>👥 Contacts</h3>\n<ul>\n<li>Filter chip bar at the top: All / Chat / Rptr / Room / Sens / Fav. Swipe left/right to cycle, or tap a chip directly</li>\n<li>Per-row colour-coded type pill (C / R / RS / S) and 4-byte pubkey prefix for disambiguation</li>\n<li><strong>Long-press a contact</strong> to toggle favourite (a star appears, the contact rises to the top)</li>\n<li>Tap a contact to open the detail screen, with a red <strong>Hold</strong> button that long-press-deletes (single tap is unbound to prevent accidents)</li>\n<li>Auto-add policies in Settings → Contacts: Auto All / Custom (per-type toggles) / Manu\n…</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:31.755Z"
    },
    {
      "id": "meshcomod",
      "name": "Meshcomod",
      "type": "fork",
      "maintainer": "ALLFATHER-BV",
      "description": "A multi-transport companion firmware built on MeshCore that exposes USB, Bluetooth and TCP connectivity simultaneously, so phones, web clients and Home Assistant can all talk to one radio at once. Adds runtime Wi-Fi config and an on-device UI.\n",
      "repository": "https://github.com/ALLFATHER-BV/meshcomod",
      "website": "https://meshcomod.com",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "stable",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "features": [
        "Simultaneous USB + BLE + TCP connections",
        "Real-time push to all connected clients",
        "Home Assistant sidebar integration",
        "Runtime Wi-Fi configuration (no CLI recovery)",
        "On-device UI tabs (BLE pairing, TCP status)"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "heltec-v4",
          "status": "supported"
        },
        {
          "id": "heltec-v4-exp",
          "status": "supported"
        },
        {
          "id": "heltec-v3",
          "status": "supported"
        },
        {
          "id": "heltec-wsl3",
          "status": "supported"
        },
        {
          "id": "heltec-paper",
          "status": "supported"
        },
        {
          "id": "xiao-esp32s3",
          "status": "supported"
        }
      ],
      "popularity": {
        "githubStars": 62,
        "githubForks": 6,
        "githubWatchers": 5,
        "githubOpenIssues": 4,
        "githubContributors": 151,
        "releaseDownloads": 144,
        "latestReleaseDownloads": 38,
        "lastChecked": "2026-06-21"
      },
      "verification": {
        "sourceAvailable": true,
        "releasesAvailable": true,
        "ciBuilds": true,
        "lastChecked": "2026-06-21"
      },
      "latest_version": "1.16.0.4",
      "released": "2026-06-16",
      "releases": [
        {
          "version": "companion-v1.16.0.4",
          "name": "Companion Firmware v1.16.0.4",
          "datetime": "2026-06-16T19:39:49Z",
          "url": "https://github.com/ALLFATHER-BV/meshcomod/releases/tag/companion-v1.16.0.4",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.3...companion-v1.16.0.4",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.3...companion-v1.16.0.4\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.3...companion-v1.16.0.4</a></p>\n"
        },
        {
          "version": "companion-v1.16.0.3",
          "name": "Companion Firmware v1.16.0.3",
          "datetime": "2026-06-15T10:44:19Z",
          "url": "https://github.com/ALLFATHER-BV/meshcomod/releases/tag/companion-v1.16.0.3",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.2...companion-v1.16.0.3",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.2...companion-v1.16.0.3\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.2...companion-v1.16.0.3</a></p>\n"
        },
        {
          "version": "companion-v1.16.0.2",
          "name": "Companion Firmware v1.16.0.2",
          "datetime": "2026-06-14T06:32:51Z",
          "url": "https://github.com/ALLFATHER-BV/meshcomod/releases/tag/companion-v1.16.0.2",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.1...companion-v1.16.0.2",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.1...companion-v1.16.0.2\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/ALLFATHER-BV/meshcomod/compare/companion-v1.16.0.1...companion-v1.16.0.2</a></p>\n"
        },
        {
          "version": "companion-v1.16.0.1",
          "name": "Companion Firmware v1.16.0.1",
          "datetime": "2026-06-13T21:10:09Z",
          "url": "https://github.com/ALLFATHER-BV/meshcomod/releases/tag/companion-v1.16.0.1",
          "prerelease": false,
          "notes": "**meshcomod companion v1.16.0.1** (on MeshCore 1.16).\n\nBoards: Heltec V4 (OLED), Heltec V3, Heltec Wireless Paper (E213), Seeed Xiao S3 WIO — multi-transport USB + BLE + TCP.\n\n**Fixes**\n- **BLE no longer fails to start when Wi-Fi credentials are set** (issue #32). On the V4/OLED companions, BLE and Wi-Fi now co-init correctly at boot instead of BLE being deferred and unable to come up later.\n\nFlash the `-merged.bin` at 0x0 for a first-time/recovery flash, or the app-only `.bin` at 0x10000 over a matching partition table.",
          "notesHtml": "<p><strong>meshcomod companion v1.16.0.1</strong> (on MeshCore 1.16).</p>\n<p>Boards: Heltec V4 (OLED), Heltec V3, Heltec Wireless Paper (E213), Seeed Xiao S3 WIO — multi-transport USB + BLE + TCP.</p>\n<p><strong>Fixes</strong></p>\n<ul>\n<li><strong>BLE no longer fails to start when Wi-Fi credentials are set</strong> (issue #32). On the V4/OLED companions, BLE and Wi-Fi now co-init correctly at boot instead of BLE being deferred and unable to come up later.</li>\n</ul>\n<p>Flash the <code>-merged.bin</code> at 0x0 for a first-time/recovery flash, or the app-only <code>.bin</code> at 0x10000 over a matching partition table.</p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:32.127Z"
    },
    {
      "id": "meshcore-lowpower",
      "name": "MeshCore Low-Power",
      "type": "fork",
      "maintainer": "dt267",
      "description": "A power-optimised MeshCore firmware with deep sleep, a full companion display UI with multi-transport connectivity (BLE + USB + WiFi in a single build), advanced radio and network controls, a browser-based configuration portal, and battery-life profiling — built for multi-day off-grid operation.\n",
      "repository": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "features": [
        "Deep power optimisation with idle current profiling",
        "Unified BLE + USB + WiFi companion build (single binary)",
        "Browser-based configuration portal (backup, restore, flash, reboot)",
        "Companion backup/restore (preferences, WiFi credentials, presets)",
        "Adaptive Rx boosted gain on Heltec V4.2",
        "GPS constellation selection and runtime GPS update interval",
        "Low-battery protection and voltage reading",
        "Native multilingual display on Heltec T096 colour TFT",
        "KCT8103L FEM auto-detection on Heltec V4.3"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": true,
          "lowPowerRx": true
        }
      },
      "devices": [
        {
          "id": "heltec-v3",
          "status": "supported"
        },
        {
          "id": "heltec-wsl3",
          "status": "supported"
        },
        {
          "id": "heltec-v4",
          "status": "supported"
        },
        {
          "id": "heltec-v4-exp",
          "status": "supported"
        },
        {
          "id": "heltec-e213",
          "status": "supported"
        },
        {
          "id": "heltec-e290",
          "status": "supported"
        },
        {
          "id": "heltec-paper",
          "status": "supported"
        },
        {
          "id": "heltec-t096",
          "status": "supported"
        },
        {
          "id": "xiao-esp32s3",
          "status": "supported"
        },
        {
          "id": "rak-4631",
          "status": "supported",
          "notes": "Uses RAK19003 base board for power profiling."
        },
        {
          "id": "uart-solar-node-station",
          "status": "supported",
          "notes": "Uses RAK4631 target; same as rak-4631."
        }
      ],
      "latest_version": "1.16.dev_0621",
      "released": "2026-06-21",
      "releases": [
        {
          "version": "MeshCore-low-power-v1.16.dev_0621",
          "name": "MeshCore low power - v1.16.dev_0621",
          "datetime": "2026-06-21T07:24:05Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.16.dev_0621",
          "prerelease": false,
          "notes": "### v1.16_0621\r\n\r\n- **Configuration portal for Companion, Repeater, and Room Server — configure, back up, restore, and update firmware without the CLI.** *(ESP32 devices only)*\r\n\r\n  Open it the same way as before — `start ota` in the CLI, or **Start OTA** from the companion Settings menu. Previously this landed on a firmware-only upload page; it now opens the full configuration portal where you can configure, back up, restore, flash firmware, and reboot — all from one page in the browser.\r\n\r\n  The companion backup covers custom preferences (Quick Send presets, saved locations, channel hop limits, display settings, WiFi credentials,...) that upstream MeshCore doesn't have — handy when moving to a new device. For the Repeater and Room Server, this is the first time backup and restore are available at all — no more re-entering everything from scratch after a node failure or hardware swap.\r\n\r\n  The portal is password-protected. Companion: set one with `set portal.password` in the CLI. Repeater / Room Server: the existing admin password is used automatically.\r\n\r\n  The backup format is compatible with the official MeshCore app — upstream preferences in the backup can be restored by the app. Passwords are never written to backup files.\r\n\r\n- **Config portal AP: open network, login page, 1-client limit, 10-minute idle auto-shutdown.**\r\n\r\n  The WiFi AP is open (no AP password); access is gated by a browser login page using the portal password described above. Only one device can associate with the AP at a time. If no device connects within 10 minutes of the AP opening, it shuts down automatically.\r\n\r\n  <img alt=\"config-portal\" src=\"https://github.com/user-attachments/assets/92a088b9-49b3-40d1-8caa-fd3da634347b\" />\r\n\r\n\r\n- **Fix: full-flash (`_merged.bin`) images for Vision Master E213 and E290 were built with the wrong flash size.**\r\n\r\n  Both boards have 16 MB of flash, but their merged full-flash images were generated with an 8 MB flash-size header. The pre-merged images are now built with the correct 16 MB size. If you previously flashed an E213 or E290 using a `_merged.bin`, re-flash with the corrected image. OTA (`.bin`) updates were not affected.",
          "notesHtml": "<h3>v1.16_0621</h3>\n<ul>\n<li><p><strong>Configuration portal for Companion, Repeater, and Room Server — configure, back up, restore, and update firmware without the CLI.</strong> <em>(ESP32 devices only)</em></p>\n<p>Open it the same way as before — <code>start ota</code> in the CLI, or <strong>Start OTA</strong> from the companion Settings menu. Previously this landed on a firmware-only upload page; it now opens the full configuration portal where you can configure, back up, restore, flash firmware, and reboot — all from one page in the browser.</p>\n<p>The companion backup covers custom preferences (Quick Send presets, saved locations, channel hop limits, display settings, WiFi credentials,...) that upstream MeshCore doesn't have — handy when moving to a new device. For the Repeater and Room Server, this is the first time backup and restore are available at all — no more re-entering everything from scratch after a node failure or hardware swap.</p>\n<p>The portal is password-protected. Companion: set one with <code>set portal.password</code> in the CLI. Repeater / Room Server: the existing admin password is used automatically.</p>\n<p>The backup format is compatible with the official MeshCore app — upstream preferences in the backup can be restored by the app. Passwords are never written to backup files.</p>\n</li>\n<li><p><strong>Config portal AP: open network, login page, 1-client limit, 10-minute idle auto-shutdown.</strong></p>\n<p>The WiFi AP is open (no AP password); access is gated by a browser login page using the portal password described above. Only one device can associate with the AP at a time. If no device connects within 10 minutes of the AP opening, it shuts down automatically.</p>\n<img alt=\"config-portal\" src=\"https://github.com/user-attachments/assets/92a088b9-49b3-40d1-8caa-fd3da634347b\" /></li>\n<li><p><strong>Fix: full-flash (<code>_merged.bin</code>) images for Vision Master E213 and E290 were built with the wrong flash size.</strong></p>\n<p>Both boards have 16 MB of flash, but their merged full-flash images were generated with an 8 MB flash-size header. The pre-merged images are now built with the correct 16 MB size. If you previously flashed an E213 or E290 using a <code>_merged.bin</code>, re-flash with the corrected image. OTA (<code>.bin</code>) updates were not affected.</p>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.16.dev_0614",
          "name": "MeshCore low power - v1.16.dev_0614",
          "datetime": "2026-06-14T04:15:08Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.16.dev_0614",
          "prerelease": false,
          "notes": "### v1.16_0614\r\n\r\n- **New devices: Heltec Vision Master E213, Wireless Paper, and Vision Master E290 — full e-ink companion support (Companion, Repeater, Room Server).**\r\n\r\n  Three e-ink boards are now fully supported with the complete companion UI — Quick Send, Contacts, Settings, Saved Locations, GPS Trace, and message preview. Repeater and Room Server firmware are provided for all three.\r\n\r\n  - **Heltec Vision Master E213** *(author-tested, v1.1.1)*  — ESP32-S3 with a 2.13\" e-ink display (250×122 px), SX1262 LoRa, and a QuickLink I2C port. Has a second user button (GPIO21): press to scroll up in any list, or to go back — faster than double clicking the main button.\r\n  - **Heltec Wireless Paper** — ESP32-S3 with the same 2.13\" e-ink panel as the E213 in a more compact form factor. Shares the same companion UI and firmware variants as the E213. Single button only.\r\n  - **Heltec Vision Master E290** — ESP32-S3R8 with a larger 2.9\" e-ink display (296×128 px), SX1262 LoRa, and a QuickLink I2C port. Also has a second button (GPIO21) like the E213. The companion UI adapts automatically to the wider panel — more message lines and a larger clock on the Home screen.\r\n\r\n  **Common characteristics across all three e-ink boards:**\r\n  - **Always-on display** — e-ink retains content indefinitely without power; no screen timeout.\r\n  - **Native multilingual text** — Latin, Cyrillic, and Greek scripts render natively.\r\n  - **Font Weight setting** — choose between **Thin** and **Bold** via **Settings → Font Weight**. Preference is saved to flash.\r\n  - **I2C sensor support** — environment sensors can be connected via the QuickLink I2C port.\r\n\r\n- **Companion: unified BLE / USB / WiFi connection mode for all ESP32-S3 boards.**\r\n\r\n  All ESP32-S3 companion builds (Heltec V3, V4, E213, Wireless Paper, E290, XIAO S3) now ship as a single unified firmware image that supports all three connection transports: **BLE**, **USB serial**, and **WiFi TCP**. The active mode is saved to flash and selected at boot — no per-mode build is needed.\r\n\r\n  Switching is done via **Settings → Connection Mode**, which opens a direct selection screen listing all three modes with the current one marked `*`. Navigate to the desired mode and confirm — the device reboots into the new mode.\r\n\r\n  Alternatively, switch via [TerminalCLI](Companion_TerminalCLI_Commands.md): `set conn.mode wifi|ble|usb`. WiFi credentials are configured with `set wifi.ssid` / `set wifi.password`, or from the **OTA update page** which now includes a WiFi credentials form alongside the firmware upload button.\r\n\r\n  In WiFi mode, the node connects as a STA to your router and the Home screen shows the IP address and port. All three modes meet the low-power criteria of this repo.  \r\n\r\n- **Companion UI: Home screen always shows a large clock; message count shown in the header.**\r\n\r\n  The center of the Home screen now always shows the current time (`HH:MM`) in a large font — `MSG: N` is gone. If there are messages stored in memory, their count and a small envelope icon appear in the header (where the small clock used to be); the header is left empty when count is zero. The header clock is visible again on all other pages as before.\r\n\r\n  On e-ink displays (E213, Wireless Paper, E290), the clock is rendered in a large font; pairing pin or connection status appears at the bottom-left, and the date at the bottom-right. On OLED and T096, the layout is: large clock → date → connection status, stacked top to bottom.\r\n\r\n  Before the clock is synchronized with the app or GPS, the display shows uptime counting up from `00:00` since boot, consistent with the small header clock.\r\n\r\n- **Repeater/Room Server: flood hop limits now correctly ignore leading-zero path padding.**\r\n\r\n  Some senders limit how far a packet propagates by pre-filling the path with zero entries — a TTL trick used by custom firmware, and by companions in this firmware via `ch.hops`. Previously, repeaters counted these zeros as real relay hops, causi\n…",
          "notesHtml": "<h3>v1.16_0614</h3>\n<ul>\n<li><p><strong>New devices: Heltec Vision Master E213, Wireless Paper, and Vision Master E290 — full e-ink companion support (Companion, Repeater, Room Server).</strong></p>\n<p>Three e-ink boards are now fully supported with the complete companion UI — Quick Send, Contacts, Settings, Saved Locations, GPS Trace, and message preview. Repeater and Room Server firmware are provided for all three.</p>\n<ul>\n<li><strong>Heltec Vision Master E213</strong> <em>(author-tested, v1.1.1)</em>  — ESP32-S3 with a 2.13\" e-ink display (250×122 px), SX1262 LoRa, and a QuickLink I2C port. Has a second user button (GPIO21): press to scroll up in any list, or to go back — faster than double clicking the main button.</li>\n<li><strong>Heltec Wireless Paper</strong> — ESP32-S3 with the same 2.13\" e-ink panel as the E213 in a more compact form factor. Shares the same companion UI and firmware variants as the E213. Single button only.</li>\n<li><strong>Heltec Vision Master E290</strong> — ESP32-S3R8 with a larger 2.9\" e-ink display (296×128 px), SX1262 LoRa, and a QuickLink I2C port. Also has a second button (GPIO21) like the E213. The companion UI adapts automatically to the wider panel — more message lines and a larger clock on the Home screen.</li>\n</ul>\n<p><strong>Common characteristics across all three e-ink boards:</strong></p>\n<ul>\n<li><strong>Always-on display</strong> — e-ink retains content indefinitely without power; no screen timeout.</li>\n<li><strong>Native multilingual text</strong> — Latin, Cyrillic, and Greek scripts render natively.</li>\n<li><strong>Font Weight setting</strong> — choose between <strong>Thin</strong> and <strong>Bold</strong> via <strong>Settings → Font Weight</strong>. Preference is saved to flash.</li>\n<li><strong>I2C sensor support</strong> — environment sensors can be connected via the QuickLink I2C port.</li>\n</ul>\n</li>\n<li><p><strong>Companion: unified BLE / USB / WiFi connection mode for all ESP32-S3 boards.</strong></p>\n<p>All ESP32-S3 companion builds (Heltec V3, V4, E213, Wireless Paper, E290, XIAO S3) now ship as a single unified firmware image that supports all three connection transports: <strong>BLE</strong>, <strong>USB serial</strong>, and <strong>WiFi TCP</strong>. The active mode is saved to flash and selected at boot — no per-mode build is needed.</p>\n<p>Switching is done via <strong>Settings → Connection Mode</strong>, which opens a direct selection screen listing all three modes with the current one marked <code>*</code>. Navigate to the desired mode and confirm — the device reboots into the new mode.</p>\n<p>Alternatively, switch via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>: <code>set conn.mode wifi|ble|usb</code>. WiFi credentials are configured with <code>set wifi.ssid</code> / <code>set wifi.password</code>, or from the <strong>OTA update page</strong> which now includes a WiFi credentials form alongside the firmware upload button.</p>\n<p>In WiFi mode, the node connects as a STA to your router and the Home screen shows the IP address and port. All three modes meet the low-power criteria of this repo.  </p>\n</li>\n<li><p><strong>Companion UI: Home screen always shows a large clock; message count shown in the header.</strong></p>\n<p>The center of the Home screen now always shows the current time (<code>HH:MM</code>) in a large font — <code>MSG: N</code> is gone. If there are messages stored in memory, their count and a small envelope icon appear in the header (where the small clock used to be); the header is left empty when count is zero. The header clock is visible again on all other pages as before.</p>\n<p>On e-ink displays (E213, Wireless Paper, E290), the clock is rendered in a large font; pairing pin or connection status appears at the bottom-left, and the date at the bottom-right. On OLED and T096, the layout is: large clock → date → connection status, stacked top to bottom.</p>\n<p>Before the clock is synchronized with the app or GPS, the display shows uptime counting up from <code>00:00</code> since boot, consistent with the small header clock.</p>\n</li>\n<li><p><strong>Repeater/Room Server: flood hop limits now correctly ignore leading-zero path padding.</strong></p>\n<p>Some senders limit how far a packet propagates by pre-filling the path with zero entries — a TTL trick used by custom firmware, and by companions in this firmware via <code>ch.hops</code>. Previously, repeaters counted these zeros as real relay hops, causi\n…</p>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.16.dev_0607",
          "name": "MeshCore low power - v1.16.dev_0607",
          "datetime": "2026-06-07T05:01:31Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.16.dev_0607",
          "prerelease": false,
          "notes": "### v1.16_0607\r\n\r\n- **Companion UI: Native multilingual display on Heltec T096 (ST7735S)**\r\n\r\n  Node names and messages now render natively on the T096 color TFT — characters are displayed as-is instead of being converted to ASCII equivalents. Supported languages include all 31 from v1.14 plus additional scripts:\r\n\r\n  **Latin-based:** Catalan, Croatian, Czech, Danish, Dutch, Estonian, Finnish, French, German, Hungarian, Icelandic, Italian, Latvian, Lithuanian, Maltese, Norwegian, Polish, Portuguese, Romanian, Slovak, Slovenian, Spanish, Swedish, Turkish, Vietnamese, Welsh\r\n\r\n  **Cyrillic:** Belarusian, Bulgarian, Macedonian, Russian, Serbian, Ukrainian\r\n\r\n  **Greek:** Greek\r\n\r\n- **Companion UI: Contacts screen now includes room servers; request telemetry from any contact.**\r\n\r\n  Room servers appear in the contact list tagged `[R]`. Selecting any contact — chat node or room server — and long pressing opens an action menu: **Send message** or **Request telemetry**. Requesting telemetry displays the node's battery voltage and GPS coordinates (if present); long press to open the GPS Trace screen for that location.\r\n\r\n  GPS coordinates follow the **Pos. Format** selected in Settings (DD, UTM, or MGRS).\r\n\r\n  The message inbox group list now tags group/channel entries with `[G]` and room server entries with `[R]` for consistent visual distinction. Each room message shows the original author's name. When viewing a room message, long press to open the popup and select **Reply** to post back to the room (visible to all subscribers).\r\n\r\n  > **Private room servers:** messaging requires a prior login. Public rooms (no password) work without any login. For private rooms, log in once via the MeshCore app — if your account has admin rights on that room server, the session persists across reboots. Regular user sessions are not saved to flash and will require re-login after the room server reboots.\r\n\r\n- **Companion: switch the app connection between BLE and USB serial without reflashing.**\r\n\r\n  In USB mode the node behaves like a standard `usb` build — the PC app connects over the USB serial port directly. Toggle via **Settings → Connection Mode** on the display, or via TerminalCLI: `set conn.mode usb` / `set conn.mode ble`. The setting persists across reboots. BLE toggle is hidden in the Settings menu while USB mode is active.\r\n\r\n- **Repeater, Room Sever: hold user button 5 seconds to power off.**\r\n\r\n  Hold the user button for 5 seconds to power off the node — faster than reaching for the CLI when you're standing next to it. The LED blinks 5 times as a warning before shutdown.\r\n\r\n- **Repeater, Room Server: `advert.hops.max` default changed to 8; room server support added; `flood.max.advert` alias.**\r\n\r\n  `advert.hops.max` now defaults to `8` instead of `flood.max` — advert relay limiting is active out of the box without any configuration. Room servers now also enforce this limit (previously repeater-only). The command `flood.max.advert` is accepted as an alias for compatibility with upstream firmware.",
          "notesHtml": "<h3>v1.16_0607</h3>\n<ul>\n<li><p><strong>Companion UI: Native multilingual display on Heltec T096 (ST7735S)</strong></p>\n<p>Node names and messages now render natively on the T096 color TFT — characters are displayed as-is instead of being converted to ASCII equivalents. Supported languages include all 31 from v1.14 plus additional scripts:</p>\n<p><strong>Latin-based:</strong> Catalan, Croatian, Czech, Danish, Dutch, Estonian, Finnish, French, German, Hungarian, Icelandic, Italian, Latvian, Lithuanian, Maltese, Norwegian, Polish, Portuguese, Romanian, Slovak, Slovenian, Spanish, Swedish, Turkish, Vietnamese, Welsh</p>\n<p><strong>Cyrillic:</strong> Belarusian, Bulgarian, Macedonian, Russian, Serbian, Ukrainian</p>\n<p><strong>Greek:</strong> Greek</p>\n</li>\n<li><p><strong>Companion UI: Contacts screen now includes room servers; request telemetry from any contact.</strong></p>\n<p>Room servers appear in the contact list tagged <code>[R]</code>. Selecting any contact — chat node or room server — and long pressing opens an action menu: <strong>Send message</strong> or <strong>Request telemetry</strong>. Requesting telemetry displays the node's battery voltage and GPS coordinates (if present); long press to open the GPS Trace screen for that location.</p>\n<p>GPS coordinates follow the <strong>Pos. Format</strong> selected in Settings (DD, UTM, or MGRS).</p>\n<p>The message inbox group list now tags group/channel entries with <code>[G]</code> and room server entries with <code>[R]</code> for consistent visual distinction. Each room message shows the original author's name. When viewing a room message, long press to open the popup and select <strong>Reply</strong> to post back to the room (visible to all subscribers).</p>\n<blockquote>\n<p><strong>Private room servers:</strong> messaging requires a prior login. Public rooms (no password) work without any login. For private rooms, log in once via the MeshCore app — if your account has admin rights on that room server, the session persists across reboots. Regular user sessions are not saved to flash and will require re-login after the room server reboots.</p>\n</blockquote>\n</li>\n<li><p><strong>Companion: switch the app connection between BLE and USB serial without reflashing.</strong></p>\n<p>In USB mode the node behaves like a standard <code>usb</code> build — the PC app connects over the USB serial port directly. Toggle via <strong>Settings → Connection Mode</strong> on the display, or via TerminalCLI: <code>set conn.mode usb</code> / <code>set conn.mode ble</code>. The setting persists across reboots. BLE toggle is hidden in the Settings menu while USB mode is active.</p>\n</li>\n<li><p><strong>Repeater, Room Sever: hold user button 5 seconds to power off.</strong></p>\n<p>Hold the user button for 5 seconds to power off the node — faster than reaching for the CLI when you're standing next to it. The LED blinks 5 times as a warning before shutdown.</p>\n</li>\n<li><p><strong>Repeater, Room Server: <code>advert.hops.max</code> default changed to 8; room server support added; <code>flood.max.advert</code> alias.</strong></p>\n<p><code>advert.hops.max</code> now defaults to <code>8</code> instead of <code>flood.max</code> — advert relay limiting is active out of the box without any configuration. Room servers now also enforce this limit (previously repeater-only). The command <code>flood.max.advert</code> is accepted as an alias for compatibility with upstream firmware.</p>\n</li>\n</ul>\n"
        },
        {
          "version": "pre-release-Heltec-E213-Wireless-Paper-E290",
          "name": "pre-release Heltec E213, Wireless Paper, E290",
          "datetime": "2026-06-11T11:45:39Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/pre-release-Heltec-E213-Wireless-Paper-E290",
          "prerelease": true,
          "notes": "### v1.16_0611 pre-release for Heltec E213, Wireless Paper and E290\r\n\r\n- **New device: Heltec Vision Master E213 — full support (Companion, Repeater, Room Server).**\r\n\r\n  The Heltec Vision Master E213 is now fully supported. It is an ESP32-S3 based board with a 2.13\" e-ink display, SX1262 LoRa radio, and a USB-C port. The complete companion UI runs on the e-ink display — Quick Send, Contacts, Settings, Saved Locations, GPS Trace, and message preview. Repeater and Room Server firmware are also provided.\r\n\r\n  **Notable characteristics:**\r\n  - **Always-on e-ink display** — no screen timeout; the display retains its content indefinitely without power.\r\n  - **Native multilingual text** — Latin, Cyrillic, and Greek scripts render natively.\r\n  - **I2C sensor support** — environment sensors (temperature, humidity, pressure...) can be connected via the QuickLink I2C port.\r\n  - **Two user buttons** — the second button (GPIO21) makes navigation faster: press it to scroll up in any list, or to go back/exit any menu.\r\n\r\n- **New devices: Heltec Wireless Paper and Heltec Vision Master E290 — full support (Companion, Repeater, Room Server).**\r\n\r\n  Two new e-ink boards are now supported:\r\n\r\n  - **Heltec Wireless Paper** — ESP32-S3 with a 2.13\" e-ink display (same resolution as E213), SX1262 LoRa radio, and a compact form factor. Shares the same companion UI and firmware variants as E213.\r\n\r\n  - **Heltec Vision Master E290** — ESP32-S3R8 with a larger 2.9\" e-ink display (296×128), SX1262 LoRa radio, and a QuickLink I2C port for external sensors. The companion UI adapts automatically to the wider, taller display — showing more message lines and better-spaced layouts compared to the 2.13\" boards.",
          "notesHtml": "<h3>v1.16_0611 pre-release for Heltec E213, Wireless Paper and E290</h3>\n<ul>\n<li><p><strong>New device: Heltec Vision Master E213 — full support (Companion, Repeater, Room Server).</strong></p>\n<p>The Heltec Vision Master E213 is now fully supported. It is an ESP32-S3 based board with a 2.13\" e-ink display, SX1262 LoRa radio, and a USB-C port. The complete companion UI runs on the e-ink display — Quick Send, Contacts, Settings, Saved Locations, GPS Trace, and message preview. Repeater and Room Server firmware are also provided.</p>\n<p><strong>Notable characteristics:</strong></p>\n<ul>\n<li><strong>Always-on e-ink display</strong> — no screen timeout; the display retains its content indefinitely without power.</li>\n<li><strong>Native multilingual text</strong> — Latin, Cyrillic, and Greek scripts render natively.</li>\n<li><strong>I2C sensor support</strong> — environment sensors (temperature, humidity, pressure...) can be connected via the QuickLink I2C port.</li>\n<li><strong>Two user buttons</strong> — the second button (GPIO21) makes navigation faster: press it to scroll up in any list, or to go back/exit any menu.</li>\n</ul>\n</li>\n<li><p><strong>New devices: Heltec Wireless Paper and Heltec Vision Master E290 — full support (Companion, Repeater, Room Server).</strong></p>\n<p>Two new e-ink boards are now supported:</p>\n<ul>\n<li><p><strong>Heltec Wireless Paper</strong> — ESP32-S3 with a 2.13\" e-ink display (same resolution as E213), SX1262 LoRa radio, and a compact form factor. Shares the same companion UI and firmware variants as E213.</p>\n</li>\n<li><p><strong>Heltec Vision Master E290</strong> — ESP32-S3R8 with a larger 2.9\" e-ink display (296×128), SX1262 LoRa radio, and a QuickLink I2C port for external sensors. The companion UI adapts automatically to the wider, taller display — showing more message lines and better-spaced layouts compared to the 2.13\" boards.</p>\n</li>\n</ul>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.15.dev_0531",
          "name": "MeshCore low power - v1.15.dev_0531",
          "datetime": "2026-05-31T02:29:03Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.15.dev_0531",
          "prerelease": false,
          "notes": "### v1.15_0531\r\n\r\n- **Full support for Heltec T096 — companion, repeater, and room server**\r\n\r\n  The Heltec T096 is now fully supported across all node types. The hardware is an nRF52840-based board with an SX1262 radio, KCT8103L FEM, UC6580 GPS, and a 0.96\" 160×80 color TFT display (ST7735S).\r\n\r\n  The complete companion UI — Quick Send, Contacts, Settings, GPS, Saved Locations, GPS Trace, and message preview — runs on the color TFT.\r\n\r\n  **Differences from other supported boards:**\r\n\r\n  - **Color TFT display.** All companion pages render in color on the 160×80 ST7735S — unlike other supported boards which use a monochrome OLED.\r\n\r\n  - **Brightness control.** A **Brightness** item in the Settings page adjusts the TFT backlight intensity: `25` → `50` → `75` → `100`. Setting is saved to flash.\r\n\r\n  - **KCT8103L FEM — same as Heltec V4.3.** `set radio.rxgain on` / `off` works identically.\r\n\r\n  - **UC6580 GPS.** `gps.interval` works the same as on Heltec V4. Constellation selection (`gps.mode`) uses a different set of options:\r\n\r\n    | Value | Constellations |\r\n    |---|---|\r\n    | `1` | GPS L1 only |\r\n    | `2` | All-system L1 (GPS+BDS+GLO+GAL) |\r\n    | `3` | All-system + QZSS dual-band *(default)* |\r\n\r\n- **AGC auto-reset improvements (all node types).**\r\n\r\n  Coordination between AGC auto-reset and channel busy detection has been improved. While the noise floor baseline is being re-established after a reset, channel sensing falls back to hardware CAD only.\r\n\r\n- **Fix: excessive flash writes on nRF52 Companion (T096, RAK4631).**\r\n\r\n  Each received advertisement previously triggered an immediate flash write — both to the advert blob store and to the contact list. In areas with high advert traffic this caused unnecessary flash wear, and a malicious node spamming adverts could wear out ExtraFS in hours. Advert blobs are now buffered in RAM and flushed to flash at most once every 10 minutes. Auto-discovered contacts use the same 10-minute pattern instead of a short debounce timer.",
          "notesHtml": "<h3>v1.15_0531</h3>\n<ul>\n<li><p><strong>Full support for Heltec T096 — companion, repeater, and room server</strong></p>\n<p>The Heltec T096 is now fully supported across all node types. The hardware is an nRF52840-based board with an SX1262 radio, KCT8103L FEM, UC6580 GPS, and a 0.96\" 160×80 color TFT display (ST7735S).</p>\n<p>The complete companion UI — Quick Send, Contacts, Settings, GPS, Saved Locations, GPS Trace, and message preview — runs on the color TFT.</p>\n<p><strong>Differences from other supported boards:</strong></p>\n<ul>\n<li><p><strong>Color TFT display.</strong> All companion pages render in color on the 160×80 ST7735S — unlike other supported boards which use a monochrome OLED.</p>\n</li>\n<li><p><strong>Brightness control.</strong> A <strong>Brightness</strong> item in the Settings page adjusts the TFT backlight intensity: <code>25</code> → <code>50</code> → <code>75</code> → <code>100</code>. Setting is saved to flash.</p>\n</li>\n<li><p><strong>KCT8103L FEM — same as Heltec V4.3.</strong> <code>set radio.rxgain on</code> / <code>off</code> works identically.</p>\n</li>\n<li><p><strong>UC6580 GPS.</strong> <code>gps.interval</code> works the same as on Heltec V4. Constellation selection (<code>gps.mode</code>) uses a different set of options:</p>\n<table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Constellations</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>1</code></td>\n<td>GPS L1 only</td>\n</tr>\n<tr>\n<td><code>2</code></td>\n<td>All-system L1 (GPS+BDS+GLO+GAL)</td>\n</tr>\n<tr>\n<td><code>3</code></td>\n<td>All-system + QZSS dual-band <em>(default)</em></td>\n</tr>\n</tbody></table>\n</li>\n</ul>\n</li>\n<li><p><strong>AGC auto-reset improvements (all node types).</strong></p>\n<p>Coordination between AGC auto-reset and channel busy detection has been improved. While the noise floor baseline is being re-established after a reset, channel sensing falls back to hardware CAD only.</p>\n</li>\n<li><p><strong>Fix: excessive flash writes on nRF52 Companion (T096, RAK4631).</strong></p>\n<p>Each received advertisement previously triggered an immediate flash write — both to the advert blob store and to the contact list. In areas with high advert traffic this caused unnecessary flash wear, and a malicious node spamming adverts could wear out ExtraFS in hours. Advert blobs are now buffered in RAM and flushed to flash at most once every 10 minutes. Auto-discovered contacts use the same 10-minute pattern instead of a short debounce timer.</p>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.15.dev_0524",
          "name": "MeshCore low power - v1.15.dev_0524",
          "datetime": "2026-05-24T01:53:36Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.15.dev_0524",
          "prerelease": false,
          "notes": "### v1.15_0524\r\n\r\n- **Fix: radio deafness recovery in noisy environments (all node types).**\r\n\r\n  When strong in-band interference causes the SX1262 AGC to become overwhelmed, the radio can go deaf — severely degraded in receive sensitivity. The firmware now detects this condition automatically and triggers an immediate hardware recalibration, restoring sensitivity without waiting for the scheduled `agc.reset.interval`. The `agc.reset.interval` setting remains available but is now unnecessary.\r\n\r\n  Two new commands let you monitor and reset the AGC reset counter:\r\n\r\n  | Command | Effect |\r\n  |---------|--------|\r\n  | `get agc.resets` | Show how many times the AGC has been auto-reset since boot or last `clear` |\r\n  | `clear agc.resets` | Reset the counter to zero |\r\n\r\n  **Real-world validation:** A repeater installed near a periodic in-band interference source (confirmed via RTL-SDR) accumulated 918 auto-resets over 8.5 hours (~1.8/min), matching the observed interference sweep cycle. A second repeater at a clean location recorded 0 resets over the same period, confirming no false positives. Without this feature, the first repeater was unreachable remotely due to persistent deafness.\r\n\r\n- **GPS update interval configurable at runtime on Heltec V4 (all node types).**\r\n\r\n  A new `gps.interval` setting controls the sleep time between GPS position updates. After each fix, GPS powers down for the configured interval, then wakes and acquires a new fix. Set it to `0` to keep GPS always on. Default is 10 seconds.\r\n\r\n  Available on **Companion** via [TerminalCLI](Companion_TerminalCLI_Commands.md) and on **Repeater / Room Server** via the Command Line:\r\n\r\n  | Command | Effect |\r\n  |---|---|\r\n  | `get gps.interval` | Show current interval (`always on` if 0) |\r\n  | `set gps.interval 0` | GPS always on — maximum accuracy, highest power draw |\r\n  | `set gps.interval 30` | GPS sleeps 30s after each fix, then re-acquires |\r\n  | `set gps.interval 300` | GPS sleeps 5 minutes after each fix |\r\n\r\n  Setting is saved to flash and takes effect immediately — no reboot needed.\r\n\r\n- **GPS constellation selection for L78K on Heltec V4 (`gps.mode`) (all node types).**\r\n\r\n  Choose which satellite constellations the L78K module tracks. Average current draw is essentially the same across all configurations in duty cycle mode with `gps.interval` greater than 10 (~23 mA mean current measured on Heltec V4.3 Companion with `gps.mode = 4` and `gps.interval = 10`). Leave at the default `4` for the most robust fix; adjust only if you have a specific coverage reason.\r\n\r\n  | Value | Constellations |\r\n  |---|---|\r\n  | `1` | GPS only |\r\n  | `2` | GPS + BeiDou |\r\n  | `3` | GPS + GLONASS |\r\n  | `4` | GPS + BeiDou + GLONASS *(default)* |\r\n\r\n  Available on **Companion** via [TerminalCLI](Companion_TerminalCLI_Commands.md) and on **Repeater / Room Server** via the Command Line:\r\n\r\n  | Command | Effect |\r\n  |---|---|\r\n  | `get gps.mode` | Show current constellation selection |\r\n  | `set gps.mode 4` | GPS + BeiDou + GLONASS (default) |\r\n  | `set gps.mode 1` | GPS only |\r\n\r\n  Setting is saved to flash. Change takes effect on next GPS on.\r\n\r\n- **Companion: GPS screen shows interval and constellation when GPS is off.**\r\n\r\n  When GPS is off, the GPS page now shows the configured update interval (`intv`) and constellation selection (`mode`, Heltec V4 only), so you can verify settings before enabling GPS.",
          "notesHtml": "<h3>v1.15_0524</h3>\n<ul>\n<li><p><strong>Fix: radio deafness recovery in noisy environments (all node types).</strong></p>\n<p>When strong in-band interference causes the SX1262 AGC to become overwhelmed, the radio can go deaf — severely degraded in receive sensitivity. The firmware now detects this condition automatically and triggers an immediate hardware recalibration, restoring sensitivity without waiting for the scheduled <code>agc.reset.interval</code>. The <code>agc.reset.interval</code> setting remains available but is now unnecessary.</p>\n<p>Two new commands let you monitor and reset the AGC reset counter:</p>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>get agc.resets</code></td>\n<td>Show how many times the AGC has been auto-reset since boot or last <code>clear</code></td>\n</tr>\n<tr>\n<td><code>clear agc.resets</code></td>\n<td>Reset the counter to zero</td>\n</tr>\n</tbody></table>\n<p><strong>Real-world validation:</strong> A repeater installed near a periodic in-band interference source (confirmed via RTL-SDR) accumulated 918 auto-resets over 8.5 hours (~1.8/min), matching the observed interference sweep cycle. A second repeater at a clean location recorded 0 resets over the same period, confirming no false positives. Without this feature, the first repeater was unreachable remotely due to persistent deafness.</p>\n</li>\n<li><p><strong>GPS update interval configurable at runtime on Heltec V4 (all node types).</strong></p>\n<p>A new <code>gps.interval</code> setting controls the sleep time between GPS position updates. After each fix, GPS powers down for the configured interval, then wakes and acquires a new fix. Set it to <code>0</code> to keep GPS always on. Default is 10 seconds.</p>\n<p>Available on <strong>Companion</strong> via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a> and on <strong>Repeater / Room Server</strong> via the Command Line:</p>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>get gps.interval</code></td>\n<td>Show current interval (<code>always on</code> if 0)</td>\n</tr>\n<tr>\n<td><code>set gps.interval 0</code></td>\n<td>GPS always on — maximum accuracy, highest power draw</td>\n</tr>\n<tr>\n<td><code>set gps.interval 30</code></td>\n<td>GPS sleeps 30s after each fix, then re-acquires</td>\n</tr>\n<tr>\n<td><code>set gps.interval 300</code></td>\n<td>GPS sleeps 5 minutes after each fix</td>\n</tr>\n</tbody></table>\n<p>Setting is saved to flash and takes effect immediately — no reboot needed.</p>\n</li>\n<li><p><strong>GPS constellation selection for L78K on Heltec V4 (<code>gps.mode</code>) (all node types).</strong></p>\n<p>Choose which satellite constellations the L78K module tracks. Average current draw is essentially the same across all configurations in duty cycle mode with <code>gps.interval</code> greater than 10 (~23 mA mean current measured on Heltec V4.3 Companion with <code>gps.mode = 4</code> and <code>gps.interval = 10</code>). Leave at the default <code>4</code> for the most robust fix; adjust only if you have a specific coverage reason.</p>\n<table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Constellations</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>1</code></td>\n<td>GPS only</td>\n</tr>\n<tr>\n<td><code>2</code></td>\n<td>GPS + BeiDou</td>\n</tr>\n<tr>\n<td><code>3</code></td>\n<td>GPS + GLONASS</td>\n</tr>\n<tr>\n<td><code>4</code></td>\n<td>GPS + BeiDou + GLONASS <em>(default)</em></td>\n</tr>\n</tbody></table>\n<p>Available on <strong>Companion</strong> via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a> and on <strong>Repeater / Room Server</strong> via the Command Line:</p>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>get gps.mode</code></td>\n<td>Show current constellation selection</td>\n</tr>\n<tr>\n<td><code>set gps.mode 4</code></td>\n<td>GPS + BeiDou + GLONASS (default)</td>\n</tr>\n<tr>\n<td><code>set gps.mode 1</code></td>\n<td>GPS only</td>\n</tr>\n</tbody></table>\n<p>Setting is saved to flash. Change takes effect on next GPS on.</p>\n</li>\n<li><p><strong>Companion: GPS screen shows interval and constellation when GPS is off.</strong></p>\n<p>When GPS is off, the GPS page now shows the configured update interval (<code>intv</code>) and constellation selection (<code>mode</code>, Heltec V4 only), so you can verify settings before enabling GPS.</p>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.15.dev_0517",
          "name": "MeshCore low power - v1.15.dev_0517",
          "datetime": "2026-05-17T03:19:48Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.15.dev_0517",
          "prerelease": false,
          "notes": "### v1.15_0517\r\n\r\n- **Companion: per-channel outgoing hop limit (`ch.hops`).**\r\n\r\n  Limit how far your outgoing messages travel on a specific channel, without affecting any other channel or any other node in the network. Useful for keeping a private or local-area channel confined to a small radius — for example, a home-to-nearby-relay link — without touching the rest of the city mesh.\r\n\r\n  Configure via **TerminalCLI**:\r\n\r\n  | Command | Effect |\r\n  |---|---|\r\n  | `set ch.hops <channel> <N>` | Limit outgoing messages on `<channel>` to at most N hops |\r\n  | `set ch.hops <channel> off` | Remove the limit |\r\n  | `get ch.hops <channel>` | Show current limit |\r\n  | `ch.hops status` | List all channels with an active limit |\r\n  | `ch.hops clear` | Remove all limits |\r\n\r\n  ```\r\n  set ch.hops Public 2         # Public channel messages travel at most 2 hops\r\n  set ch.hops My Local Net 3   # My Local Net channel travel at most 3 hops\r\n  set ch.hops Public off       # remove the limit\r\n  ch.hops status\r\n  ```\r\n\r\n\r\n  The limit applies to **your outgoing messages only** — other nodes sending on the same channel are unaffected. No repeater configuration or network coordination required.\r\n\r\n  The repeater's `group.hops.max` algorithm has been updated to correctly account for sender-side pre-fill, so `ch.hops` and `group.hops.max` work together without conflict — update repeater firmware to get full compatibility.\r\n\r\n  Settings are stored in flash and persist after reboot.\r\n\r\n- **Companion: toggle RxGain directly from the Radio screen.**\r\n\r\n  Long press on the **Radio** page cycles through RxGain modes (OFF → ON → Auto) and shows a popup confirming the new mode. The current mode is now also displayed on the Radio page itself (`RxG: OFF` / `RxG: ON` / `RxG: Auto`), so you can check it at a glance without going into Settings. *(`Auto` is available on Heltec V4.2 only.)*\r\n\r\n- **Fix: noise floor stuck at -120 in noisy environments (all node types)**\r\n\r\n  In environments with strong in-band interference, the noise floor could remain at -120 dBm for a long time instead of updating to reflect actual conditions. Fixed.",
          "notesHtml": "<h3>v1.15_0517</h3>\n<ul>\n<li><p><strong>Companion: per-channel outgoing hop limit (<code>ch.hops</code>).</strong></p>\n<p>Limit how far your outgoing messages travel on a specific channel, without affecting any other channel or any other node in the network. Useful for keeping a private or local-area channel confined to a small radius — for example, a home-to-nearby-relay link — without touching the rest of the city mesh.</p>\n<p>Configure via <strong>TerminalCLI</strong>:</p>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>set ch.hops &lt;channel&gt; &lt;N&gt;</code></td>\n<td>Limit outgoing messages on <code>&lt;channel&gt;</code> to at most N hops</td>\n</tr>\n<tr>\n<td><code>set ch.hops &lt;channel&gt; off</code></td>\n<td>Remove the limit</td>\n</tr>\n<tr>\n<td><code>get ch.hops &lt;channel&gt;</code></td>\n<td>Show current limit</td>\n</tr>\n<tr>\n<td><code>ch.hops status</code></td>\n<td>List all channels with an active limit</td>\n</tr>\n<tr>\n<td><code>ch.hops clear</code></td>\n<td>Remove all limits</td>\n</tr>\n</tbody></table>\n<pre><code>set ch.hops Public 2         # Public channel messages travel at most 2 hops\nset ch.hops My Local Net 3   # My Local Net channel travel at most 3 hops\nset ch.hops Public off       # remove the limit\nch.hops status\n</code></pre>\n<p>The limit applies to <strong>your outgoing messages only</strong> — other nodes sending on the same channel are unaffected. No repeater configuration or network coordination required.</p>\n<p>The repeater's <code>group.hops.max</code> algorithm has been updated to correctly account for sender-side pre-fill, so <code>ch.hops</code> and <code>group.hops.max</code> work together without conflict — update repeater firmware to get full compatibility.</p>\n<p>Settings are stored in flash and persist after reboot.</p>\n</li>\n<li><p><strong>Companion: toggle RxGain directly from the Radio screen.</strong></p>\n<p>Long press on the <strong>Radio</strong> page cycles through RxGain modes (OFF → ON → Auto) and shows a popup confirming the new mode. The current mode is now also displayed on the Radio page itself (<code>RxG: OFF</code> / <code>RxG: ON</code> / <code>RxG: Auto</code>), so you can check it at a glance without going into Settings. <em>(<code>Auto</code> is available on Heltec V4.2 only.)</em></p>\n</li>\n<li><p><strong>Fix: noise floor stuck at -120 in noisy environments (all node types)</strong></p>\n<p>In environments with strong in-band interference, the noise floor could remain at -120 dBm for a long time instead of updating to reflect actual conditions. Fixed.</p>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.15.dev_0510",
          "name": "MeshCore low power - v1.15.dev_0510",
          "datetime": "2026-05-10T02:47:22Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.15.dev_0510",
          "prerelease": false,
          "notes": "### v1.15_0510\r\n\r\n- **Repeater: per-type relay hop cap (`advert.hops.max` / `group.hops.max`).**\r\n\r\n  Two new settings let you independently limit how far **advertisement packets** and **group messages** are relayed across the mesh, without affecting direct messages, ACKs, or path discovery.\r\n\r\n  | Setting | Controls | Default |\r\n  |---|---|---|\r\n  | `advert.hops.max` | Max hops to relay node advertisement (ADVERT) packets | = `flood.max` |\r\n  | `group.hops.max` | Max hops to relay group messages (GRP_TXT / GRP_DATA) | = `flood.max` |\r\n\r\n  These are **repeater-only** settings. Configure via the **Command Line** in the MeshCore App:\r\n  ```\r\n  set advert.hops.max 3    # relay adverts at most 3 hops from sender\r\n  set group.hops.max 5     # relay group messages at most 5 hops\r\n  get advert.hops.max\r\n  get group.hops.max\r\n  ```\r\n\r\n  Setting either value to `0` completely suppresses that packet type — no relay at all, while everything else (DM, ACK, path) continues to work normally.\r\n\r\n  **Why this matters — advert storm reduction:**\r\n\r\n  Each repeater periodically broadcasts an advertisement that every other repeater in range relays, up to `flood.max` times (default 64). In a network of 35 repeaters and 35 companions, advert traffic alone consumes roughly 4% of airtime. Limiting to 3 hops brings that down to under 0.5% — a 7× reduction — with no loss of communication capability.  \r\n\r\n  **No coordination required.** Each repeater applies its own cap independently. You do not need all repeaters to agree on the same value — even a partial deployment reduces airtime. No region configuration, no App UI changes needed.\r\n\r\n  **Recommended profiles:**\r\n\r\n  | Profile | `advert.hops.max` | `group.hops.max` | Airtime (35R / 35C) | Use case |\r\n  |---|---|---|---|---|\r\n  | Default | = `flood.max` | = `flood.max` | ~4% | No change |\r\n  | Optimized | 3 | 5 | ~0.5% | Most deployments |\r\n  | DM-focused | 0 | 3 | ~0.2% | Prioritise direct messages |\r\n  | EU compliance | 0 | 3 | ~0.2% | Large EU networks (legal requirement) |\r\n\r\n  > **Relationship with `flood.max` and path hash size:** `flood.max` is the master hop cap for **all** flood payloads. Its default of 64 is calibrated for 1-byte path hash mode. With larger hashes the packet fills up sooner — 2-byte hash caps at 32 hops, 3-byte hash caps at 21 hops — so `flood.max` is typically set to match. `advert.hops.max` and `group.hops.max` are automatically clamped to `flood.max` and work correctly with all hash sizes. If you want to suppress adverts entirely while keeping everything else unrestricted, set `advert.hops.max 0` — leave `flood.max` untouched.\r\n\r\n- **Repeater: combining hop caps with region scope for full community isolation.**\r\n\r\n  `advert.hops.max` and `group.hops.max` work standalone — no coordination needed. For operators who also want to restrict which community's group messages get relayed, combine them with region rules and the companion's scope settings:\r\n\r\n  1. Each companion sets a region scope — either per-channel via the burger menu, or globally via **Settings → Experimental → Default Region Scope**. All outgoing flood packets (including DM path discovery) are tagged with the community name.\r\n  2. Each repeater: `denyf *` + `allowf <community>` — only relay community-tagged traffic.\r\n  3. Add `set advert.hops.max 0` to also suppress advert relay.\r\n\r\n  With a global Default Region Scope, DM path discovery is tagged and passes through `denyf *` repeaters — direct messaging works normally inside the community.\r\n\r\n  > **Default Region Scope** is in the App's Experimental Settings and is opt-in. Per-channel scope (burger menu) only tags group messages for that channel, not advertisements or DM path discovery.\r\n\r\n- **Companion: GPS coordinate display formats — DD / UTM / MGRS.**\r\n\r\n  A new **Pos. Format** item in the Settings page lets you choose how GPS coordinates are shown on the GPS page, GPS Trace screen, and Quick Send status bar.\r\n\r\n  | Format | Example |\r\n  |---|---|\r\n  | D\n…",
          "notesHtml": "<h3>v1.15_0510</h3>\n<ul>\n<li><p><strong>Repeater: per-type relay hop cap (<code>advert.hops.max</code> / <code>group.hops.max</code>).</strong></p>\n<p>Two new settings let you independently limit how far <strong>advertisement packets</strong> and <strong>group messages</strong> are relayed across the mesh, without affecting direct messages, ACKs, or path discovery.</p>\n<table>\n<thead>\n<tr>\n<th>Setting</th>\n<th>Controls</th>\n<th>Default</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>advert.hops.max</code></td>\n<td>Max hops to relay node advertisement (ADVERT) packets</td>\n<td>= <code>flood.max</code></td>\n</tr>\n<tr>\n<td><code>group.hops.max</code></td>\n<td>Max hops to relay group messages (GRP_TXT / GRP_DATA)</td>\n<td>= <code>flood.max</code></td>\n</tr>\n</tbody></table>\n<p>These are <strong>repeater-only</strong> settings. Configure via the <strong>Command Line</strong> in the MeshCore App:</p>\n<pre><code>set advert.hops.max 3    # relay adverts at most 3 hops from sender\nset group.hops.max 5     # relay group messages at most 5 hops\nget advert.hops.max\nget group.hops.max\n</code></pre>\n<p>Setting either value to <code>0</code> completely suppresses that packet type — no relay at all, while everything else (DM, ACK, path) continues to work normally.</p>\n<p><strong>Why this matters — advert storm reduction:</strong></p>\n<p>Each repeater periodically broadcasts an advertisement that every other repeater in range relays, up to <code>flood.max</code> times (default 64). In a network of 35 repeaters and 35 companions, advert traffic alone consumes roughly 4% of airtime. Limiting to 3 hops brings that down to under 0.5% — a 7× reduction — with no loss of communication capability.  </p>\n<p><strong>No coordination required.</strong> Each repeater applies its own cap independently. You do not need all repeaters to agree on the same value — even a partial deployment reduces airtime. No region configuration, no App UI changes needed.</p>\n<p><strong>Recommended profiles:</strong></p>\n<table>\n<thead>\n<tr>\n<th>Profile</th>\n<th><code>advert.hops.max</code></th>\n<th><code>group.hops.max</code></th>\n<th>Airtime (35R / 35C)</th>\n<th>Use case</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Default</td>\n<td>= <code>flood.max</code></td>\n<td>= <code>flood.max</code></td>\n<td>~4%</td>\n<td>No change</td>\n</tr>\n<tr>\n<td>Optimized</td>\n<td>3</td>\n<td>5</td>\n<td>~0.5%</td>\n<td>Most deployments</td>\n</tr>\n<tr>\n<td>DM-focused</td>\n<td>0</td>\n<td>3</td>\n<td>~0.2%</td>\n<td>Prioritise direct messages</td>\n</tr>\n<tr>\n<td>EU compliance</td>\n<td>0</td>\n<td>3</td>\n<td>~0.2%</td>\n<td>Large EU networks (legal requirement)</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p><strong>Relationship with <code>flood.max</code> and path hash size:</strong> <code>flood.max</code> is the master hop cap for <strong>all</strong> flood payloads. Its default of 64 is calibrated for 1-byte path hash mode. With larger hashes the packet fills up sooner — 2-byte hash caps at 32 hops, 3-byte hash caps at 21 hops — so <code>flood.max</code> is typically set to match. <code>advert.hops.max</code> and <code>group.hops.max</code> are automatically clamped to <code>flood.max</code> and work correctly with all hash sizes. If you want to suppress adverts entirely while keeping everything else unrestricted, set <code>advert.hops.max 0</code> — leave <code>flood.max</code> untouched.</p>\n</blockquote>\n</li>\n<li><p><strong>Repeater: combining hop caps with region scope for full community isolation.</strong></p>\n<p><code>advert.hops.max</code> and <code>group.hops.max</code> work standalone — no coordination needed. For operators who also want to restrict which community's group messages get relayed, combine them with region rules and the companion's scope settings:</p>\n<ol>\n<li>Each companion sets a region scope — either per-channel via the burger menu, or globally via <strong>Settings → Experimental → Default Region Scope</strong>. All outgoing flood packets (including DM path discovery) are tagged with the community name.</li>\n<li>Each repeater: <code>denyf *</code> + <code>allowf &lt;community&gt;</code> — only relay community-tagged traffic.</li>\n<li>Add <code>set advert.hops.max 0</code> to also suppress advert relay.</li>\n</ol>\n<p>With a global Default Region Scope, DM path discovery is tagged and passes through <code>denyf *</code> repeaters — direct messaging works normally inside the community.</p>\n<blockquote>\n<p><strong>Default Region Scope</strong> is in the App's Experimental Settings and is opt-in. Per-channel scope (burger menu) only tags group messages for that channel, not advertisements or DM path discovery.</p>\n</blockquote>\n</li>\n<li><p><strong>Companion: GPS coordinate display formats — DD / UTM / MGRS.</strong></p>\n<p>A new <strong>Pos. Format</strong> item in the Settings page lets you choose how GPS coordinates are shown on the GPS page, GPS Trace screen, and Quick Send status bar.</p>\n<table>\n<thead>\n<tr>\n<th>Format</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>D</td>\n<td></td>\n</tr>\n<tr>\n<td>…</td>\n<td></td>\n</tr>\n</tbody></table>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.15.dev_0426",
          "name": "MeshCore low power - v1.15.dev_0426",
          "datetime": "2026-04-26T04:49:25Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.15.dev_0426",
          "prerelease": false,
          "notes": "### v1.15_0426\r\n\r\n- **Companion: redesigned message preview.**\r\n\r\n  Messages are now grouped by sender or channel so you can read a conversation in one place instead of hunting through a mixed list.\r\n\r\n  From the **group list** you can scroll back through older messages from any sender or channel, including ones you've already read. Long press a group to open it.\r\n\r\n  When new messages arrive, you go straight to a **new messages view** that shows only the unread ones — from all senders and channels — one by one. Once you've read them all, a single click takes you home.\r\n\r\n  Long messages scroll one full page at a time with no overlap. Small arrows (`▲` / `▼`) appear at the corner of the screen to let you know there is more content above or below.\r\n\r\n- **Companion: reply directly from message preview.**\r\n\r\n  While reading any message, long press to open the menu. A new **Reply** option lets you send a preset message back without leaving the screen:\r\n\r\n  - If the message came from a contact, the reply goes to that contact as a private direct message.\r\n  - If the message came from a channel (Public, #SOS, or any other), the reply goes back to that same channel.\r\n\r\n  > **Note:** The **Quick Send** page always sends to the Public channel. Use Reply from the message preview when you want to respond to a specific contact or a non-Public channel.\r\n\r\n- **Companion: Contacts page and direct messaging.**\r\n\r\n  A new **Contacts** page sits between Quick Send and Saved Locations. Long press it to open the contact list, only chat-capable nodes are listed (repeaters, room servers and sensors are excluded — they cannot receive direct messages). Select a contact and long press to send them a direct message using your Quick Send presets.\r\n\r\n- **Companion: configurable Screen Off timeout in Settings.**\r\n\r\n  A new **Screen Off** item in the Settings page lets you choose how long the display stays on after the last button press: `15s` → `3min` → `Never`. Setting is saved to flash and persists after reboot.\r\n\r\n- **Companion: Flip Screen setting in Settings.**\r\n\r\n  A new **Flip Screen** toggle in the Settings page rotates the display 180°. Setting is saved to flash and persists after reboot.\r\n- **fix bugs**",
          "notesHtml": "<h3>v1.15_0426</h3>\n<ul>\n<li><p><strong>Companion: redesigned message preview.</strong></p>\n<p>Messages are now grouped by sender or channel so you can read a conversation in one place instead of hunting through a mixed list.</p>\n<p>From the <strong>group list</strong> you can scroll back through older messages from any sender or channel, including ones you've already read. Long press a group to open it.</p>\n<p>When new messages arrive, you go straight to a <strong>new messages view</strong> that shows only the unread ones — from all senders and channels — one by one. Once you've read them all, a single click takes you home.</p>\n<p>Long messages scroll one full page at a time with no overlap. Small arrows (<code>▲</code> / <code>▼</code>) appear at the corner of the screen to let you know there is more content above or below.</p>\n</li>\n<li><p><strong>Companion: reply directly from message preview.</strong></p>\n<p>While reading any message, long press to open the menu. A new <strong>Reply</strong> option lets you send a preset message back without leaving the screen:</p>\n<ul>\n<li>If the message came from a contact, the reply goes to that contact as a private direct message.</li>\n<li>If the message came from a channel (Public, #SOS, or any other), the reply goes back to that same channel.</li>\n</ul>\n<blockquote>\n<p><strong>Note:</strong> The <strong>Quick Send</strong> page always sends to the Public channel. Use Reply from the message preview when you want to respond to a specific contact or a non-Public channel.</p>\n</blockquote>\n</li>\n<li><p><strong>Companion: Contacts page and direct messaging.</strong></p>\n<p>A new <strong>Contacts</strong> page sits between Quick Send and Saved Locations. Long press it to open the contact list, only chat-capable nodes are listed (repeaters, room servers and sensors are excluded — they cannot receive direct messages). Select a contact and long press to send them a direct message using your Quick Send presets.</p>\n</li>\n<li><p><strong>Companion: configurable Screen Off timeout in Settings.</strong></p>\n<p>A new <strong>Screen Off</strong> item in the Settings page lets you choose how long the display stays on after the last button press: <code>15s</code> → <code>3min</code> → <code>Never</code>. Setting is saved to flash and persists after reboot.</p>\n</li>\n<li><p><strong>Companion: Flip Screen setting in Settings.</strong></p>\n<p>A new <strong>Flip Screen</strong> toggle in the Settings page rotates the display 180°. Setting is saved to flash and persists after reboot.</p>\n</li>\n<li><p><strong>fix bugs</strong></p>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.15.dev_0427",
          "name": "Repeater feature: per-type relay hop cap (advert.hops.max, group.hops.max) - v1.15.dev_0427",
          "datetime": "2026-04-27T09:32:36Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.15.dev_0427",
          "prerelease": true,
          "notes": "### v1.15_0427\r\n\r\n- **Repeater: per-type relay hop cap (`advert.hops.max` / `group.hops.max`).**\r\n\r\n  Two new settings let you independently limit how far **advertisement packets** and **group messages** are relayed across the mesh, without affecting direct messages, ACKs, or path discovery.\r\n\r\n  | Setting | Controls | Default |\r\n  |---|---|---|\r\n  | `advert.hops.max` | Max hops to relay node advertisement (ADVERT) packets | 64 (unchanged) |\r\n  | `group.hops.max` | Max hops to relay group messages (GRP_TXT / GRP_DATA) | 64 (unchanged) |\r\n\r\n  These are **repeater-only** settings. Configure via the **Command Line** in the MeshCore App:\r\n  ```\r\n  set advert.hops.max 3    # relay adverts at most 3 hops from sender\r\n  set group.hops.max 5     # relay group messages at most 5 hops\r\n  get advert.hops.max\r\n  get group.hops.max\r\n  ```\r\n\r\n  Setting either value to `0` completely suppresses that packet type — no relay at all, while everything else (DM, ACK, path) continues to work normally.\r\n\r\n  **Why this matters — advert storm reduction:**\r\n\r\n  Each repeater periodically broadcasts an advertisement that every other repeater in range relays, up to `flood.max` times (default 64). In a network of 35 repeaters and 35 companions, advert traffic alone consumes roughly 4% of airtime. Limiting to 3 hops brings that down to under 0.5% — a 7× reduction — with no loss of communication capability.  \r\n\r\n  **No coordination required.** Each repeater applies its own cap independently. You do not need all repeaters to agree on the same value — even a partial deployment reduces airtime. No region configuration, no App UI changes needed.\r\n\r\n  **Recommended profiles:**\r\n\r\n  | Profile | `advert.hops.max` | `group.hops.max` | Airtime (35R / 35C) | Use case |\r\n  |---|---|---|---|---|\r\n  | Default | 64 | 64 | ~4% | No change |\r\n  | Optimized | 3 | 5 | ~0.5% | Most deployments |\r\n  | DM-focused | 0 | 3 | ~0.2% | Prioritise direct messages |\r\n  | EU compliance | 0 | 3 | ~0.2% | Large EU networks (legal requirement) |\r\n\r\n  > **Relationship with `flood.max`:** `flood.max` (long-standing setting, default 64) is the master hop cap for **all** flood payloads — DMs on first send, path discovery, group messages, adverts. It applies regardless of payload type. `advert.hops.max` and `group.hops.max` add finer per-type control on top: they can only be equal to or stricter than `flood.max`, never looser. Setting `flood.max` lower automatically clamps both values to match. If you want to suppress adverts entirely while keeping DMs unrestricted, lower `advert.hops.max` to `0` — leave `flood.max` untouched.",
          "notesHtml": "<h3>v1.15_0427</h3>\n<ul>\n<li><p><strong>Repeater: per-type relay hop cap (<code>advert.hops.max</code> / <code>group.hops.max</code>).</strong></p>\n<p>Two new settings let you independently limit how far <strong>advertisement packets</strong> and <strong>group messages</strong> are relayed across the mesh, without affecting direct messages, ACKs, or path discovery.</p>\n<table>\n<thead>\n<tr>\n<th>Setting</th>\n<th>Controls</th>\n<th>Default</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>advert.hops.max</code></td>\n<td>Max hops to relay node advertisement (ADVERT) packets</td>\n<td>64 (unchanged)</td>\n</tr>\n<tr>\n<td><code>group.hops.max</code></td>\n<td>Max hops to relay group messages (GRP_TXT / GRP_DATA)</td>\n<td>64 (unchanged)</td>\n</tr>\n</tbody></table>\n<p>These are <strong>repeater-only</strong> settings. Configure via the <strong>Command Line</strong> in the MeshCore App:</p>\n<pre><code>set advert.hops.max 3    # relay adverts at most 3 hops from sender\nset group.hops.max 5     # relay group messages at most 5 hops\nget advert.hops.max\nget group.hops.max\n</code></pre>\n<p>Setting either value to <code>0</code> completely suppresses that packet type — no relay at all, while everything else (DM, ACK, path) continues to work normally.</p>\n<p><strong>Why this matters — advert storm reduction:</strong></p>\n<p>Each repeater periodically broadcasts an advertisement that every other repeater in range relays, up to <code>flood.max</code> times (default 64). In a network of 35 repeaters and 35 companions, advert traffic alone consumes roughly 4% of airtime. Limiting to 3 hops brings that down to under 0.5% — a 7× reduction — with no loss of communication capability.  </p>\n<p><strong>No coordination required.</strong> Each repeater applies its own cap independently. You do not need all repeaters to agree on the same value — even a partial deployment reduces airtime. No region configuration, no App UI changes needed.</p>\n<p><strong>Recommended profiles:</strong></p>\n<table>\n<thead>\n<tr>\n<th>Profile</th>\n<th><code>advert.hops.max</code></th>\n<th><code>group.hops.max</code></th>\n<th>Airtime (35R / 35C)</th>\n<th>Use case</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Default</td>\n<td>64</td>\n<td>64</td>\n<td>~4%</td>\n<td>No change</td>\n</tr>\n<tr>\n<td>Optimized</td>\n<td>3</td>\n<td>5</td>\n<td>~0.5%</td>\n<td>Most deployments</td>\n</tr>\n<tr>\n<td>DM-focused</td>\n<td>0</td>\n<td>3</td>\n<td>~0.2%</td>\n<td>Prioritise direct messages</td>\n</tr>\n<tr>\n<td>EU compliance</td>\n<td>0</td>\n<td>3</td>\n<td>~0.2%</td>\n<td>Large EU networks (legal requirement)</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p><strong>Relationship with <code>flood.max</code>:</strong> <code>flood.max</code> (long-standing setting, default 64) is the master hop cap for <strong>all</strong> flood payloads — DMs on first send, path discovery, group messages, adverts. It applies regardless of payload type. <code>advert.hops.max</code> and <code>group.hops.max</code> add finer per-type control on top: they can only be equal to or stricter than <code>flood.max</code>, never looser. Setting <code>flood.max</code> lower automatically clamps both values to match. If you want to suppress adverts entirely while keeping DMs unrestricted, lower <code>advert.hops.max</code> to <code>0</code> — leave <code>flood.max</code> untouched.</p>\n</blockquote>\n</li>\n</ul>\n"
        },
        {
          "version": "MeshCore-low-power-v1.15.dev_0419",
          "name": "MeshCore low power - v1.15.dev_0419",
          "datetime": "2026-04-19T04:50:53Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/MeshCore-low-power-v1.15.dev_0419",
          "prerelease": false,
          "notes": "bump to 1.15.dev",
          "notesHtml": "<p>bump to 1.15.dev</p>\n"
        },
        {
          "version": "XIAO-S3-Wio-low-power-v1.14_0417",
          "name": "XIAO S3 Wio low power - v1.14_0417",
          "datetime": "2026-04-17T13:57:17Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/XIAO-S3-Wio-low-power-v1.14_0417",
          "prerelease": false,
          "notes": "### v1.14_0417\r\n\r\n- **Hybrid RSSI + hardware CAD channel sensing (all node types).**\r\n\r\n  `isChannelActive()` now performs a two-stage check before transmitting:\r\n  1. RSSI check (fast, single SPI register read) — defers if signal is above `noise_floor + int.thresh`.\r\n  2. Hardware CAD (`scanChannel()`) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).\r\n\r\n  RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.\r\n\r\n  `int.thresh=0` disables both RSSI and CAD. `int.thresh=1` enables full hybrid at maximum sensitivity.\r\n\r\n  **On repeaters** (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, **`txdelay=2`**, 100 messages):\r\n\r\n  - **Repeaters close together / strong inter-repeater signal:** RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → **9% collision rate**.\r\n  - **Spread-out repeaters, some pairs below noise floor:** RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD **8%** vs RSSI-only **17%**.\r\n  - **Many hidden node pairs:** neither RSSI nor CAD helps. **Only `txdelay` reduces the floor.** Example: ~20–24% regardless of sensing method.\r\n\r\n  **On companions** (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):\r\n\r\n  - `int.thresh=3`: **53–64%** of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)\r\n  - `int.thresh=0` (no sensing): **0–1%** relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back\r\n\r\n  Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.\r\n\r\n- **Companion: `get/set txdelay`, `get/set direct.txdelay`, `get/set int.thresh` via [TerminalCLI](Companion_TerminalCLI_Commands.md).**\r\n\r\n  Relay timing and interference threshold are now configurable without reflashing.\r\n\r\n- **Companion: \"Heard N Repeats\" alert after Quick Send.**\r\n\r\n  After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.\r\n\r\n- **Companion: local time and date on the display.**\r\n\r\n  All pages now show the current time (`HH:MM`) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. `14 Apr 2026`).\r\n\r\n  Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via [TerminalCLI](Companion_TerminalCLI_Commands.md):\r\n  ```\r\n  set tz.offset 7    # UTC+7\r\n  set tz.offset -5   # UTC-5\r\n  get tz.offset\r\n  ```\r\n  Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.\r\n\r\n- **Companion: Metric / Imperial units.**\r\n\r\n  A new **Units** item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.\r\n\r\n  | Display | Metric | Imperial |\r\n  |---|---|---|\r\n  | GPS Trace distance | `150m` / `1.2km` | `492ft` / `0.7mi` |\r\n  | GPS page altitude | `245m` | `804ft` |\r\n  | Home page date | `14 Apr 2026` | `Apr 14 2026` |\r\n\r\n- **Companion: GPS Privacy mode.**\r\n\r\n  A new **GPS Privacy** item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…",
          "notesHtml": "<h3>v1.14_0417</h3>\n<ul>\n<li><p><strong>Hybrid RSSI + hardware CAD channel sensing (all node types).</strong></p>\n<p><code>isChannelActive()</code> now performs a two-stage check before transmitting:</p>\n<ol>\n<li>RSSI check (fast, single SPI register read) — defers if signal is above <code>noise_floor + int.thresh</code>.</li>\n<li>Hardware CAD (<code>scanChannel()</code>) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).</li>\n</ol>\n<p>RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.</p>\n<p><code>int.thresh=0</code> disables both RSSI and CAD. <code>int.thresh=1</code> enables full hybrid at maximum sensitivity.</p>\n<p><strong>On repeaters</strong> (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, <strong><code>txdelay=2</code></strong>, 100 messages):</p>\n<ul>\n<li><strong>Repeaters close together / strong inter-repeater signal:</strong> RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → <strong>9% collision rate</strong>.</li>\n<li><strong>Spread-out repeaters, some pairs below noise floor:</strong> RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD <strong>8%</strong> vs RSSI-only <strong>17%</strong>.</li>\n<li><strong>Many hidden node pairs:</strong> neither RSSI nor CAD helps. <strong>Only <code>txdelay</code> reduces the floor.</strong> Example: ~20–24% regardless of sensing method.</li>\n</ul>\n<p><strong>On companions</strong> (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):</p>\n<ul>\n<li><code>int.thresh=3</code>: <strong>53–64%</strong> of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)</li>\n<li><code>int.thresh=0</code> (no sensing): <strong>0–1%</strong> relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back</li>\n</ul>\n<p>Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.</p>\n</li>\n<li><p><strong>Companion: <code>get/set txdelay</code>, <code>get/set direct.txdelay</code>, <code>get/set int.thresh</code> via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>.</strong></p>\n<p>Relay timing and interference threshold are now configurable without reflashing.</p>\n</li>\n<li><p><strong>Companion: \"Heard N Repeats\" alert after Quick Send.</strong></p>\n<p>After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.</p>\n</li>\n<li><p><strong>Companion: local time and date on the display.</strong></p>\n<p>All pages now show the current time (<code>HH:MM</code>) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. <code>14 Apr 2026</code>).</p>\n<p>Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>:</p>\n<pre><code>set tz.offset 7    # UTC+7\nset tz.offset -5   # UTC-5\nget tz.offset\n</code></pre>\n<p>Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.</p>\n</li>\n<li><p><strong>Companion: Metric / Imperial units.</strong></p>\n<p>A new <strong>Units</strong> item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.</p>\n<table>\n<thead>\n<tr>\n<th>Display</th>\n<th>Metric</th>\n<th>Imperial</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>GPS Trace distance</td>\n<td><code>150m</code> / <code>1.2km</code></td>\n<td><code>492ft</code> / <code>0.7mi</code></td>\n</tr>\n<tr>\n<td>GPS page altitude</td>\n<td><code>245m</code></td>\n<td><code>804ft</code></td>\n</tr>\n<tr>\n<td>Home page date</td>\n<td><code>14 Apr 2026</code></td>\n<td><code>Apr 14 2026</code></td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>Companion: GPS Privacy mode.</strong></p>\n<p>A new <strong>GPS Privacy</strong> item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…</p>\n</li>\n</ul>\n"
        },
        {
          "version": "RAK4631-low-power-v1.14_0417",
          "name": "RAK4631 low power - v1.14_0417",
          "datetime": "2026-04-17T13:53:55Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/RAK4631-low-power-v1.14_0417",
          "prerelease": false,
          "notes": "### v1.14_0417\r\n\r\n- **Hybrid RSSI + hardware CAD channel sensing (all node types).**\r\n\r\n  `isChannelActive()` now performs a two-stage check before transmitting:\r\n  1. RSSI check (fast, single SPI register read) — defers if signal is above `noise_floor + int.thresh`.\r\n  2. Hardware CAD (`scanChannel()`) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).\r\n\r\n  RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.\r\n\r\n  `int.thresh=0` disables both RSSI and CAD. `int.thresh=1` enables full hybrid at maximum sensitivity.\r\n\r\n  **On repeaters** (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, **`txdelay=2`**, 100 messages):\r\n\r\n  - **Repeaters close together / strong inter-repeater signal:** RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → **9% collision rate**.\r\n  - **Spread-out repeaters, some pairs below noise floor:** RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD **8%** vs RSSI-only **17%**.\r\n  - **Many hidden node pairs:** neither RSSI nor CAD helps. **Only `txdelay` reduces the floor.** Example: ~20–24% regardless of sensing method.\r\n\r\n  **On companions** (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):\r\n\r\n  - `int.thresh=3`: **53–64%** of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)\r\n  - `int.thresh=0` (no sensing): **0–1%** relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back\r\n\r\n  Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.\r\n\r\n- **Companion: `get/set txdelay`, `get/set direct.txdelay`, `get/set int.thresh` via [TerminalCLI](Companion_TerminalCLI_Commands.md).**\r\n\r\n  Relay timing and interference threshold are now configurable without reflashing.\r\n\r\n- **Companion: \"Heard N Repeats\" alert after Quick Send.**\r\n\r\n  After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.\r\n\r\n- **Companion: local time and date on the display.**\r\n\r\n  All pages now show the current time (`HH:MM`) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. `14 Apr 2026`).\r\n\r\n  Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via [TerminalCLI](Companion_TerminalCLI_Commands.md):\r\n  ```\r\n  set tz.offset 7    # UTC+7\r\n  set tz.offset -5   # UTC-5\r\n  get tz.offset\r\n  ```\r\n  Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.\r\n\r\n- **Companion: Metric / Imperial units.**\r\n\r\n  A new **Units** item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.\r\n\r\n  | Display | Metric | Imperial |\r\n  |---|---|---|\r\n  | GPS Trace distance | `150m` / `1.2km` | `492ft` / `0.7mi` |\r\n  | GPS page altitude | `245m` | `804ft` |\r\n  | Home page date | `14 Apr 2026` | `Apr 14 2026` |\r\n\r\n- **Companion: GPS Privacy mode.**\r\n\r\n  A new **GPS Privacy** item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…",
          "notesHtml": "<h3>v1.14_0417</h3>\n<ul>\n<li><p><strong>Hybrid RSSI + hardware CAD channel sensing (all node types).</strong></p>\n<p><code>isChannelActive()</code> now performs a two-stage check before transmitting:</p>\n<ol>\n<li>RSSI check (fast, single SPI register read) — defers if signal is above <code>noise_floor + int.thresh</code>.</li>\n<li>Hardware CAD (<code>scanChannel()</code>) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).</li>\n</ol>\n<p>RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.</p>\n<p><code>int.thresh=0</code> disables both RSSI and CAD. <code>int.thresh=1</code> enables full hybrid at maximum sensitivity.</p>\n<p><strong>On repeaters</strong> (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, <strong><code>txdelay=2</code></strong>, 100 messages):</p>\n<ul>\n<li><strong>Repeaters close together / strong inter-repeater signal:</strong> RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → <strong>9% collision rate</strong>.</li>\n<li><strong>Spread-out repeaters, some pairs below noise floor:</strong> RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD <strong>8%</strong> vs RSSI-only <strong>17%</strong>.</li>\n<li><strong>Many hidden node pairs:</strong> neither RSSI nor CAD helps. <strong>Only <code>txdelay</code> reduces the floor.</strong> Example: ~20–24% regardless of sensing method.</li>\n</ul>\n<p><strong>On companions</strong> (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):</p>\n<ul>\n<li><code>int.thresh=3</code>: <strong>53–64%</strong> of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)</li>\n<li><code>int.thresh=0</code> (no sensing): <strong>0–1%</strong> relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back</li>\n</ul>\n<p>Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.</p>\n</li>\n<li><p><strong>Companion: <code>get/set txdelay</code>, <code>get/set direct.txdelay</code>, <code>get/set int.thresh</code> via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>.</strong></p>\n<p>Relay timing and interference threshold are now configurable without reflashing.</p>\n</li>\n<li><p><strong>Companion: \"Heard N Repeats\" alert after Quick Send.</strong></p>\n<p>After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.</p>\n</li>\n<li><p><strong>Companion: local time and date on the display.</strong></p>\n<p>All pages now show the current time (<code>HH:MM</code>) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. <code>14 Apr 2026</code>).</p>\n<p>Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>:</p>\n<pre><code>set tz.offset 7    # UTC+7\nset tz.offset -5   # UTC-5\nget tz.offset\n</code></pre>\n<p>Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.</p>\n</li>\n<li><p><strong>Companion: Metric / Imperial units.</strong></p>\n<p>A new <strong>Units</strong> item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.</p>\n<table>\n<thead>\n<tr>\n<th>Display</th>\n<th>Metric</th>\n<th>Imperial</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>GPS Trace distance</td>\n<td><code>150m</code> / <code>1.2km</code></td>\n<td><code>492ft</code> / <code>0.7mi</code></td>\n</tr>\n<tr>\n<td>GPS page altitude</td>\n<td><code>245m</code></td>\n<td><code>804ft</code></td>\n</tr>\n<tr>\n<td>Home page date</td>\n<td><code>14 Apr 2026</code></td>\n<td><code>Apr 14 2026</code></td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>Companion: GPS Privacy mode.</strong></p>\n<p>A new <strong>GPS Privacy</strong> item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…</p>\n</li>\n</ul>\n"
        },
        {
          "version": "Heltec-V4-OLED-low-power-v1.14_0417",
          "name": "Heltec V4 OLED low power - v1.14_0417",
          "datetime": "2026-04-17T14:04:26Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/Heltec-V4-OLED-low-power-v1.14_0417",
          "prerelease": false,
          "notes": "### v1.14_0417\r\n\r\n- **Hybrid RSSI + hardware CAD channel sensing (all node types).**\r\n\r\n  `isChannelActive()` now performs a two-stage check before transmitting:\r\n  1. RSSI check (fast, single SPI register read) — defers if signal is above `noise_floor + int.thresh`.\r\n  2. Hardware CAD (`scanChannel()`) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).\r\n\r\n  RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.\r\n\r\n  `int.thresh=0` disables both RSSI and CAD. `int.thresh=1` enables full hybrid at maximum sensitivity.\r\n\r\n  **On repeaters** (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, **`txdelay=2`**, 100 messages):\r\n\r\n  - **Repeaters close together / strong inter-repeater signal:** RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → **9% collision rate**.\r\n  - **Spread-out repeaters, some pairs below noise floor:** RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD **8%** vs RSSI-only **17%**.\r\n  - **Many hidden node pairs:** neither RSSI nor CAD helps. **Only `txdelay` reduces the floor.** Example: ~20–24% regardless of sensing method.\r\n\r\n  **On companions** (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):\r\n\r\n  - `int.thresh=3`: **53–64%** of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)\r\n  - `int.thresh=0` (no sensing): **0–1%** relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back\r\n\r\n  Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.\r\n\r\n- **Companion: `get/set txdelay`, `get/set direct.txdelay`, `get/set int.thresh` via [TerminalCLI](Companion_TerminalCLI_Commands.md).**\r\n\r\n  Relay timing and interference threshold are now configurable without reflashing.\r\n\r\n- **Companion: \"Heard N Repeats\" alert after Quick Send.**\r\n\r\n  After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.\r\n\r\n- **Companion: local time and date on the display.**\r\n\r\n  All pages now show the current time (`HH:MM`) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. `14 Apr 2026`).\r\n\r\n  Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via [TerminalCLI](Companion_TerminalCLI_Commands.md):\r\n  ```\r\n  set tz.offset 7    # UTC+7\r\n  set tz.offset -5   # UTC-5\r\n  get tz.offset\r\n  ```\r\n  Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.\r\n\r\n- **Companion: Metric / Imperial units.**\r\n\r\n  A new **Units** item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.\r\n\r\n  | Display | Metric | Imperial |\r\n  |---|---|---|\r\n  | GPS Trace distance | `150m` / `1.2km` | `492ft` / `0.7mi` |\r\n  | GPS page altitude | `245m` | `804ft` |\r\n  | Home page date | `14 Apr 2026` | `Apr 14 2026` |\r\n\r\n- **Companion: GPS Privacy mode.**\r\n\r\n  A new **GPS Privacy** item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…",
          "notesHtml": "<h3>v1.14_0417</h3>\n<ul>\n<li><p><strong>Hybrid RSSI + hardware CAD channel sensing (all node types).</strong></p>\n<p><code>isChannelActive()</code> now performs a two-stage check before transmitting:</p>\n<ol>\n<li>RSSI check (fast, single SPI register read) — defers if signal is above <code>noise_floor + int.thresh</code>.</li>\n<li>Hardware CAD (<code>scanChannel()</code>) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).</li>\n</ol>\n<p>RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.</p>\n<p><code>int.thresh=0</code> disables both RSSI and CAD. <code>int.thresh=1</code> enables full hybrid at maximum sensitivity.</p>\n<p><strong>On repeaters</strong> (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, <strong><code>txdelay=2</code></strong>, 100 messages):</p>\n<ul>\n<li><strong>Repeaters close together / strong inter-repeater signal:</strong> RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → <strong>9% collision rate</strong>.</li>\n<li><strong>Spread-out repeaters, some pairs below noise floor:</strong> RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD <strong>8%</strong> vs RSSI-only <strong>17%</strong>.</li>\n<li><strong>Many hidden node pairs:</strong> neither RSSI nor CAD helps. <strong>Only <code>txdelay</code> reduces the floor.</strong> Example: ~20–24% regardless of sensing method.</li>\n</ul>\n<p><strong>On companions</strong> (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):</p>\n<ul>\n<li><code>int.thresh=3</code>: <strong>53–64%</strong> of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)</li>\n<li><code>int.thresh=0</code> (no sensing): <strong>0–1%</strong> relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back</li>\n</ul>\n<p>Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.</p>\n</li>\n<li><p><strong>Companion: <code>get/set txdelay</code>, <code>get/set direct.txdelay</code>, <code>get/set int.thresh</code> via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>.</strong></p>\n<p>Relay timing and interference threshold are now configurable without reflashing.</p>\n</li>\n<li><p><strong>Companion: \"Heard N Repeats\" alert after Quick Send.</strong></p>\n<p>After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.</p>\n</li>\n<li><p><strong>Companion: local time and date on the display.</strong></p>\n<p>All pages now show the current time (<code>HH:MM</code>) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. <code>14 Apr 2026</code>).</p>\n<p>Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>:</p>\n<pre><code>set tz.offset 7    # UTC+7\nset tz.offset -5   # UTC-5\nget tz.offset\n</code></pre>\n<p>Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.</p>\n</li>\n<li><p><strong>Companion: Metric / Imperial units.</strong></p>\n<p>A new <strong>Units</strong> item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.</p>\n<table>\n<thead>\n<tr>\n<th>Display</th>\n<th>Metric</th>\n<th>Imperial</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>GPS Trace distance</td>\n<td><code>150m</code> / <code>1.2km</code></td>\n<td><code>492ft</code> / <code>0.7mi</code></td>\n</tr>\n<tr>\n<td>GPS page altitude</td>\n<td><code>245m</code></td>\n<td><code>804ft</code></td>\n</tr>\n<tr>\n<td>Home page date</td>\n<td><code>14 Apr 2026</code></td>\n<td><code>Apr 14 2026</code></td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>Companion: GPS Privacy mode.</strong></p>\n<p>A new <strong>GPS Privacy</strong> item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…</p>\n</li>\n</ul>\n"
        },
        {
          "version": "Heltec-V3-WSL3-low-power-v1.14_0417",
          "name": "Heltec V3 & WSL3 low power - v1.14_0417",
          "datetime": "2026-04-17T14:00:08Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/Heltec-V3-WSL3-low-power-v1.14_0417",
          "prerelease": false,
          "notes": "### v1.14_0417\r\n\r\n- **Hybrid RSSI + hardware CAD channel sensing (all node types).**\r\n\r\n  `isChannelActive()` now performs a two-stage check before transmitting:\r\n  1. RSSI check (fast, single SPI register read) — defers if signal is above `noise_floor + int.thresh`.\r\n  2. Hardware CAD (`scanChannel()`) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).\r\n\r\n  RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.\r\n\r\n  `int.thresh=0` disables both RSSI and CAD. `int.thresh=1` enables full hybrid at maximum sensitivity.\r\n\r\n  **On repeaters** (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, **`txdelay=2`**, 100 messages):\r\n\r\n  - **Repeaters close together / strong inter-repeater signal:** RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → **9% collision rate**.\r\n  - **Spread-out repeaters, some pairs below noise floor:** RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD **8%** vs RSSI-only **17%**.\r\n  - **Many hidden node pairs:** neither RSSI nor CAD helps. **Only `txdelay` reduces the floor.** Example: ~20–24% regardless of sensing method.\r\n\r\n  **On companions** (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):\r\n\r\n  - `int.thresh=3`: **53–64%** of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)\r\n  - `int.thresh=0` (no sensing): **0–1%** relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back\r\n\r\n  Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.\r\n\r\n- **Companion: `get/set txdelay`, `get/set direct.txdelay`, `get/set int.thresh` via [TerminalCLI](Companion_TerminalCLI_Commands.md).**\r\n\r\n  Relay timing and interference threshold are now configurable without reflashing.\r\n\r\n- **Companion: \"Heard N Repeats\" alert after Quick Send.**\r\n\r\n  After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.\r\n\r\n- **Companion: local time and date on the display.**\r\n\r\n  All pages now show the current time (`HH:MM`) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. `14 Apr 2026`).\r\n\r\n  Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via [TerminalCLI](Companion_TerminalCLI_Commands.md):\r\n  ```\r\n  set tz.offset 7    # UTC+7\r\n  set tz.offset -5   # UTC-5\r\n  get tz.offset\r\n  ```\r\n  Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.\r\n\r\n- **Companion: Metric / Imperial units.**\r\n\r\n  A new **Units** item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.\r\n\r\n  | Display | Metric | Imperial |\r\n  |---|---|---|\r\n  | GPS Trace distance | `150m` / `1.2km` | `492ft` / `0.7mi` |\r\n  | GPS page altitude | `245m` | `804ft` |\r\n  | Home page date | `14 Apr 2026` | `Apr 14 2026` |\r\n\r\n- **Companion: GPS Privacy mode.**\r\n\r\n  A new **GPS Privacy** item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…",
          "notesHtml": "<h3>v1.14_0417</h3>\n<ul>\n<li><p><strong>Hybrid RSSI + hardware CAD channel sensing (all node types).</strong></p>\n<p><code>isChannelActive()</code> now performs a two-stage check before transmitting:</p>\n<ol>\n<li>RSSI check (fast, single SPI register read) — defers if signal is above <code>noise_floor + int.thresh</code>.</li>\n<li>Hardware CAD (<code>scanChannel()</code>) — if RSSI misses, performs LoRa chirp correlation to detect signals below the noise floor (~16ms blocking scan on SX126x).</li>\n</ol>\n<p>RSSI also detects any in-band signal (interference, jamming), while CAD only correlates LoRa chirp patterns and ignores non-LoRa noise entirely. With hybrid, RSSI acts as the first guard — CAD only runs when the channel appears clear to RSSI.</p>\n<p><code>int.thresh=0</code> disables both RSSI and CAD. <code>int.thresh=1</code> enables full hybrid at maximum sensitivity.</p>\n<p><strong>On repeaters</strong> (single source sending): results depend on topology. Field tests with 4 repeaters (SF8/BW62.5kHz, <strong><code>txdelay=2</code></strong>, 100 messages):</p>\n<ul>\n<li><strong>Repeaters close together / strong inter-repeater signal:</strong> RSSI handles detection well, CAD rarely fires. Example: int.thresh=1 → <strong>9% collision rate</strong>.</li>\n<li><strong>Spread-out repeaters, some pairs below noise floor:</strong> RSSI misses sub-NF pairs; CAD fills the gap. Example: hybrid/CAD <strong>8%</strong> vs RSSI-only <strong>17%</strong>.</li>\n<li><strong>Many hidden node pairs:</strong> neither RSSI nor CAD helps. <strong>Only <code>txdelay</code> reduces the floor.</strong> Example: ~20–24% regardless of sensing method.</li>\n</ul>\n<p><strong>On companions</strong> (multiple sources sending concurrently): channel sensing still helps, but with diminishing returns. Tested with 2 concurrent companions plus a third node sending long messages every 5s (SF8/BW62.5kHz):</p>\n<ul>\n<li><code>int.thresh=3</code>: <strong>53–64%</strong> of messages successfully relayed by all 4 repeaters (confirmed by hearing each relay back)</li>\n<li><code>int.thresh=0</code> (no sensing): <strong>0–1%</strong> relayed by all 4; most messages are relayed by 0–1 repeaters only — collisions occur at two levels: concurrent companion transmissions corrupt each other at the repeater, and the resulting relay transmissions from multiple repeaters collide on the way back</li>\n</ul>\n<p>Channel sensing — even imperfect — is far better than none. The remaining loss at int.thresh=3 is a fundamental ALOHA-style limitation: uncoordinated LoRa nodes cannot eliminate simultaneous transmission without a shared scheduling mechanism that does not exist in this protocol.</p>\n</li>\n<li><p><strong>Companion: <code>get/set txdelay</code>, <code>get/set direct.txdelay</code>, <code>get/set int.thresh</code> via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>.</strong></p>\n<p>Relay timing and interference threshold are now configurable without reflashing.</p>\n</li>\n<li><p><strong>Companion: \"Heard N Repeats\" alert after Quick Send.</strong></p>\n<p>After sending from the Quick Send screen, the display shows how many repeaters have relayed the message (e.g. \"Heard 3 Repeats\"). The counter updates in real time as each relay is heard.</p>\n</li>\n<li><p><strong>Companion: local time and date on the display.</strong></p>\n<p>All pages now show the current time (<code>HH:MM</code>) in the header, between the page title and the battery icon. The Home page also shows the full date at the bottom (e.g. <code>14 Apr 2026</code>).</p>\n<p>Time is sourced from the device RTC, which is synchronized upon app connection or GPS fix. Configure your local timezone offset once via <a href=\"https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/blob/HEAD/Companion_TerminalCLI_Commands.md\" target=\"_blank\" rel=\"noopener noreferrer\">TerminalCLI</a>:</p>\n<pre><code>set tz.offset 7    # UTC+7\nset tz.offset -5   # UTC-5\nget tz.offset\n</code></pre>\n<p>Offset is saved to flash. All internal timestamps remain UTC — the offset is applied only for display.</p>\n</li>\n<li><p><strong>Companion: Metric / Imperial units.</strong></p>\n<p>A new <strong>Units</strong> item in the Settings page toggles between Metric and Imperial. Setting is saved to flash and persists after reboot.</p>\n<table>\n<thead>\n<tr>\n<th>Display</th>\n<th>Metric</th>\n<th>Imperial</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>GPS Trace distance</td>\n<td><code>150m</code> / <code>1.2km</code></td>\n<td><code>492ft</code> / <code>0.7mi</code></td>\n</tr>\n<tr>\n<td>GPS page altitude</td>\n<td><code>245m</code></td>\n<td><code>804ft</code></td>\n</tr>\n<tr>\n<td>Home page date</td>\n<td><code>14 Apr 2026</code></td>\n<td><code>Apr 14 2026</code></td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>Companion: GPS Privacy mode.</strong></p>\n<p>A new <strong>GPS Privacy</strong> item in the Settings page lets you stop GPS coordinates from being attached to Quick Send me\n…</p>\n</li>\n</ul>\n"
        },
        {
          "version": "Heltec-V4-OLED-low-power-v1.14_0410",
          "name": "Heltec V4 OLED low power - v1.14_0410",
          "datetime": "2026-04-10T04:40:07Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/Heltec-V4-OLED-low-power-v1.14_0410",
          "prerelease": false,
          "notes": "### v1.14_0410\r\n\r\n- **Message preview: scroll long messages & see all 256 buffered messages.**\r\n\r\n  The message preview screen is rebuilt from the ground up. All 256 buffered messages are now navigable — previously capped at 32. Long messages that overflow the screen can be scrolled line by line.\r\n\r\n  #### Button controls in message preview\r\n\r\n  | Action | Effect |\r\n  |---|---|\r\n  | **Single click** | Scroll text down (3 lines); advances to next older message at end of text |\r\n  | **Double click** | Scroll text up (3 lines); goes to next newer message at top; at newest → home |\r\n  | **Long press** | Open menu: **Save location** *(if message has GPS coords)* / **Home** |\r\n\r\n  #### Counter and unread tracking\r\n\r\n  ```\r\n  ┌──────────────────────────────┐\r\n  │ 5/19                    42s  │\r\n  │──────────────────────────────│\r\n  │ (2) Alien:                   │\r\n  │ Hello everyone, just wanted  │\r\n  │ to check in. We made it to   │\r\n  │ base camp safe and sound.    │\r\n  │                           ▼  │\r\n  └──────────────────────────────┘\r\n  ```\r\n\r\n  `5/19` = viewing message 5 (newest = 19, oldest = 1). `▼` = more text below. `42s` = time since received. The counter tracks unread messages — when you close preview and return, only new messages since last session are counted.\r\n\r\n- **Saved Locations: save GPS coordinates from messages to flash.**\r\n\r\n  When viewing a message with GPS coordinates, long press opens a menu. Choose **Save location**, then pick one of 10 slots to save into. Saved locations persist in flash memory — they survive reboot.\r\n\r\n  Navigate to the **SAVED LOCS** page on the home screen to browse your saved locations and open the GPS Trace screen for any of them.\r\n\r\n  ```\r\n  ┌──────────────────────────────┐\r\n  │ SAVED  2/10                  │\r\n  │──────────────────────────────│\r\n  │ > Alien: I need help         │\r\n  │   Big Boy: Heading home      │\r\n  │                              │\r\n  │                              │\r\n  └──────────────────────────────┘\r\n  ```\r\n\r\n  Each entry shows **sender + message snippet** so you can identify entries even when multiple locations from the same person are saved.\r\n\r\n  | Press | Effect |\r\n  |---|---|\r\n  | Single click | Move highlight to next entry |\r\n  | Long press | Open GPS Trace screen for that location |\r\n  | Double click | Return to home |\r\n\r\n- **GPS Trace screen: live distance & bearing to a saved location.**\r\n\r\n  ```\r\n  ┌──────────────────────────────┐\r\n  │ Alien: I need help       5m  │\r\n  │──────────────────────────────│\r\n  │      10.7769  106.7009       │\r\n  │                              │\r\n  │           1.2km              │\r\n  │                              │\r\n  │          247°  WSW           │\r\n  └──────────────────────────────┘\r\n  ```\r\n\r\n  The timer in the top-right corner shows how long you have been on this Trace screen. Requires own GPS fix for distance/bearing. Raw coordinates are always shown. Any button returns to the Saved Locations list.\r\n\r\n- **Saved locations CLI commands (TerminalCLI).**\r\n\r\n  Manage saved locations from the terminal without touching the display:\r\n\r\n  | Command | Effect |\r\n  |---|---|\r\n  | `get loc` | List all occupied slots (`N:lat,lon:name`, N is 0-based) |\r\n  | `set loc.<N> <name> <lat> <lon>` | Save to slot N (0-based; display shows 1–10) |\r\n  | `del loc.<N>` | Clear slot N (0-based) |\r\n  | `del loc.all` | Clear all slots |",
          "notesHtml": "<h3>v1.14_0410</h3>\n<ul>\n<li><p><strong>Message preview: scroll long messages &amp; see all 256 buffered messages.</strong></p>\n<p>The message preview screen is rebuilt from the ground up. All 256 buffered messages are now navigable — previously capped at 32. Long messages that overflow the screen can be scrolled line by line.</p>\n<h4>Button controls in message preview</h4>\n<table>\n<thead>\n<tr>\n<th>Action</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><strong>Single click</strong></td>\n<td>Scroll text down (3 lines); advances to next older message at end of text</td>\n</tr>\n<tr>\n<td><strong>Double click</strong></td>\n<td>Scroll text up (3 lines); goes to next newer message at top; at newest → home</td>\n</tr>\n<tr>\n<td><strong>Long press</strong></td>\n<td>Open menu: <strong>Save location</strong> <em>(if message has GPS coords)</em> / <strong>Home</strong></td>\n</tr>\n</tbody></table>\n<h4>Counter and unread tracking</h4>\n<pre><code>┌──────────────────────────────┐\n│ 5/19                    42s  │\n│──────────────────────────────│\n│ (2) Alien:                   │\n│ Hello everyone, just wanted  │\n│ to check in. We made it to   │\n│ base camp safe and sound.    │\n│                           ▼  │\n└──────────────────────────────┘\n</code></pre>\n<p><code>5/19</code> = viewing message 5 (newest = 19, oldest = 1). <code>▼</code> = more text below. <code>42s</code> = time since received. The counter tracks unread messages — when you close preview and return, only new messages since last session are counted.</p>\n</li>\n<li><p><strong>Saved Locations: save GPS coordinates from messages to flash.</strong></p>\n<p>When viewing a message with GPS coordinates, long press opens a menu. Choose <strong>Save location</strong>, then pick one of 10 slots to save into. Saved locations persist in flash memory — they survive reboot.</p>\n<p>Navigate to the <strong>SAVED LOCS</strong> page on the home screen to browse your saved locations and open the GPS Trace screen for any of them.</p>\n<pre><code>┌──────────────────────────────┐\n│ SAVED  2/10                  │\n│──────────────────────────────│\n│ &gt; Alien: I need help         │\n│   Big Boy: Heading home      │\n│                              │\n│                              │\n└──────────────────────────────┘\n</code></pre>\n<p>Each entry shows <strong>sender + message snippet</strong> so you can identify entries even when multiple locations from the same person are saved.</p>\n<table>\n<thead>\n<tr>\n<th>Press</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Single click</td>\n<td>Move highlight to next entry</td>\n</tr>\n<tr>\n<td>Long press</td>\n<td>Open GPS Trace screen for that location</td>\n</tr>\n<tr>\n<td>Double click</td>\n<td>Return to home</td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>GPS Trace screen: live distance &amp; bearing to a saved location.</strong></p>\n<pre><code>┌──────────────────────────────┐\n│ Alien: I need help       5m  │\n│──────────────────────────────│\n│      10.7769  106.7009       │\n│                              │\n│           1.2km              │\n│                              │\n│          247°  WSW           │\n└──────────────────────────────┘\n</code></pre>\n<p>The timer in the top-right corner shows how long you have been on this Trace screen. Requires own GPS fix for distance/bearing. Raw coordinates are always shown. Any button returns to the Saved Locations list.</p>\n</li>\n<li><p><strong>Saved locations CLI commands (TerminalCLI).</strong></p>\n<p>Manage saved locations from the terminal without touching the display:</p>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>get loc</code></td>\n<td>List all occupied slots (<code>N:lat,lon:name</code>, N is 0-based)</td>\n</tr>\n<tr>\n<td><code>set loc.&lt;N&gt; &lt;name&gt; &lt;lat&gt; &lt;lon&gt;</code></td>\n<td>Save to slot N (0-based; display shows 1–10)</td>\n</tr>\n<tr>\n<td><code>del loc.&lt;N&gt;</code></td>\n<td>Clear slot N (0-based)</td>\n</tr>\n<tr>\n<td><code>del loc.all</code></td>\n<td>Clear all slots</td>\n</tr>\n</tbody></table>\n</li>\n</ul>\n"
        },
        {
          "version": "Heltec-V3-WSL3-low-power-v1.14_0410",
          "name": "Heltec V3 & WSL3 low power - v1.14_0410",
          "datetime": "2026-04-10T04:32:34Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/Heltec-V3-WSL3-low-power-v1.14_0410",
          "prerelease": false,
          "notes": "### v1.14_0410\r\n\r\n- **Message preview: scroll long messages & see all 256 buffered messages.**\r\n\r\n  The message preview screen is rebuilt from the ground up. All 256 buffered messages are now navigable — previously capped at 32. Long messages that overflow the screen can be scrolled line by line.\r\n\r\n  #### Button controls in message preview\r\n\r\n  | Action | Effect |\r\n  |---|---|\r\n  | **Single click** | Scroll text down (3 lines); advances to next older message at end of text |\r\n  | **Double click** | Scroll text up (3 lines); goes to next newer message at top; at newest → home |\r\n  | **Long press** | Open menu: **Save location** *(if message has GPS coords)* / **Home** |\r\n\r\n  #### Counter and unread tracking\r\n\r\n  ```\r\n  ┌──────────────────────────────┐\r\n  │ 5/19                    42s  │\r\n  │──────────────────────────────│\r\n  │ (2) Alien:                   │\r\n  │ Hello everyone, just wanted  │\r\n  │ to check in. We made it to   │\r\n  │ base camp safe and sound.    │\r\n  │                           ▼  │\r\n  └──────────────────────────────┘\r\n  ```\r\n\r\n  `5/19` = viewing message 5 (newest = 19, oldest = 1). `▼` = more text below. `42s` = time since received. The counter tracks unread messages — when you close preview and return, only new messages since last session are counted.\r\n\r\n- **Saved Locations: save GPS coordinates from messages to flash.**\r\n\r\n  When viewing a message with GPS coordinates, long press opens a menu. Choose **Save location**, then pick one of 10 slots to save into. Saved locations persist in flash memory — they survive reboot.\r\n\r\n  Navigate to the **SAVED LOCS** page on the home screen to browse your saved locations and open the GPS Trace screen for any of them.\r\n\r\n  ```\r\n  ┌──────────────────────────────┐\r\n  │ SAVED  2/10                  │\r\n  │──────────────────────────────│\r\n  │ > Alien: I need help         │\r\n  │   Big Boy: Heading home      │\r\n  │                              │\r\n  │                              │\r\n  └──────────────────────────────┘\r\n  ```\r\n\r\n  Each entry shows **sender + message snippet** so you can identify entries even when multiple locations from the same person are saved.\r\n\r\n  | Press | Effect |\r\n  |---|---|\r\n  | Single click | Move highlight to next entry |\r\n  | Long press | Open GPS Trace screen for that location |\r\n  | Double click | Return to home |\r\n\r\n- **GPS Trace screen: live distance & bearing to a saved location.**\r\n\r\n  ```\r\n  ┌──────────────────────────────┐\r\n  │ Alien: I need help       5m  │\r\n  │──────────────────────────────│\r\n  │      10.7769  106.7009       │\r\n  │                              │\r\n  │           1.2km              │\r\n  │                              │\r\n  │          247°  WSW           │\r\n  └──────────────────────────────┘\r\n  ```\r\n\r\n  The timer in the top-right corner shows how long you have been on this Trace screen. Requires own GPS fix for distance/bearing. Raw coordinates are always shown. Any button returns to the Saved Locations list.\r\n\r\n- **Saved locations CLI commands (TerminalCLI).**\r\n\r\n  Manage saved locations from the terminal without touching the display:\r\n\r\n  | Command | Effect |\r\n  |---|---|\r\n  | `get loc` | List all occupied slots (`N:lat,lon:name`, N is 0-based) |\r\n  | `set loc.<N> <name> <lat> <lon>` | Save to slot N (0-based; display shows 1–10) |\r\n  | `del loc.<N>` | Clear slot N (0-based) |\r\n  | `del loc.all` | Clear all slots |",
          "notesHtml": "<h3>v1.14_0410</h3>\n<ul>\n<li><p><strong>Message preview: scroll long messages &amp; see all 256 buffered messages.</strong></p>\n<p>The message preview screen is rebuilt from the ground up. All 256 buffered messages are now navigable — previously capped at 32. Long messages that overflow the screen can be scrolled line by line.</p>\n<h4>Button controls in message preview</h4>\n<table>\n<thead>\n<tr>\n<th>Action</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><strong>Single click</strong></td>\n<td>Scroll text down (3 lines); advances to next older message at end of text</td>\n</tr>\n<tr>\n<td><strong>Double click</strong></td>\n<td>Scroll text up (3 lines); goes to next newer message at top; at newest → home</td>\n</tr>\n<tr>\n<td><strong>Long press</strong></td>\n<td>Open menu: <strong>Save location</strong> <em>(if message has GPS coords)</em> / <strong>Home</strong></td>\n</tr>\n</tbody></table>\n<h4>Counter and unread tracking</h4>\n<pre><code>┌──────────────────────────────┐\n│ 5/19                    42s  │\n│──────────────────────────────│\n│ (2) Alien:                   │\n│ Hello everyone, just wanted  │\n│ to check in. We made it to   │\n│ base camp safe and sound.    │\n│                           ▼  │\n└──────────────────────────────┘\n</code></pre>\n<p><code>5/19</code> = viewing message 5 (newest = 19, oldest = 1). <code>▼</code> = more text below. <code>42s</code> = time since received. The counter tracks unread messages — when you close preview and return, only new messages since last session are counted.</p>\n</li>\n<li><p><strong>Saved Locations: save GPS coordinates from messages to flash.</strong></p>\n<p>When viewing a message with GPS coordinates, long press opens a menu. Choose <strong>Save location</strong>, then pick one of 10 slots to save into. Saved locations persist in flash memory — they survive reboot.</p>\n<p>Navigate to the <strong>SAVED LOCS</strong> page on the home screen to browse your saved locations and open the GPS Trace screen for any of them.</p>\n<pre><code>┌──────────────────────────────┐\n│ SAVED  2/10                  │\n│──────────────────────────────│\n│ &gt; Alien: I need help         │\n│   Big Boy: Heading home      │\n│                              │\n│                              │\n└──────────────────────────────┘\n</code></pre>\n<p>Each entry shows <strong>sender + message snippet</strong> so you can identify entries even when multiple locations from the same person are saved.</p>\n<table>\n<thead>\n<tr>\n<th>Press</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Single click</td>\n<td>Move highlight to next entry</td>\n</tr>\n<tr>\n<td>Long press</td>\n<td>Open GPS Trace screen for that location</td>\n</tr>\n<tr>\n<td>Double click</td>\n<td>Return to home</td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>GPS Trace screen: live distance &amp; bearing to a saved location.</strong></p>\n<pre><code>┌──────────────────────────────┐\n│ Alien: I need help       5m  │\n│──────────────────────────────│\n│      10.7769  106.7009       │\n│                              │\n│           1.2km              │\n│                              │\n│          247°  WSW           │\n└──────────────────────────────┘\n</code></pre>\n<p>The timer in the top-right corner shows how long you have been on this Trace screen. Requires own GPS fix for distance/bearing. Raw coordinates are always shown. Any button returns to the Saved Locations list.</p>\n</li>\n<li><p><strong>Saved locations CLI commands (TerminalCLI).</strong></p>\n<p>Manage saved locations from the terminal without touching the display:</p>\n<table>\n<thead>\n<tr>\n<th>Command</th>\n<th>Effect</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>get loc</code></td>\n<td>List all occupied slots (<code>N:lat,lon:name</code>, N is 0-based)</td>\n</tr>\n<tr>\n<td><code>set loc.&lt;N&gt; &lt;name&gt; &lt;lat&gt; &lt;lon&gt;</code></td>\n<td>Save to slot N (0-based; display shows 1–10)</td>\n</tr>\n<tr>\n<td><code>del loc.&lt;N&gt;</code></td>\n<td>Clear slot N (0-based)</td>\n</tr>\n<tr>\n<td><code>del loc.all</code></td>\n<td>Clear all slots</td>\n</tr>\n</tbody></table>\n</li>\n</ul>\n"
        },
        {
          "version": "RAK4631-low-power-v1.14_0404",
          "name": "RAK4631 low power - v1.14_0404",
          "datetime": "2026-04-04T10:34:37Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/RAK4631-low-power-v1.14_0404",
          "prerelease": false,
          "notes": "Ported the BLE random disconnection fix from ESP32 to nRF52.",
          "notesHtml": "<p>Ported the BLE random disconnection fix from ESP32 to nRF52.</p>\n"
        },
        {
          "version": "Heltec-V4-OLED-low-power-v1.14_0404",
          "name": "Heltec V4 OLED low power - v1.14_0404",
          "datetime": "2026-04-04T10:51:14Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/Heltec-V4-OLED-low-power-v1.14_0404",
          "prerelease": false,
          "notes": "### v1.14_0404\r\n\r\n- **Quick Send and Settings — control your Companion without a phone.**\r\n\r\n  Two new pages are added to the Companion's display, accessible without a phone or app.\r\n\r\n  #### Button controls\r\n\r\n  - **Single click / Double click** — navigate between pages (next / previous)\r\n  - **Long press on FIRST page** — reopen unread message preview (up to 32 messages buffered)\r\n  - **Long press** on Quick Send or Settings — enter the page; active item highlights\r\n    - Single click = next item · Double click = exit · Long press = confirm\r\n\r\n  #### Quick Send\r\n\r\n  Send a short status message directly over LoRa to the public channel — no typing, no phone needed. Useful when your phone is dead or unavailable.\r\n\r\n  GPS coordinates are automatically appended if available (e.g. `I'm OK @10.7769,106.7009`). If GPS has no current fix, last known coordinates are used with a `?` prefix so you know before sending.\r\n\r\n  **10 built-in presets:**\r\n  - I'm OK\r\n  - On my way\r\n  - I need help\r\n  - Everyone OK here\r\n  - Wait for me\r\n  - Heading home\r\n  - Running late\r\n  - Lost contact, call me\r\n  - Battery low, signing off\r\n  - All clear\r\n\r\n  **Customize via TerminalCLI** — changes are saved to flash and persist after reboot:\r\n  ```\r\n  get quick                        list all current presets\r\n  set quick.0 Arrived at camp      set preset at index 0\r\n  set quick.reset                  restore all 10 built-in defaults\r\n  ```\r\n\r\n  #### Settings\r\n\r\n  A scrollable list of device settings, controlled directly from the button:\r\n\r\n  | Item | Action |\r\n  |---|---|\r\n  | BLE | Toggle Bluetooth on/off (shows connection state) |\r\n  | Repeat | Toggle repeat mode on/off |\r\n  | RxGain | Cycle RxGain mode: OFF → ON → AUTO *(AUTO: V4.2 only)* |\r\n  | Buzzer | Toggle buzzer on/muted *(boards with buzzer only)* |\r\n  | Send Advert | Broadcast your presence to nearby nodes |\r\n  | Start OTA | Start OTA update mode — connect to `MeshCore-OTA` WiFi and go to `192.168.4.1/update` |\r\n  | Shutdown | Power off the device |\r\n\r\n- **Heltec V4.3 support (KCT8103L FEM).**\r\n  Firmware automatically detects V4.2 / V4.3 at boot — no configuration required. V4.3 replaces the GC1109 FEM with KCT8103L, which supports explicit LNA/bypass RX mode selection via `radio.rxgain`.\r\n\r\n  | Mode | Description |\r\n  |---|---|\r\n  | `on` *(default)* | FEM LNA active — best sensitivity |\r\n  | `off` | FEM bypass — SX1262 boosted gain compensates, better in high-interference environments near strong transmitters |\r\n\r\n  > V4.3 does **not** support `auto` mode — use `on` or `off`.\r\n\r\n  **TerminalCLI** (Companion app), **Command Line** (Repeater / Room Server):\r\n  ```\r\n  set radio.rxgain on\r\n  set radio.rxgain off\r\n  get radio.rxgain\r\n  ```\r\n  \r\n  Setting is saved and restored after reboot.\r\n\r\n- **Unified firmware for \"No Display\" hardware variants.**\r\n\r\n  A single firmware binary now runs on both OLED and no-display hardware — no separate build required. The display is detected automatically at boot via I2C probe.\r\n\r\n  | Hardware | Detected as |\r\n  |---|---|\r\n  | Heltec V4.2 with OLED | Heltec V4.2 OLED |\r\n  | Heltec V4.2 without OLED | Heltec V4.2 No Display |\r\n  | Heltec V4.3 with OLED | Heltec V4.3 OLED |\r\n  | Heltec V4.3 without OLED | Heltec V4.3 No Display |\r\n\r\n  The device name shown in the MeshCore app reflects the actual hardware detected. On no-display hardware, the user button has no effect (previously it could trigger unintended I2C writes).",
          "notesHtml": "<h3>v1.14_0404</h3>\n<ul>\n<li><p><strong>Quick Send and Settings — control your Companion without a phone.</strong></p>\n<p>Two new pages are added to the Companion's display, accessible without a phone or app.</p>\n<h4>Button controls</h4>\n<ul>\n<li><strong>Single click / Double click</strong> — navigate between pages (next / previous)</li>\n<li><strong>Long press on FIRST page</strong> — reopen unread message preview (up to 32 messages buffered)</li>\n<li><strong>Long press</strong> on Quick Send or Settings — enter the page; active item highlights<ul>\n<li>Single click = next item · Double click = exit · Long press = confirm</li>\n</ul>\n</li>\n</ul>\n<h4>Quick Send</h4>\n<p>Send a short status message directly over LoRa to the public channel — no typing, no phone needed. Useful when your phone is dead or unavailable.</p>\n<p>GPS coordinates are automatically appended if available (e.g. <code>I'm OK @10.7769,106.7009</code>). If GPS has no current fix, last known coordinates are used with a <code>?</code> prefix so you know before sending.</p>\n<p><strong>10 built-in presets:</strong></p>\n<ul>\n<li>I'm OK</li>\n<li>On my way</li>\n<li>I need help</li>\n<li>Everyone OK here</li>\n<li>Wait for me</li>\n<li>Heading home</li>\n<li>Running late</li>\n<li>Lost contact, call me</li>\n<li>Battery low, signing off</li>\n<li>All clear</li>\n</ul>\n<p><strong>Customize via TerminalCLI</strong> — changes are saved to flash and persist after reboot:</p>\n<pre><code>get quick                        list all current presets\nset quick.0 Arrived at camp      set preset at index 0\nset quick.reset                  restore all 10 built-in defaults\n</code></pre>\n<h4>Settings</h4>\n<p>A scrollable list of device settings, controlled directly from the button:</p>\n<table>\n<thead>\n<tr>\n<th>Item</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>BLE</td>\n<td>Toggle Bluetooth on/off (shows connection state)</td>\n</tr>\n<tr>\n<td>Repeat</td>\n<td>Toggle repeat mode on/off</td>\n</tr>\n<tr>\n<td>RxGain</td>\n<td>Cycle RxGain mode: OFF → ON → AUTO <em>(AUTO: V4.2 only)</em></td>\n</tr>\n<tr>\n<td>Buzzer</td>\n<td>Toggle buzzer on/muted <em>(boards with buzzer only)</em></td>\n</tr>\n<tr>\n<td>Send Advert</td>\n<td>Broadcast your presence to nearby nodes</td>\n</tr>\n<tr>\n<td>Start OTA</td>\n<td>Start OTA update mode — connect to <code>MeshCore-OTA</code> WiFi and go to <code>192.168.4.1/update</code></td>\n</tr>\n<tr>\n<td>Shutdown</td>\n<td>Power off the device</td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>Heltec V4.3 support (KCT8103L FEM).</strong>\nFirmware automatically detects V4.2 / V4.3 at boot — no configuration required. V4.3 replaces the GC1109 FEM with KCT8103L, which supports explicit LNA/bypass RX mode selection via <code>radio.rxgain</code>.</p>\n<table>\n<thead>\n<tr>\n<th>Mode</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>on</code> <em>(default)</em></td>\n<td>FEM LNA active — best sensitivity</td>\n</tr>\n<tr>\n<td><code>off</code></td>\n<td>FEM bypass — SX1262 boosted gain compensates, better in high-interference environments near strong transmitters</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p>V4.3 does <strong>not</strong> support <code>auto</code> mode — use <code>on</code> or <code>off</code>.</p>\n</blockquote>\n<p><strong>TerminalCLI</strong> (Companion app), <strong>Command Line</strong> (Repeater / Room Server):</p>\n<pre><code>set radio.rxgain on\nset radio.rxgain off\nget radio.rxgain\n</code></pre>\n<p>Setting is saved and restored after reboot.</p>\n</li>\n<li><p><strong>Unified firmware for \"No Display\" hardware variants.</strong></p>\n<p>A single firmware binary now runs on both OLED and no-display hardware — no separate build required. The display is detected automatically at boot via I2C probe.</p>\n<table>\n<thead>\n<tr>\n<th>Hardware</th>\n<th>Detected as</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Heltec V4.2 with OLED</td>\n<td>Heltec V4.2 OLED</td>\n</tr>\n<tr>\n<td>Heltec V4.2 without OLED</td>\n<td>Heltec V4.2 No Display</td>\n</tr>\n<tr>\n<td>Heltec V4.3 with OLED</td>\n<td>Heltec V4.3 OLED</td>\n</tr>\n<tr>\n<td>Heltec V4.3 without OLED</td>\n<td>Heltec V4.3 No Display</td>\n</tr>\n</tbody></table>\n<p>The device name shown in the MeshCore app reflects the actual hardware detected. On no-display hardware, the user button has no effect (previously it could trigger unintended I2C writes).</p>\n</li>\n</ul>\n"
        },
        {
          "version": "Heltec-V3-WSL3-low-power-v1.14_0404",
          "name": "Heltec V3 & WSL3 low power - v1.14_0404",
          "datetime": "2026-04-04T10:47:33Z",
          "url": "https://github.com/dt267/MeshCore-Low-Power-Firmware-For-Heltec-V3-V4/releases/tag/Heltec-V3-WSL3-low-power-v1.14_0404",
          "prerelease": false,
          "notes": "### v1.14_0404\r\n\r\n- **Quick Send and Settings — control your Companion without a phone.**\r\n\r\n  Two new pages are added to the Companion's display, accessible without a phone or app.\r\n\r\n  #### Button controls\r\n\r\n  - **Single click / Double click** — navigate between pages (next / previous)\r\n  - **Long press on FIRST page** — reopen unread message preview (up to 32 messages buffered)\r\n  - **Long press** on Quick Send or Settings — enter the page; active item highlights\r\n    - Single click = next item · Double click = exit · Long press = confirm\r\n\r\n  #### Quick Send\r\n\r\n  Send a short status message directly over LoRa to the public channel — no typing, no phone needed. Useful when your phone is dead or unavailable.\r\n\r\n  GPS coordinates are automatically appended if available (e.g. `I'm OK @10.7769,106.7009`). If GPS has no current fix, last known coordinates are used with a `?` prefix so you know before sending.\r\n\r\n  **10 built-in presets:**\r\n  - I'm OK\r\n  - On my way\r\n  - I need help\r\n  - Everyone OK here\r\n  - Wait for me\r\n  - Heading home\r\n  - Running late\r\n  - Lost contact, call me\r\n  - Battery low, signing off\r\n  - All clear\r\n\r\n  **Customize via TerminalCLI** — changes are saved to flash and persist after reboot:\r\n  ```\r\n  get quick                        list all current presets\r\n  set quick.0 Arrived at camp      set preset at index 0\r\n  set quick.reset                  restore all 10 built-in defaults\r\n  ```\r\n\r\n  #### Settings\r\n\r\n  A scrollable list of device settings, controlled directly from the button:\r\n\r\n  | Item | Action |\r\n  |---|---|\r\n  | BLE | Toggle Bluetooth on/off (shows connection state) |\r\n  | Repeat | Toggle repeat mode on/off |\r\n  | RxGain | Cycle RxGain mode: OFF → ON → AUTO *(AUTO: V4.2 only)* |\r\n  | Buzzer | Toggle buzzer on/muted *(boards with buzzer only)* |\r\n  | Send Advert | Broadcast your presence to nearby nodes |\r\n  | Start OTA | Start OTA update mode — connect to `MeshCore-OTA` WiFi and go to `192.168.4.1/update` |\r\n  | Shutdown | Power off the device |\r\n\r\n- **Unified firmware for \"No Display\" hardware variants.**\r\n\r\n  A single firmware binary now runs on both OLED and no-display hardware — no separate build required. The display is detected automatically at boot via I2C probe.\r\n\r\n  | Hardware | Detected as |\r\n  |---|---|\r\n  | Heltec V3 with OLED | Heltec V3 |\r\n  | Heltec WSL3 (no OLED) | Heltec WSL3 |\r\n\r\n  The device name shown in the MeshCore app reflects the actual hardware detected. On no-display hardware, the user button has no effect (previously it could trigger unintended I2C writes).",
          "notesHtml": "<h3>v1.14_0404</h3>\n<ul>\n<li><p><strong>Quick Send and Settings — control your Companion without a phone.</strong></p>\n<p>Two new pages are added to the Companion's display, accessible without a phone or app.</p>\n<h4>Button controls</h4>\n<ul>\n<li><strong>Single click / Double click</strong> — navigate between pages (next / previous)</li>\n<li><strong>Long press on FIRST page</strong> — reopen unread message preview (up to 32 messages buffered)</li>\n<li><strong>Long press</strong> on Quick Send or Settings — enter the page; active item highlights<ul>\n<li>Single click = next item · Double click = exit · Long press = confirm</li>\n</ul>\n</li>\n</ul>\n<h4>Quick Send</h4>\n<p>Send a short status message directly over LoRa to the public channel — no typing, no phone needed. Useful when your phone is dead or unavailable.</p>\n<p>GPS coordinates are automatically appended if available (e.g. <code>I'm OK @10.7769,106.7009</code>). If GPS has no current fix, last known coordinates are used with a <code>?</code> prefix so you know before sending.</p>\n<p><strong>10 built-in presets:</strong></p>\n<ul>\n<li>I'm OK</li>\n<li>On my way</li>\n<li>I need help</li>\n<li>Everyone OK here</li>\n<li>Wait for me</li>\n<li>Heading home</li>\n<li>Running late</li>\n<li>Lost contact, call me</li>\n<li>Battery low, signing off</li>\n<li>All clear</li>\n</ul>\n<p><strong>Customize via TerminalCLI</strong> — changes are saved to flash and persist after reboot:</p>\n<pre><code>get quick                        list all current presets\nset quick.0 Arrived at camp      set preset at index 0\nset quick.reset                  restore all 10 built-in defaults\n</code></pre>\n<h4>Settings</h4>\n<p>A scrollable list of device settings, controlled directly from the button:</p>\n<table>\n<thead>\n<tr>\n<th>Item</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>BLE</td>\n<td>Toggle Bluetooth on/off (shows connection state)</td>\n</tr>\n<tr>\n<td>Repeat</td>\n<td>Toggle repeat mode on/off</td>\n</tr>\n<tr>\n<td>RxGain</td>\n<td>Cycle RxGain mode: OFF → ON → AUTO <em>(AUTO: V4.2 only)</em></td>\n</tr>\n<tr>\n<td>Buzzer</td>\n<td>Toggle buzzer on/muted <em>(boards with buzzer only)</em></td>\n</tr>\n<tr>\n<td>Send Advert</td>\n<td>Broadcast your presence to nearby nodes</td>\n</tr>\n<tr>\n<td>Start OTA</td>\n<td>Start OTA update mode — connect to <code>MeshCore-OTA</code> WiFi and go to <code>192.168.4.1/update</code></td>\n</tr>\n<tr>\n<td>Shutdown</td>\n<td>Power off the device</td>\n</tr>\n</tbody></table>\n</li>\n<li><p><strong>Unified firmware for \"No Display\" hardware variants.</strong></p>\n<p>A single firmware binary now runs on both OLED and no-display hardware — no separate build required. The display is detected automatically at boot via I2C probe.</p>\n<table>\n<thead>\n<tr>\n<th>Hardware</th>\n<th>Detected as</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Heltec V3 with OLED</td>\n<td>Heltec V3</td>\n</tr>\n<tr>\n<td>Heltec WSL3 (no OLED)</td>\n<td>Heltec WSL3</td>\n</tr>\n</tbody></table>\n<p>The device name shown in the MeshCore app reflects the actual hardware detected. On no-display hardware, the user button has no effect (previously it could trigger unintended I2C writes).</p>\n</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:33.826Z"
    },
    {
      "id": "meshcore-solo",
      "name": "MeshCore Solo",
      "type": "fork",
      "maintainer": "MarekZegare4",
      "maintainers": [
        {
          "name": "MarekZegare4",
          "url": "https://github.com/MarekZegare4"
        }
      ],
      "maintainerUrl": "https://github.com/MarekZegare4",
      "repository": "https://github.com/MarekZegare4/MeshCore-Solo",
      "website": "https://marekzegare4.github.io/Solo-tools/",
      "license": "MIT",
      "description": "A fork of the official MeshCore companion radio firmware with extended features and UI enhancements. Adds GPS navigation (waypoints, compass, trail recording with GPX export), battery power-saving (hardware RX duty-cycle + adaptive power control), favourite contacts dial, extended language support with native Unicode rendering, message delivery status, screen lock, auto-reply bot, repeater mode with diagnostics, and more — all optimized for joystick-only navigation on small displays.\n",
      "status": "active",
      "lifecycle": "active",
      "maturity": "stable",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "standalone-ui"
      ],
      "features": [
        "Extended Unicode support with Lemon font and native input",
        "GPS navigation suite (waypoints, compass, backtrack, trail recording)",
        "GPX export via USB serial",
        "Screenshot capture over USB",
        "Favourites dial for pinned contacts",
        "Message delivery status indicators",
        "DM auto-resend and incoming deduplication",
        "Screen lock with time and sensor display",
        "Auto-reply bot with command responses",
        "Auto-advert for location sharing",
        "Battery power saving (RX duty-cycle + APC)",
        "Companion repeater mode with diagnostics",
        "Ping functionality in Nearby Nodes",
        "SOS broadcast with configurable target",
        "Quiet hours for sound suppression",
        "Mark-all-read at type level",
        "Lock-screen unread count",
        "Channel scanner home page",
        "Contact distance sorting",
        "Signal stats screen",
        "Display test pattern",
        "Power profile presets",
        "Solo Tools web app for screenshot capture and GPX export (https://marekzegare4.github.io/Solo-tools/)"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true,
          "rawPacketSend": true,
          "rawPacketObserve": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": false,
          "wifiAp": false
        },
        "operations": {
          "webFlasher": false,
          "ota": false,
          "bleDfu": false,
          "configurationBackup": true
        },
        "networking": {
          "repeater": true,
          "roomServer": false,
          "observer": false,
          "mqtt": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": true,
          "lowPowerRx": true
        }
      },
      "changelog": {
        "source": "github",
        "repo": "MarekZegare4/MeshCore-Solo"
      },
      "devices": [
        {
          "id": "wio-tracker-l1",
          "status": "supported",
          "target": "wio-tracker-l1",
          "platformio_board": "seeed-wio-tracker-l1",
          "notes": "OLED variant (SSD1306/SH1106 128x64)"
        },
        {
          "id": "wio-tracker-l1-pro",
          "status": "supported",
          "target": "wio-tracker-l1",
          "platformio_board": "seeed-wio-tracker-l1",
          "notes": "OLED variant — same firmware target as wio-tracker-l1"
        },
        {
          "id": "wio-tracker-l1-eink",
          "status": "supported",
          "target": "wio-tracker-l1-eink",
          "platformio_board": "seeed-wio-tracker-l1",
          "notes": "E-ink variant (GxEPD2 250x122)"
        },
        {
          "id": "gatiot-gat562-30s",
          "status": "supported",
          "target": "gat562_30s_mesh_kit",
          "platformio_board": "rak4631",
          "notes": "GAT562 30S Mesh Kit"
        }
      ],
      "latest_version": "1.19",
      "released": "2026-06-16",
      "releases": [
        {
          "version": "v1.19",
          "name": "Solo v1.19",
          "datetime": "2026-06-16T08:11:43Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.19",
          "prerelease": false,
          "notes": "## MeshCore Solo Companion Firmware v1.19\r\n\r\n### What's new\r\n\r\n- **Message delivery status** — outgoing messages now show an end-to-end delivery marker, auto-scaled to the font (legible on landscape e-ink), in both the history list and the fullscreen view:\r\n  - **Direct messages** (and room servers): pending → delivered (✓) → failed (✗), driven by the real end-to-end ACK. While pending, a row of dots shows one per send so auto-resend progress is visible.\r\n  - **Auto-resend** — a pending DM whose ACK times out is re-sent automatically (reusing the original timestamp) until resends run out. Configurable count under Settings › Messages › Resend (0–5, default 2). Runs in the background, independent of which screen is open; incoming duplicates from retries are dropped.\r\n  - **Channels** — ✓ appears only once a repeater echo confirms the message was relayed into the mesh. No echo is normal (flood has no recipient ACK), so no pending/fail is shown.\r\n- **Auto-reply bot overhaul** — the trigger/reply bot grows into a small auto-responder:\r\n  - **Query commands** — a DM or monitored-channel message is scanned for `!` tokens (`!ping !batt !loc !time !temp !hops !status !help`) and answered in one combined reply.\r\n  - **Away / reply-to-all** — a lone `*` trigger replies to every message.\r\n  - **Separate DM and channel triggers**, each with its own reply text.\r\n  - **Quiet hours** — silence push replies during a chosen window (wraps midnight).\r\n  - **Throttling & anti-loop** — per-contact DM throttle so one sender can't starve others; channel echo guard so the bot never answers itself; reply counter shown in the bot screen header.\r\n- **Keyboard overhaul** — one shared keyboard across all screens (reclaims duplicate RAM), icon keys (⇧ caps, ⎵ space, ⌫ delete, ✓ OK), and a second **symbols page** toggled with `#@`/`abc`.\r\n- **UI refresh**\r\n  - Proportional **scrollbar** with up/down triangle caps replaces the old `^`/`v` arrows, scaling with the font (1× OLED, 2× landscape e-ink); used by every scrollable list and the fullscreen message view. The redundant `>` selection marker is gone and rows shifted left to reclaim space.\r\n  - Status-bar single-letter indicators (M/B/A/G) replaced with scalable **mini-icons** (mute, bluetooth, advert, trail).\r\n- **Nearby Nodes reorganized** — one list over two sources (stored contacts + live discover scan) with a unified detail/action menu. Type filter and sort are independent axes and persist across re-entry; the active filter is shown in the title and in empty-list messages.\r\n- **Tools › Trail reorganized** — a short two-level action menu (Hold Enter) replaces the flat ~12-item list; view-aware settings; a fitted **square map grid**; and the waypoint manager split out into its own component. No change to trail recording itself.\r\n- **OTA updates** — each solo release now ships a DFU `.zip` (`solo-<ver>-<device>-ota.zip`) for over-the-air / BLE-DFU updates, alongside the `.uf2` for USB flashing.\r\n\r\n### Fixes\r\n\r\n- **GPS battery drain on shutdown** — GPS is powered off before `SYSTEMOFF`, and uses the correct active-level (`!PIN_GPS_EN_ACTIVE`) instead of a hardcoded level.\r\n- **Buzzer octave 8** — the RTTTL parser now fully accepts octave 8 instead of clamping it away (which could leak a digit into the next note's duration).\r\n- **Trail file robustness** — `Waypoint`/trail readers check every header read, so a truncated file is rejected instead of using a garbage count.\r\n\r\n### Under the hood\r\n\r\n- OTA DFU zip is named and attached to releases by the `_solo_dual` build workflow; the per-build Actions artifact already carried it.\r\n- Large UI consolidation: shared `drawList` / header / key-decode helpers, deduplicated status-bar indicators, reusable scalable mini-icon facility (`icons.h`), and an audit-pass cleanup premoving dead code and redundant scroll-clamp logic.",
          "notesHtml": "<h2>MeshCore Solo Companion Firmware v1.19</h2>\n<h3>What's new</h3>\n<ul>\n<li><strong>Message delivery status</strong> — outgoing messages now show an end-to-end delivery marker, auto-scaled to the font (legible on landscape e-ink), in both the history list and the fullscreen view:<ul>\n<li><strong>Direct messages</strong> (and room servers): pending → delivered (✓) → failed (✗), driven by the real end-to-end ACK. While pending, a row of dots shows one per send so auto-resend progress is visible.</li>\n<li><strong>Auto-resend</strong> — a pending DM whose ACK times out is re-sent automatically (reusing the original timestamp) until resends run out. Configurable count under Settings › Messages › Resend (0–5, default 2). Runs in the background, independent of which screen is open; incoming duplicates from retries are dropped.</li>\n<li><strong>Channels</strong> — ✓ appears only once a repeater echo confirms the message was relayed into the mesh. No echo is normal (flood has no recipient ACK), so no pending/fail is shown.</li>\n</ul>\n</li>\n<li><strong>Auto-reply bot overhaul</strong> — the trigger/reply bot grows into a small auto-responder:<ul>\n<li><strong>Query commands</strong> — a DM or monitored-channel message is scanned for <code>!</code> tokens (<code>!ping !batt !loc !time !temp !hops !status !help</code>) and answered in one combined reply.</li>\n<li><strong>Away / reply-to-all</strong> — a lone <code>*</code> trigger replies to every message.</li>\n<li><strong>Separate DM and channel triggers</strong>, each with its own reply text.</li>\n<li><strong>Quiet hours</strong> — silence push replies during a chosen window (wraps midnight).</li>\n<li><strong>Throttling &amp; anti-loop</strong> — per-contact DM throttle so one sender can't starve others; channel echo guard so the bot never answers itself; reply counter shown in the bot screen header.</li>\n</ul>\n</li>\n<li><strong>Keyboard overhaul</strong> — one shared keyboard across all screens (reclaims duplicate RAM), icon keys (⇧ caps, ⎵ space, ⌫ delete, ✓ OK), and a second <strong>symbols page</strong> toggled with <code>#@</code>/<code>abc</code>.</li>\n<li><strong>UI refresh</strong><ul>\n<li>Proportional <strong>scrollbar</strong> with up/down triangle caps replaces the old <code>^</code>/<code>v</code> arrows, scaling with the font (1× OLED, 2× landscape e-ink); used by every scrollable list and the fullscreen message view. The redundant <code>&gt;</code> selection marker is gone and rows shifted left to reclaim space.</li>\n<li>Status-bar single-letter indicators (M/B/A/G) replaced with scalable <strong>mini-icons</strong> (mute, bluetooth, advert, trail).</li>\n</ul>\n</li>\n<li><strong>Nearby Nodes reorganized</strong> — one list over two sources (stored contacts + live discover scan) with a unified detail/action menu. Type filter and sort are independent axes and persist across re-entry; the active filter is shown in the title and in empty-list messages.</li>\n<li><strong>Tools › Trail reorganized</strong> — a short two-level action menu (Hold Enter) replaces the flat ~12-item list; view-aware settings; a fitted <strong>square map grid</strong>; and the waypoint manager split out into its own component. No change to trail recording itself.</li>\n<li><strong>OTA updates</strong> — each solo release now ships a DFU <code>.zip</code> (<code>solo-&lt;ver&gt;-&lt;device&gt;-ota.zip</code>) for over-the-air / BLE-DFU updates, alongside the <code>.uf2</code> for USB flashing.</li>\n</ul>\n<h3>Fixes</h3>\n<ul>\n<li><strong>GPS battery drain on shutdown</strong> — GPS is powered off before <code>SYSTEMOFF</code>, and uses the correct active-level (<code>!PIN_GPS_EN_ACTIVE</code>) instead of a hardcoded level.</li>\n<li><strong>Buzzer octave 8</strong> — the RTTTL parser now fully accepts octave 8 instead of clamping it away (which could leak a digit into the next note's duration).</li>\n<li><strong>Trail file robustness</strong> — <code>Waypoint</code>/trail readers check every header read, so a truncated file is rejected instead of using a garbage count.</li>\n</ul>\n<h3>Under the hood</h3>\n<ul>\n<li>OTA DFU zip is named and attached to releases by the <code>_solo_dual</code> build workflow; the per-build Actions artifact already carried it.</li>\n<li>Large UI consolidation: shared <code>drawList</code> / header / key-decode helpers, deduplicated status-bar indicators, reusable scalable mini-icon facility (<code>icons.h</code>), and an audit-pass cleanup premoving dead code and redundant scroll-clamp logic.</li>\n</ul>\n"
        },
        {
          "version": "v1.18",
          "name": "Solo v1.18",
          "datetime": "2026-06-14T08:22:51Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.18",
          "prerelease": false,
          "notes": "## MeshCore Solo Companion Firmware v1.18\r\n\r\n### New device support\r\n\r\n- **GAT562 30S Mesh Kit** — the firmware now supports the GAT562 30S alongside the Wio Tracker L1 family. Pre-built `.uf2` files for all supported devices are published with each release — see the [Supported Devices](https://github.com/MarekZegare4/MeshCore-Solo#supported-devices) table.\r\n\r\n### What's new\r\n\r\n- **GAT562 30S Mesh Kit support** — see above.\r\n- **Battery saving (radio)** — two new independent toggles under Settings › Radio:\r\n  - **Pwr save** — hardware duty-cycle receive (SX126x `SetRxDutyCycle`): the radio cycles RX↔sleep autonomously and wakes on a preamble, cutting average RX current with only a small increase in receive latency\r\n  - **Auto pwr** — Adaptive Power Control: trims TX power on strong links (based on ACK SNR) and ramps back up on weak or lost links; the home screen shows the live transmit power\r\n- **BLE disconnect icon fix** — the BLE status icon now updates immediately when the connection drops (e.g. out of range, supervision timeout). Previously it could stay active until the next UI polling cycle.\r\n- **Bot trigger preserves case** — the auto-reply trigger phrase is now stored exactly as typed. Matching remains case-insensitive, so `Ping`, `ping` and `PING` all trigger the bot, but the trigger no longer gets silently lowercased when saved.\r\n- **Screenshot support in all solo builds** — `ENABLE_SCREENSHOT` is now enabled in every solo firmware build. No need to use a separate `_dev` environment. Use the [Solo Tools](https://marekzegare4.github.io/Solo-tools/) web app to capture screenshots directly from the browser.\r\n\r\n\r\n### Under the hood\r\n\r\n- CI matrix for solo firmware builds is now fully dynamic — new devices are picked up automatically from `platformio.ini` based on the `_solo_dual` env suffix, no workflow changes required.\r\n- `AbstractUITask::onBLEDisconnected()` virtual hook added — called by `setHasConnection()` on transition to disconnected; `UITask` overrides it to set `_next_refresh = 0`.\r\n- `build.sh` gains `build-solo-firmwares` command, backed by `build_all_firmwares_by_suffix \"_solo_dual\"`.",
          "notesHtml": "<h2>MeshCore Solo Companion Firmware v1.18</h2>\n<h3>New device support</h3>\n<ul>\n<li><strong>GAT562 30S Mesh Kit</strong> — the firmware now supports the GAT562 30S alongside the Wio Tracker L1 family. Pre-built <code>.uf2</code> files for all supported devices are published with each release — see the <a href=\"https://github.com/MarekZegare4/MeshCore-Solo#supported-devices\" target=\"_blank\" rel=\"noopener noreferrer\">Supported Devices</a> table.</li>\n</ul>\n<h3>What's new</h3>\n<ul>\n<li><strong>GAT562 30S Mesh Kit support</strong> — see above.</li>\n<li><strong>Battery saving (radio)</strong> — two new independent toggles under Settings › Radio:<ul>\n<li><strong>Pwr save</strong> — hardware duty-cycle receive (SX126x <code>SetRxDutyCycle</code>): the radio cycles RX↔sleep autonomously and wakes on a preamble, cutting average RX current with only a small increase in receive latency</li>\n<li><strong>Auto pwr</strong> — Adaptive Power Control: trims TX power on strong links (based on ACK SNR) and ramps back up on weak or lost links; the home screen shows the live transmit power</li>\n</ul>\n</li>\n<li><strong>BLE disconnect icon fix</strong> — the BLE status icon now updates immediately when the connection drops (e.g. out of range, supervision timeout). Previously it could stay active until the next UI polling cycle.</li>\n<li><strong>Bot trigger preserves case</strong> — the auto-reply trigger phrase is now stored exactly as typed. Matching remains case-insensitive, so <code>Ping</code>, <code>ping</code> and <code>PING</code> all trigger the bot, but the trigger no longer gets silently lowercased when saved.</li>\n<li><strong>Screenshot support in all solo builds</strong> — <code>ENABLE_SCREENSHOT</code> is now enabled in every solo firmware build. No need to use a separate <code>_dev</code> environment. Use the <a href=\"https://marekzegare4.github.io/Solo-tools/\" target=\"_blank\" rel=\"noopener noreferrer\">Solo Tools</a> web app to capture screenshots directly from the browser.</li>\n</ul>\n<h3>Under the hood</h3>\n<ul>\n<li>CI matrix for solo firmware builds is now fully dynamic — new devices are picked up automatically from <code>platformio.ini</code> based on the <code>_solo_dual</code> env suffix, no workflow changes required.</li>\n<li><code>AbstractUITask::onBLEDisconnected()</code> virtual hook added — called by <code>setHasConnection()</code> on transition to disconnected; <code>UITask</code> overrides it to set <code>_next_refresh = 0</code>.</li>\n<li><code>build.sh</code> gains <code>build-solo-firmwares</code> command, backed by <code>build_all_firmwares_by_suffix \"_solo_dual\"</code>.</li>\n</ul>\n"
        },
        {
          "version": "v1.17",
          "name": "Solo v1.17",
          "datetime": "2026-06-09T15:33:39Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.17",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Solo Firmware v1.17\r\n\r\n### What's new\r\n\r\n- **Nearby Nodes — navigate & save waypoints from the list** — the context menu now exposes _Navigate_ and _Save waypoint_ directly from the Nearby list and detail view, so you no longer have to open the separate Tools → Waypoints screen. Long-press Options in the detail view also opens a _Ping_ submenu.\r\n- **Nearby Nodes — TIME sort filter** — a new `[TIME]` filter sorts contacts by last-seen time (most recent first) instead of distance, useful when GPS is unavailable.\r\n- **Battery indicator calibrated** — the 100 % ceiling of the LiPo discharge curve was corrected from 4200 mV to 4170 mV, matching what the board's charger actually delivers.\r\n- **Advert sound scope control** — a new _Sound → Advert_ setting lets you choose whether advert notifications play for all nodes or only direct (zero-hop) neighbours, cutting noise on busy meshes.\r\n- **Sound slot \"None\" option** — DM, channel and advert melody slots can now be set to _None_ to silence that notification category entirely without muting everything.\r\n- **Mark-as-read feedback** — marking messages read (per-contact or per-channel) now shows a brief _\"N marked read\"_ confirmation on screen.\r\n- **[Web tool] GPX Downloader** — a standalone web page for downloading saved GPX trails from the device over the browser's Web Serial API, no desktop app required.\r\n\r\n### Under the hood\r\n\r\n- `SoundNotifier` extracted from `UITask::notify()` — all buzzer/melody logic lives in one place, reducing future merge conflict surface with upstream.\r\n- `KeyboardWidget` is now a single shared instance across screens (saves ~1.5 KB heap).\r\n- `onDiscoveredAdvert` extracted as a separate virtual so upstream `onDiscoveredContact` keeps its original 4-parameter signature.",
          "notesHtml": "<h2>Wio Tracker L1 — Solo Firmware v1.17</h2>\n<h3>What's new</h3>\n<ul>\n<li><strong>Nearby Nodes — navigate &amp; save waypoints from the list</strong> — the context menu now exposes <em>Navigate</em> and <em>Save waypoint</em> directly from the Nearby list and detail view, so you no longer have to open the separate Tools → Waypoints screen. Long-press Options in the detail view also opens a <em>Ping</em> submenu.</li>\n<li><strong>Nearby Nodes — TIME sort filter</strong> — a new <code>[TIME]</code> filter sorts contacts by last-seen time (most recent first) instead of distance, useful when GPS is unavailable.</li>\n<li><strong>Battery indicator calibrated</strong> — the 100 % ceiling of the LiPo discharge curve was corrected from 4200 mV to 4170 mV, matching what the board's charger actually delivers.</li>\n<li><strong>Advert sound scope control</strong> — a new <em>Sound → Advert</em> setting lets you choose whether advert notifications play for all nodes or only direct (zero-hop) neighbours, cutting noise on busy meshes.</li>\n<li><strong>Sound slot \"None\" option</strong> — DM, channel and advert melody slots can now be set to <em>None</em> to silence that notification category entirely without muting everything.</li>\n<li><strong>Mark-as-read feedback</strong> — marking messages read (per-contact or per-channel) now shows a brief <em>\"N marked read\"</em> confirmation on screen.</li>\n<li><strong>[Web tool] GPX Downloader</strong> — a standalone web page for downloading saved GPX trails from the device over the browser's Web Serial API, no desktop app required.</li>\n</ul>\n<h3>Under the hood</h3>\n<ul>\n<li><code>SoundNotifier</code> extracted from <code>UITask::notify()</code> — all buzzer/melody logic lives in one place, reducing future merge conflict surface with upstream.</li>\n<li><code>KeyboardWidget</code> is now a single shared instance across screens (saves ~1.5 KB heap).</li>\n<li><code>onDiscoveredAdvert</code> extracted as a separate virtual so upstream <code>onDiscoveredContact</code> keeps its original 4-parameter signature.</li>\n</ul>\n"
        },
        {
          "version": "v1.16",
          "name": "Solo v1.16",
          "datetime": "2026-06-06T16:35:39Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.16",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Solo Firmware v1.16\r\n\r\nRebases the Solo fork onto upstream MeshCore **v1.16.0** (254 commits)\r\n\r\n### What's new (from upstream)\r\n\r\n- **NRF52 power-saving** — the companion now puts the MCU to sleep whenever there's no pending work, instead of looping continuously between events.\r\n- **Better reception of longer messages at low spreading factors** — the LoRa preamble is now 32 (was 16) for SF below 9, which makes longer frames more reliable on weak links.\r\n- **More robust sensors** — the I²C sensor subsystem was rewritten to probe the bus before touching any device, so an absent or misbehaving sensor can no longer hang or crash the node.\r\n- **Charging-aware shutdown** — the device no longer auto-shuts-down on low battery while it's on external power, and shows a shutdown warning on OLED.\r\n- **New companion command** for sending raw packets, plus assorted CLI additions (`flood.max.advert`, `flood.max.unscoped`, region hierarchy) and bounds-checking fixes that the phone app and repeaters benefit from.\r\n- **Battery-voltage reading fix** carried in from upstream.",
          "notesHtml": "<h2>Wio Tracker L1 — Solo Firmware v1.16</h2>\n<p>Rebases the Solo fork onto upstream MeshCore <strong>v1.16.0</strong> (254 commits)</p>\n<h3>What's new (from upstream)</h3>\n<ul>\n<li><strong>NRF52 power-saving</strong> — the companion now puts the MCU to sleep whenever there's no pending work, instead of looping continuously between events.</li>\n<li><strong>Better reception of longer messages at low spreading factors</strong> — the LoRa preamble is now 32 (was 16) for SF below 9, which makes longer frames more reliable on weak links.</li>\n<li><strong>More robust sensors</strong> — the I²C sensor subsystem was rewritten to probe the bus before touching any device, so an absent or misbehaving sensor can no longer hang or crash the node.</li>\n<li><strong>Charging-aware shutdown</strong> — the device no longer auto-shuts-down on low battery while it's on external power, and shows a shutdown warning on OLED.</li>\n<li><strong>New companion command</strong> for sending raw packets, plus assorted CLI additions (<code>flood.max.advert</code>, <code>flood.max.unscoped</code>, region hierarchy) and bounds-checking fixes that the phone app and repeaters benefit from.</li>\n<li><strong>Battery-voltage reading fix</strong> carried in from upstream.</li>\n</ul>\n"
        },
        {
          "version": "v1.15.1",
          "name": "Solo v1.15.1",
          "datetime": "2026-06-05T11:31:47Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.15.1",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Solo Firmware v1.15.1\r\n\r\nHotfix for Bluetooth pairing and buzzer regressions in v1.15 (introduced by the Advert-sound change). No schema change — upgrade in place from v1.15.\r\n\r\n### Fixes\r\n\r\n- **Bluetooth pairing PIN is shown again** — on the published OLED + e-ink (dual BLE+USB) builds the pairing PIN was never drawn, so the phone asked for a code that wasn't displayed and pairing failed. The PIN now appears on the **Bluetooth** home page while BLE is on and not yet bonded.\r\n- **Auto buzzer mute works again** — in v1.15 \"Auto\" was effectively always muted on dual builds (the connection state was hardcoded true). It now mutes only when a companion app is actually connected — **BLE bonded or a host holding the USB serial port open** — and stays audible on charge-only / no host. (Plain serial monitors that assert DTR count as connected.)\r\n- **Bluetooth status indicator** — the top-bar BT dot again reflects a real BLE connection instead of showing connected permanently.\r\n- **New-message display wake** — the screen wakes for an incoming message again when no app is connected.\r\n\r\n### Background\r\n\r\nv1.15's advert-sound feature broadened the internal \"connected\" flag from BLE-bonded to *any* transport, but the dual interface always reports its send-fallback as connected — so everything keyed off \"connected\" (PIN prompt, Auto mute, BT indicator, message-wake) misbehaved. This release splits the two notions: BLE-specific UI uses the BLE bond state, while Auto mute / message-wake use a new \"app connected over BLE or USB\" check (USB detected via the CDC DTR line).",
          "notesHtml": "<h2>Wio Tracker L1 — Solo Firmware v1.15.1</h2>\n<p>Hotfix for Bluetooth pairing and buzzer regressions in v1.15 (introduced by the Advert-sound change). No schema change — upgrade in place from v1.15.</p>\n<h3>Fixes</h3>\n<ul>\n<li><strong>Bluetooth pairing PIN is shown again</strong> — on the published OLED + e-ink (dual BLE+USB) builds the pairing PIN was never drawn, so the phone asked for a code that wasn't displayed and pairing failed. The PIN now appears on the <strong>Bluetooth</strong> home page while BLE is on and not yet bonded.</li>\n<li><strong>Auto buzzer mute works again</strong> — in v1.15 \"Auto\" was effectively always muted on dual builds (the connection state was hardcoded true). It now mutes only when a companion app is actually connected — <strong>BLE bonded or a host holding the USB serial port open</strong> — and stays audible on charge-only / no host. (Plain serial monitors that assert DTR count as connected.)</li>\n<li><strong>Bluetooth status indicator</strong> — the top-bar BT dot again reflects a real BLE connection instead of showing connected permanently.</li>\n<li><strong>New-message display wake</strong> — the screen wakes for an incoming message again when no app is connected.</li>\n</ul>\n<h3>Background</h3>\n<p>v1.15's advert-sound feature broadened the internal \"connected\" flag from BLE-bonded to <em>any</em> transport, but the dual interface always reports its send-fallback as connected — so everything keyed off \"connected\" (PIN prompt, Auto mute, BT indicator, message-wake) misbehaved. This release splits the two notions: BLE-specific UI uses the BLE bond state, while Auto mute / message-wake use a new \"app connected over BLE or USB\" check (USB detected via the CDC DTR line).</p>\n"
        },
        {
          "version": "v1.15",
          "name": "Solo v1.15",
          "datetime": "2026-06-04T15:35:06Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.15",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Solo Firmware v1.15\r\n\r\nAdds a full **GPS navigation suite** on top of Solo v1.14 — the L1 becomes a standalone off-grid navigator, no phone required.\r\n\r\n### Highlights\r\n\r\n- **Waypoints** — mark your current spot or type coordinates, give it a short label, then get live bearing + distance back to it. Ideal for car / camp / water / a meeting point.\r\n- **GPS compass** — *Tools › Compass*: a heads-up heading tape derived from GPS course-over-ground. No magnetometer needed.\r\n- **Navigate to anything** — a saved waypoint, the start of your trail (backtrack), a node from Nearby Nodes, or a location someone texts you.\r\n- **Share & save locations over the mesh** — send a waypoint in a message; on the other end, navigate to or save any shared location with one menu.\r\n- **Global Units setting** — one Metric / Imperial switch (Settings › System) drives every distance and speed in the UI.\r\n- **Advert sound** — an optional audible \"in range\" heartbeat: the device chirps when it receives an advert from another node — pair it with Auto-Advert to keep tabs on a buddy hands-free.\r\n\r\n### Changes\r\n\r\n**Navigation (new)**\r\n\r\n- **Waypoints** — *Tools › Trail › Hold Enter*: **Mark here** drops one at the current GPS fix; **Waypoints** opens the list, which carries a synthetic **Trail start** backtrack row, a usage counter (`WAYPOINTS 3/16`), and a **+ Add by coords** row to enter a point by lat/lon/label with no fix required (hemisphere chosen with LEFT/RIGHT since the keyboard has no minus key). Per-waypoint **Rename / Delete / Send**, plus **Clear waypoints**. Stored in their own `/waypoints` file (16 max) — independent of the trail and **not** cleared by Reset trail.\r\n- **Navigate-to-point view** — distance plus two *absolute* bearings, **To:** (target) and **Hdg:** (your course over ground), compared by eye. Reused by waypoints, trail backtrack, Nearby-node navigation and message-shared locations.\r\n- **GPS compass** — *Tools › Compass*: a scrolling N..E..S..W heading tape under a fixed travel-direction pointer, with a large degrees + cardinal readout. Works whether or not a trail is recording.\r\n- **Navigate to a node** — Nearby Nodes detail → **Hold Enter** now opens an Options menu (**Navigate** / **Ping**); Navigate opens the bearing/distance view targeting the node's last-known position.\r\n- **Trail map as a live view** — the Map draws your current position and all waypoints continuously, even with no trail recording. While a trail exists it frames the recorded route and clamps far-off waypoints to the nearest edge (a distant mark can't blow up the scale); with no trail it auto-fits to your waypoints and position. Markers show the first two label characters, placed edge-aware so labels stay on-map.\r\n- **Navigate / save a shared location** — any message carrying a `lat,lon` (what `{loc}` inserts) or a `[WAY]lat,lon label` share offers **Navigate** and **Save waypoint** from its **Hold Enter** menu — on the history row or in fullscreen, for DMs and channels. **Send** on a waypoint shares it to a contact or channel, pre-filling the message to confirm.\r\n- **Waypoints in GPX** — the GPX export now includes saved waypoints as `<wpt>` elements (label → `<name>`, plus `<time>`) alongside the track, so they import as pins in OsmAnd / Garmin / GPX Studio.\r\n\r\n**Units**\r\n\r\n- **Global Metric / Imperial** (Settings › System) drives every distance and speed: Nearby Nodes, Trail (Summary, List deltas, waypoint distances), the navigate-to-point view, the trail min-distance gate (5/10/25/100 m ↔ 15/30/75/300 ft) and the map scale bar.\r\n- **Trail readout** — the action menu's old four-way km/h·mph·min/km·min/mi cycle is now a **Speed / Pace** toggle; the unit follows the global setting.\r\n\r\n**Notifications**\r\n\r\n- **Advert sound** — Settings › Sound gains an **AD sound** entry (built-in / Melody 1 / Melody 2). The device plays it whenever it receives an advert from any node; combined with Auto-Advert on both ends it acts as a hands-free \"still i\n…",
          "notesHtml": "<h2>Wio Tracker L1 — Solo Firmware v1.15</h2>\n<p>Adds a full <strong>GPS navigation suite</strong> on top of Solo v1.14 — the L1 becomes a standalone off-grid navigator, no phone required.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Waypoints</strong> — mark your current spot or type coordinates, give it a short label, then get live bearing + distance back to it. Ideal for car / camp / water / a meeting point.</li>\n<li><strong>GPS compass</strong> — <em>Tools › Compass</em>: a heads-up heading tape derived from GPS course-over-ground. No magnetometer needed.</li>\n<li><strong>Navigate to anything</strong> — a saved waypoint, the start of your trail (backtrack), a node from Nearby Nodes, or a location someone texts you.</li>\n<li><strong>Share &amp; save locations over the mesh</strong> — send a waypoint in a message; on the other end, navigate to or save any shared location with one menu.</li>\n<li><strong>Global Units setting</strong> — one Metric / Imperial switch (Settings › System) drives every distance and speed in the UI.</li>\n<li><strong>Advert sound</strong> — an optional audible \"in range\" heartbeat: the device chirps when it receives an advert from another node — pair it with Auto-Advert to keep tabs on a buddy hands-free.</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>Navigation (new)</strong></p>\n<ul>\n<li><strong>Waypoints</strong> — <em>Tools › Trail › Hold Enter</em>: <strong>Mark here</strong> drops one at the current GPS fix; <strong>Waypoints</strong> opens the list, which carries a synthetic <strong>Trail start</strong> backtrack row, a usage counter (<code>WAYPOINTS 3/16</code>), and a <strong>+ Add by coords</strong> row to enter a point by lat/lon/label with no fix required (hemisphere chosen with LEFT/RIGHT since the keyboard has no minus key). Per-waypoint <strong>Rename / Delete / Send</strong>, plus <strong>Clear waypoints</strong>. Stored in their own <code>/waypoints</code> file (16 max) — independent of the trail and <strong>not</strong> cleared by Reset trail.</li>\n<li><strong>Navigate-to-point view</strong> — distance plus two <em>absolute</em> bearings, <strong>To:</strong> (target) and <strong>Hdg:</strong> (your course over ground), compared by eye. Reused by waypoints, trail backtrack, Nearby-node navigation and message-shared locations.</li>\n<li><strong>GPS compass</strong> — <em>Tools › Compass</em>: a scrolling N..E..S..W heading tape under a fixed travel-direction pointer, with a large degrees + cardinal readout. Works whether or not a trail is recording.</li>\n<li><strong>Navigate to a node</strong> — Nearby Nodes detail → <strong>Hold Enter</strong> now opens an Options menu (<strong>Navigate</strong> / <strong>Ping</strong>); Navigate opens the bearing/distance view targeting the node's last-known position.</li>\n<li><strong>Trail map as a live view</strong> — the Map draws your current position and all waypoints continuously, even with no trail recording. While a trail exists it frames the recorded route and clamps far-off waypoints to the nearest edge (a distant mark can't blow up the scale); with no trail it auto-fits to your waypoints and position. Markers show the first two label characters, placed edge-aware so labels stay on-map.</li>\n<li><strong>Navigate / save a shared location</strong> — any message carrying a <code>lat,lon</code> (what <code>{loc}</code> inserts) or a <code>[WAY]lat,lon label</code> share offers <strong>Navigate</strong> and <strong>Save waypoint</strong> from its <strong>Hold Enter</strong> menu — on the history row or in fullscreen, for DMs and channels. <strong>Send</strong> on a waypoint shares it to a contact or channel, pre-filling the message to confirm.</li>\n<li><strong>Waypoints in GPX</strong> — the GPX export now includes saved waypoints as <code>&lt;wpt&gt;</code> elements (label → <code>&lt;name&gt;</code>, plus <code>&lt;time&gt;</code>) alongside the track, so they import as pins in OsmAnd / Garmin / GPX Studio.</li>\n</ul>\n<p><strong>Units</strong></p>\n<ul>\n<li><strong>Global Metric / Imperial</strong> (Settings › System) drives every distance and speed: Nearby Nodes, Trail (Summary, List deltas, waypoint distances), the navigate-to-point view, the trail min-distance gate (5/10/25/100 m ↔ 15/30/75/300 ft) and the map scale bar.</li>\n<li><strong>Trail readout</strong> — the action menu's old four-way km/h·mph·min/km·min/mi cycle is now a <strong>Speed / Pace</strong> toggle; the unit follows the global setting.</li>\n</ul>\n<p><strong>Notifications</strong></p>\n<ul>\n<li><strong>Advert sound</strong> — Settings › Sound gains an <strong>AD sound</strong> entry (built-in / Melody 1 / Melody 2). The device plays it whenever it receives an advert from any node; combined with Auto-Advert on both ends it acts as a hands-free \"still i\n…</li>\n</ul>\n"
        },
        {
          "version": "v1.14",
          "name": "Solo v1.14",
          "datetime": "2026-05-29T10:59:08Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.14",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Solo Firmware v1.14\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Renamed Plus → Solo** — to better reflect that this firmware is designed for *off-grid, standalone* use without needing a companion app on the phone; release artefacts are now `solo-v1.14-oled.uf2` and `solo-v1.14-eink.uf2`\r\n- **E-ink screenshot support** — `tools/screenshot.py` now works with both OLED and the e-ink panel; auto-detects rotation 0–3 and uses GxEPD2's visible dimensions; build with `-D ENABLE_SCREENSHOT`\r\n- **Battery percentage field** — new `Batt %` option for the Clock page dashboard, now sharing the same LiPo discharge curve and `low_batt_mv` cutoff as the top-bar indicator (so both readings agree)\r\n- **Channel favourites** — mark individual channels as favourites from the channel context menu; new Settings › Contacts filter to hide non-favourite channels\r\n- **Context menu cycling unified** — LEFT/RIGHT now cycles values everywhere (Notif, Melody, Fav, Duration, BPM) without closing the popup; ENTER reserved for one-shot actions\r\n- **Popup menus expand to fit the screen** — on portrait e-ink up to 16 items fit without scrolling; on OLED items are now hard-capped to what physically fits\r\n\r\n### Changes\r\n\r\n**New features**\r\n- **E-ink screenshot** — `WioTrackerL1Eink_companion_dual_dev` env enables capture; protocol header widened to 11 bytes (display type, rotation, uint16 width/height/chunk fields) so it scales to any GxEPD2 panel and rotation\r\n- **Dashboard `Batt %` field** — new Clock-page option computed from the same piecewise LiPo curve used by the top-bar battery indicator\r\n- **Channel favourites** — `ch_fav_bitmask` in prefs; toggle from Channel context menu; Settings › Contacts › Channels filter (all / favourites only)\r\n- **GPS trail — scale grid on map** — toggle from the Trail action menu (Grid row); cycles with LEFT/RIGHT now (previously ENTER only)\r\n- **Ringtone editor migrated to PopupMenu** — Duration and BPM now cycle in-place with LEFT/RIGHT; separate BPM+/BPM- rows removed\r\n\r\n**Fixes**\r\n- **OLED joystick rotation** — enforce reset moved after prefs load, so stale e-ink rotation values no longer reverse joystick mapping on OLED builds (`FEAT_JOYSTICK_ROTATION_SETTING=0`)\r\n- **First melody note duration** — preview-only side effect that shortened the first note in `playMelody()` no longer corrupts the stored sequence\r\n- **Home pages migration** — pages added in this release (Favourites, Trail) are appended to stored `page_order` instead of being hidden; SHUTDOWN is evicted from a full order to make room for required pages\r\n- **Pin picker fallback** — pressing `+` on an empty Favourites tile with no starred contacts and no recent DMs now lists all chat contacts instead of showing \"No fav contacts\"\r\n- **Popup menus on OLED** — height-clamped to what fits on screen (max 4 items at 64 px), so long context menus no longer draw outside the panel\r\n- **Trail action menu** — Grid toggle now also works with LEFT/RIGHT (not just ENTER); Export labels shortened to `Export (live)` / `Export (saved)` to fit\r\n- **E-ink default font** — unknown-character fallback rectangle aligned with the text cell baseline instead of one pixel below\r\n- **Build** — added `DisplayDriver::getBuffer`/`getBufferSize` virtuals so MyMesh no longer needs to know about concrete display types",
          "notesHtml": "<h2>Wio Tracker L1 — Solo Firmware v1.14</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Renamed Plus → Solo</strong> — to better reflect that this firmware is designed for <em>off-grid, standalone</em> use without needing a companion app on the phone; release artefacts are now <code>solo-v1.14-oled.uf2</code> and <code>solo-v1.14-eink.uf2</code></li>\n<li><strong>E-ink screenshot support</strong> — <code>tools/screenshot.py</code> now works with both OLED and the e-ink panel; auto-detects rotation 0–3 and uses GxEPD2's visible dimensions; build with <code>-D ENABLE_SCREENSHOT</code></li>\n<li><strong>Battery percentage field</strong> — new <code>Batt %</code> option for the Clock page dashboard, now sharing the same LiPo discharge curve and <code>low_batt_mv</code> cutoff as the top-bar indicator (so both readings agree)</li>\n<li><strong>Channel favourites</strong> — mark individual channels as favourites from the channel context menu; new Settings › Contacts filter to hide non-favourite channels</li>\n<li><strong>Context menu cycling unified</strong> — LEFT/RIGHT now cycles values everywhere (Notif, Melody, Fav, Duration, BPM) without closing the popup; ENTER reserved for one-shot actions</li>\n<li><strong>Popup menus expand to fit the screen</strong> — on portrait e-ink up to 16 items fit without scrolling; on OLED items are now hard-capped to what physically fits</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li><strong>E-ink screenshot</strong> — <code>WioTrackerL1Eink_companion_dual_dev</code> env enables capture; protocol header widened to 11 bytes (display type, rotation, uint16 width/height/chunk fields) so it scales to any GxEPD2 panel and rotation</li>\n<li><strong>Dashboard <code>Batt %</code> field</strong> — new Clock-page option computed from the same piecewise LiPo curve used by the top-bar battery indicator</li>\n<li><strong>Channel favourites</strong> — <code>ch_fav_bitmask</code> in prefs; toggle from Channel context menu; Settings › Contacts › Channels filter (all / favourites only)</li>\n<li><strong>GPS trail — scale grid on map</strong> — toggle from the Trail action menu (Grid row); cycles with LEFT/RIGHT now (previously ENTER only)</li>\n<li><strong>Ringtone editor migrated to PopupMenu</strong> — Duration and BPM now cycle in-place with LEFT/RIGHT; separate BPM+/BPM- rows removed</li>\n</ul>\n<p><strong>Fixes</strong></p>\n<ul>\n<li><strong>OLED joystick rotation</strong> — enforce reset moved after prefs load, so stale e-ink rotation values no longer reverse joystick mapping on OLED builds (<code>FEAT_JOYSTICK_ROTATION_SETTING=0</code>)</li>\n<li><strong>First melody note duration</strong> — preview-only side effect that shortened the first note in <code>playMelody()</code> no longer corrupts the stored sequence</li>\n<li><strong>Home pages migration</strong> — pages added in this release (Favourites, Trail) are appended to stored <code>page_order</code> instead of being hidden; SHUTDOWN is evicted from a full order to make room for required pages</li>\n<li><strong>Pin picker fallback</strong> — pressing <code>+</code> on an empty Favourites tile with no starred contacts and no recent DMs now lists all chat contacts instead of showing \"No fav contacts\"</li>\n<li><strong>Popup menus on OLED</strong> — height-clamped to what fits on screen (max 4 items at 64 px), so long context menus no longer draw outside the panel</li>\n<li><strong>Trail action menu</strong> — Grid toggle now also works with LEFT/RIGHT (not just ENTER); Export labels shortened to <code>Export (live)</code> / <code>Export (saved)</code> to fit</li>\n<li><strong>E-ink default font</strong> — unknown-character fallback rectangle aligned with the text cell baseline instead of one pixel below</li>\n<li><strong>Build</strong> — added <code>DisplayDriver::getBuffer</code>/<code>getBufferSize</code> virtuals so MyMesh no longer needs to know about concrete display types</li>\n</ul>\n"
        },
        {
          "version": "v1.13",
          "name": "Wio Tracker L1 Firmware v1.13",
          "datetime": "2026-05-26T14:00:21Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.13",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.13\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Favourites dial** — new home page with a 2×3 grid of pinned contacts; Enter opens the DM directly, pin/unpin from the contact context menu in the DM list\r\n- **GPS trail** — Tools › Trail records your route in a RAM ring (512 points); three views cycle with LEFT/RIGHT: Summary (distance, time, avg speed/pace), Map (auto-fit with segment markers), List (per-point timestamps and deltas); Hold Enter for Start/Stop, Save/Load to flash, GPX export over USB Serial, and settings (min-distance gate, speed units)\r\n- **Mark-all-read** — Hold Enter on the DM / Channels / Rooms mode-select screen to mark everything in that category read at once\r\n- **Unicode messages on both displays** — Cyrillic, Greek, Polish, Czech, Baltic and other Latin Extended scripts now render correctly in messages, keyboard preview and reply prefix on both OLED and e-ink when the Lemon font is enabled\r\n- **E-ink full-refresh interval** — Settings › Display › Full rfsh lets you pick how many partial refreshes happen before a cleansing full refresh (off / 5 / 10 / 20 / 30); reduces visible ghosting on long sessions *(e-ink only)*\r\n- **Faster long-message rendering** — fullscreen message view now wraps text in O(n) instead of O(n²); noticeably snappier on long messages, especially with the Lemon font on e-ink\r\n\r\n### Changes\r\n\r\n**New features**\r\n- **Favourites dial home page** — 2×3 grid of pinned contacts; Enter on a filled tile opens the DM, Enter on an empty tile opens an in-place picker (upstream-favourited contacts first, then recent DMs); LEFT/RIGHT reorders in the Home Pages settings\r\n- **GPS trail** — background sampling with configurable min-distance gate (5 / 10 / 25 / 100 m); segments tracked across start/stop cycles; single flash slot `/trail` (binary, magic-versioned header); GPX 1.1 export streams live ring or saved file straight to USB Serial; `G` indicator in status bar blinks while active\r\n- **Mark-all-read** — Hold Enter on the message-type screen clears unread counters for the highlighted mode (DM / Channels / Rooms)\r\n- **Settings sections collapsible** — all sections start collapsed; Enter on a section header expands/collapses it, making long lists (Home Pages, Messages) much faster to navigate\r\n- E-ink: `Full rfsh` setting in Settings › Display — controls how many partial refreshes occur before a cleansing full panel refresh\r\n- Schema versioning of saved preferences — `/new_prefs` now carries a tail sentinel so older saves are detected and treated safely on load; file self-heals on next save\r\n\r\n**Fixes**\r\n- Sensors home page: Enter no longer accidentally toggles GPS on/off while viewing sensor readings\r\n- Upgrade from v1.11 with trail settings in flash: `trail_units_idx` was silently read from the old sentinel byte (giving \"min/mi\" instead of km/h default) — schema bumped to `0xC0DE0004`, corrupted value reset to 0 on mismatch\r\n- Lemon font now correctly decodes multi-byte UTF-8 on the e-ink display (Cyrillic, Greek, Polish accents, etc.); previously rendered as garbage glyphs\r\n- Keyboard preview translates UTF-8 through the active font path, so non-ASCII input shows correctly while typing\r\n- Reply path: the `@[nick]` prefix is now preserved verbatim — a nickname containing `{loc}` / `{time}` is no longer substituted as a placeholder\r\n- Home page order: validity flag prevents a junk byte in flash from being interpreted as a \"custom order\" state\r\n- E-ink: unknown-character fallback rectangle now aligns to the top of the text cell instead of sitting one pixel below the line\r\n- E-ink: Lemon glyphs at text size 2/3 (splash version, clock) no longer render at size 1 scale",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.13</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Favourites dial</strong> — new home page with a 2×3 grid of pinned contacts; Enter opens the DM directly, pin/unpin from the contact context menu in the DM list</li>\n<li><strong>GPS trail</strong> — Tools › Trail records your route in a RAM ring (512 points); three views cycle with LEFT/RIGHT: Summary (distance, time, avg speed/pace), Map (auto-fit with segment markers), List (per-point timestamps and deltas); Hold Enter for Start/Stop, Save/Load to flash, GPX export over USB Serial, and settings (min-distance gate, speed units)</li>\n<li><strong>Mark-all-read</strong> — Hold Enter on the DM / Channels / Rooms mode-select screen to mark everything in that category read at once</li>\n<li><strong>Unicode messages on both displays</strong> — Cyrillic, Greek, Polish, Czech, Baltic and other Latin Extended scripts now render correctly in messages, keyboard preview and reply prefix on both OLED and e-ink when the Lemon font is enabled</li>\n<li><strong>E-ink full-refresh interval</strong> — Settings › Display › Full rfsh lets you pick how many partial refreshes happen before a cleansing full refresh (off / 5 / 10 / 20 / 30); reduces visible ghosting on long sessions <em>(e-ink only)</em></li>\n<li><strong>Faster long-message rendering</strong> — fullscreen message view now wraps text in O(n) instead of O(n²); noticeably snappier on long messages, especially with the Lemon font on e-ink</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li><strong>Favourites dial home page</strong> — 2×3 grid of pinned contacts; Enter on a filled tile opens the DM, Enter on an empty tile opens an in-place picker (upstream-favourited contacts first, then recent DMs); LEFT/RIGHT reorders in the Home Pages settings</li>\n<li><strong>GPS trail</strong> — background sampling with configurable min-distance gate (5 / 10 / 25 / 100 m); segments tracked across start/stop cycles; single flash slot <code>/trail</code> (binary, magic-versioned header); GPX 1.1 export streams live ring or saved file straight to USB Serial; <code>G</code> indicator in status bar blinks while active</li>\n<li><strong>Mark-all-read</strong> — Hold Enter on the message-type screen clears unread counters for the highlighted mode (DM / Channels / Rooms)</li>\n<li><strong>Settings sections collapsible</strong> — all sections start collapsed; Enter on a section header expands/collapses it, making long lists (Home Pages, Messages) much faster to navigate</li>\n<li>E-ink: <code>Full rfsh</code> setting in Settings › Display — controls how many partial refreshes occur before a cleansing full panel refresh</li>\n<li>Schema versioning of saved preferences — <code>/new_prefs</code> now carries a tail sentinel so older saves are detected and treated safely on load; file self-heals on next save</li>\n</ul>\n<p><strong>Fixes</strong></p>\n<ul>\n<li>Sensors home page: Enter no longer accidentally toggles GPS on/off while viewing sensor readings</li>\n<li>Upgrade from v1.11 with trail settings in flash: <code>trail_units_idx</code> was silently read from the old sentinel byte (giving \"min/mi\" instead of km/h default) — schema bumped to <code>0xC0DE0004</code>, corrupted value reset to 0 on mismatch</li>\n<li>Lemon font now correctly decodes multi-byte UTF-8 on the e-ink display (Cyrillic, Greek, Polish accents, etc.); previously rendered as garbage glyphs</li>\n<li>Keyboard preview translates UTF-8 through the active font path, so non-ASCII input shows correctly while typing</li>\n<li>Reply path: the <code>@[nick]</code> prefix is now preserved verbatim — a nickname containing <code>{loc}</code> / <code>{time}</code> is no longer substituted as a placeholder</li>\n<li>Home page order: validity flag prevents a junk byte in flash from being interpreted as a \"custom order\" state</li>\n<li>E-ink: unknown-character fallback rectangle now aligns to the top of the text cell instead of sitting one pixel below the line</li>\n<li>E-ink: Lemon glyphs at text size 2/3 (splash version, clock) no longer render at size 1 scale</li>\n</ul>\n"
        },
        {
          "version": "v1.12",
          "name": "Wio Tracker L1 Firmware v1.12",
          "datetime": "2026-05-24T18:55:09Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.12",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.12\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Unicode messages on both displays** — Cyrillic, Greek, Polish, Czech, Baltic and other Latin Extended scripts now render correctly in messages, keyboard preview and reply prefix on both OLED and e-ink when the Lemon font is enabled\r\n- **E-ink full-refresh interval** — Settings › Display › Full rfsh lets you pick how many partial refreshes happen before a cleansing full refresh (off / 5 / 10 / 20 / 30); reduces visible ghosting on long sessions *(e-ink only)*\r\n- **Faster long-message rendering** — fullscreen message view now wraps text in O(n) instead of O(n²); noticeably snappier on long messages, especially with the Lemon font on e-ink\r\n\r\n### Changes\r\n\r\n**New features**\r\n- E-ink: `Full rfsh` setting in Settings › Display — controls how many partial refreshes occur before a cleansing full panel refresh\r\n- Schema versioning of saved preferences — `/new_prefs` now carries a tail sentinel so older saves are detected and treated safely on load; file self-heals on next save\r\n\r\n**Fixes**\r\n- Lemon font now correctly decodes multi-byte UTF-8 on the e-ink display (Cyrillic, Greek, Polish accents, etc.); previously rendered as garbage glyphs\r\n- Keyboard preview translates UTF-8 through the active font path, so non-ASCII input shows correctly while typing\r\n- Reply path: the `@[nick]` prefix is now preserved verbatim — a nickname containing `{loc}` / `{time}` is no longer substituted as a placeholder\r\n- Home page order: validity flag prevents a junk byte in flash from being interpreted as a \"custom order\" state\r\n- E-ink: unknown-character fallback rectangle now aligns to the top of the text cell instead of sitting one pixel below the line\r\n- E-ink: Lemon glyphs at text size 2/3 (splash version, clock) no longer render at size 1 scale\r\n\r\n### Upgrade notes\r\n\r\n- Settings and message history are preserved across upgrades from v1.11\r\n- First boot after upgrade may log `prefs schema sentinel mismatch` over serial — expected, file is rewritten with the new sentinel on the next setting change",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.12</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Unicode messages on both displays</strong> — Cyrillic, Greek, Polish, Czech, Baltic and other Latin Extended scripts now render correctly in messages, keyboard preview and reply prefix on both OLED and e-ink when the Lemon font is enabled</li>\n<li><strong>E-ink full-refresh interval</strong> — Settings › Display › Full rfsh lets you pick how many partial refreshes happen before a cleansing full refresh (off / 5 / 10 / 20 / 30); reduces visible ghosting on long sessions <em>(e-ink only)</em></li>\n<li><strong>Faster long-message rendering</strong> — fullscreen message view now wraps text in O(n) instead of O(n²); noticeably snappier on long messages, especially with the Lemon font on e-ink</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>E-ink: <code>Full rfsh</code> setting in Settings › Display — controls how many partial refreshes occur before a cleansing full panel refresh</li>\n<li>Schema versioning of saved preferences — <code>/new_prefs</code> now carries a tail sentinel so older saves are detected and treated safely on load; file self-heals on next save</li>\n</ul>\n<p><strong>Fixes</strong></p>\n<ul>\n<li>Lemon font now correctly decodes multi-byte UTF-8 on the e-ink display (Cyrillic, Greek, Polish accents, etc.); previously rendered as garbage glyphs</li>\n<li>Keyboard preview translates UTF-8 through the active font path, so non-ASCII input shows correctly while typing</li>\n<li>Reply path: the <code>@[nick]</code> prefix is now preserved verbatim — a nickname containing <code>{loc}</code> / <code>{time}</code> is no longer substituted as a placeholder</li>\n<li>Home page order: validity flag prevents a junk byte in flash from being interpreted as a \"custom order\" state</li>\n<li>E-ink: unknown-character fallback rectangle now aligns to the top of the text cell instead of sitting one pixel below the line</li>\n<li>E-ink: Lemon glyphs at text size 2/3 (splash version, clock) no longer render at size 1 scale</li>\n</ul>\n<h3>Upgrade notes</h3>\n<ul>\n<li>Settings and message history are preserved across upgrades from v1.11</li>\n<li>First boot after upgrade may log <code>prefs schema sentinel mismatch</code> over serial — expected, file is rewritten with the new sentinel on the next setting change</li>\n</ul>\n"
        },
        {
          "version": "v1.11",
          "name": "Wio Tracker L1 Firmware v1.11",
          "datetime": "2026-05-23T22:53:09Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/v1.11",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.11\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Joystick rotation** — joystick input mapping can now be rotated independently of the display, useful in custom enclosures *(e-ink only)*\r\n- **Home screen page ordering** — all home pages including Clock can now be reordered and toggled in Settings › Home Pages; position indicators are shown immediately on first render\r\n- **Unified firmware branch** — OLED and e-ink builds are now maintained in a single branch; firmware files renamed to `WioTrackerL1_companion_dual` and `WioTrackerL1Eink_companion_dual`\r\n\r\n### Changes\r\n\r\n**New features**\r\n- E-ink: runtime joystick rotation setting in Settings › Display — rotates directional input 0° / 90° / 180° / 270° independently of display rotation\r\n- Settings › Home Pages: LEFT/RIGHT reorders any page in the navigation sequence; ENTER toggles pages ON/OFF (Settings and Messages are always visible and cannot be disabled)\r\n\r\n**Fixes**\r\n- Home Pages: several visibility and ordering bugs fixed\r\n- Display: unknown-character block rendering unified across OLED and e-ink builds\r\n\r\n**Build / CI**\r\n- Firmware environments renamed: `WioTrackerL1_companion_radio_dual_settings` → `WioTrackerL1_companion_dual`, `WioTrackerL1Eink_companion_radio_dual` → `WioTrackerL1Eink_companion_dual`\r\n- Workflow now triggers on `plus_*` tags and correctly injects firmware version into both build jobs",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.11</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Joystick rotation</strong> — joystick input mapping can now be rotated independently of the display, useful in custom enclosures <em>(e-ink only)</em></li>\n<li><strong>Home screen page ordering</strong> — all home pages including Clock can now be reordered and toggled in Settings › Home Pages; position indicators are shown immediately on first render</li>\n<li><strong>Unified firmware branch</strong> — OLED and e-ink builds are now maintained in a single branch; firmware files renamed to <code>WioTrackerL1_companion_dual</code> and <code>WioTrackerL1Eink_companion_dual</code></li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>E-ink: runtime joystick rotation setting in Settings › Display — rotates directional input 0° / 90° / 180° / 270° independently of display rotation</li>\n<li>Settings › Home Pages: LEFT/RIGHT reorders any page in the navigation sequence; ENTER toggles pages ON/OFF (Settings and Messages are always visible and cannot be disabled)</li>\n</ul>\n<p><strong>Fixes</strong></p>\n<ul>\n<li>Home Pages: several visibility and ordering bugs fixed</li>\n<li>Display: unknown-character block rendering unified across OLED and e-ink builds</li>\n</ul>\n<p><strong>Build / CI</strong></p>\n<ul>\n<li>Firmware environments renamed: <code>WioTrackerL1_companion_radio_dual_settings</code> → <code>WioTrackerL1_companion_dual</code>, <code>WioTrackerL1Eink_companion_radio_dual</code> → <code>WioTrackerL1Eink_companion_dual</code></li>\n<li>Workflow now triggers on <code>plus_*</code> tags and correctly injects firmware version into both build jobs</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.10",
          "name": "Wio Tracker L1 Firmware v1.15-plus.1.10",
          "datetime": "2026-05-22T22:07:08Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.10",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.10\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **E-ink display support** — the Wio Tracker L1 now has a dedicated e-ink firmware variant; all screens have been adapted for the 250 × 122 / 122 × 250 panel with full portrait and landscape support\r\n- **Home screen page ordering** — all home pages can now be reordered directly in Settings; Settings and Messages are always present and cannot be disabled\r\n- **Runtime font switcher** — choose between the default Adafruit font and the Lemon Unicode font in Settings › Display\r\n- **Single dual-serial firmware** — one build supports both BLE and USB serial; separate BLE/USB variants are retired\r\n- **Unified firmware** — the previously separate font-switcher build has been merged into the main firmware; there is now a single OLED build and a single e-ink build\r\n\r\n### Changes\r\n\r\n**New features**\r\n- E-ink firmware: new build target `WioTrackerL1Eink_companion_radio_dual` for Wio Tracker L1 with e-ink display\r\n- E-ink: all home screen pages (Clock, Recent, Radio, Bluetooth, Advert, Tools, Settings, Messages, Shutdown) adapted for the e-ink panel\r\n- E-ink: adaptive layout engine — all screens reflow correctly in both portrait (122 × 250) and landscape (250 × 122) orientations\r\n- E-ink: runtime display rotation setting in Settings › Display — applied immediately and persisted across reboots\r\n- E-ink: clock seconds suppressed by default to reduce panel refresh wear\r\n- E-ink: Lemon font support with pixel-accurate glyph scaling\r\n- Settings › Home Pages: LEFT/RIGHT reorders any page in the navigation sequence; ENTER toggles pages ON/OFF (except Settings and Messages, which are always visible)\r\n- Settings › Display: runtime font selection — Default (Adafruit) or Lemon (Unicode, pixel-accurate wrap)\r\n- Settings › Display: 12 h / 24 h clock format toggle (default 24 h)\r\n\r\n**Fixes**\r\n- MeshCore logo on splash screen is centre-cropped rather than overflowing in portrait mode\r\n- Lemon font glyphs now scale correctly with `setTextSize` on the lock screen clock\r\n- `use_lemon_font` preference is now persisted to flash and survives reboots\r\n- Strip `@[nick]` reply prefix from channel and DM history card previews\r\n\r\n**Build / CI**\r\n- Font-switcher firmware variant merged into the main OLED build — no separate download needed",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.10</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>E-ink display support</strong> — the Wio Tracker L1 now has a dedicated e-ink firmware variant; all screens have been adapted for the 250 × 122 / 122 × 250 panel with full portrait and landscape support</li>\n<li><strong>Home screen page ordering</strong> — all home pages can now be reordered directly in Settings; Settings and Messages are always present and cannot be disabled</li>\n<li><strong>Runtime font switcher</strong> — choose between the default Adafruit font and the Lemon Unicode font in Settings › Display</li>\n<li><strong>Single dual-serial firmware</strong> — one build supports both BLE and USB serial; separate BLE/USB variants are retired</li>\n<li><strong>Unified firmware</strong> — the previously separate font-switcher build has been merged into the main firmware; there is now a single OLED build and a single e-ink build</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>E-ink firmware: new build target <code>WioTrackerL1Eink_companion_radio_dual</code> for Wio Tracker L1 with e-ink display</li>\n<li>E-ink: all home screen pages (Clock, Recent, Radio, Bluetooth, Advert, Tools, Settings, Messages, Shutdown) adapted for the e-ink panel</li>\n<li>E-ink: adaptive layout engine — all screens reflow correctly in both portrait (122 × 250) and landscape (250 × 122) orientations</li>\n<li>E-ink: runtime display rotation setting in Settings › Display — applied immediately and persisted across reboots</li>\n<li>E-ink: clock seconds suppressed by default to reduce panel refresh wear</li>\n<li>E-ink: Lemon font support with pixel-accurate glyph scaling</li>\n<li>Settings › Home Pages: LEFT/RIGHT reorders any page in the navigation sequence; ENTER toggles pages ON/OFF (except Settings and Messages, which are always visible)</li>\n<li>Settings › Display: runtime font selection — Default (Adafruit) or Lemon (Unicode, pixel-accurate wrap)</li>\n<li>Settings › Display: 12 h / 24 h clock format toggle (default 24 h)</li>\n</ul>\n<p><strong>Fixes</strong></p>\n<ul>\n<li>MeshCore logo on splash screen is centre-cropped rather than overflowing in portrait mode</li>\n<li>Lemon font glyphs now scale correctly with <code>setTextSize</code> on the lock screen clock</li>\n<li><code>use_lemon_font</code> preference is now persisted to flash and survives reboots</li>\n<li>Strip <code>@[nick]</code> reply prefix from channel and DM history card previews</li>\n</ul>\n<p><strong>Build / CI</strong></p>\n<ul>\n<li>Font-switcher firmware variant merged into the main OLED build — no separate download needed</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.9",
          "name": "Wio Tracker L1 Firmware v1.15-plus.1.9",
          "datetime": "2026-05-21T07:37:51Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.9",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.9\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Active node discovery** — the Nearby screen now sends a live discovery ping and displays responding nodes (repeaters, sensors, rooms) with RSSI, SNR and remote SNR. Tap Enter on a node for a full-screen detail view including the public key.\r\n\r\n### Changes\r\n\r\n**New features**\r\n- Nearby screen: active node discovery via `NODE_DISCOVER_REQ` replaces the old passive advert scan; nodes respond with name, type, RSSI and SNR data\r\n- Nearby screen: each discovered node is shown as a 2-line boxed card with RSSI, SNR and remote SNR\r\n- Nearby screen: navigate discovered nodes with UP/DOWN; press Enter to open a full-screen detail view showing name, public key (base64), RSSI, SNR, remote SNR and known/new status",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.9</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Active node discovery</strong> — the Nearby screen now sends a live discovery ping and displays responding nodes (repeaters, sensors, rooms) with RSSI, SNR and remote SNR. Tap Enter on a node for a full-screen detail view including the public key.</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>Nearby screen: active node discovery via <code>NODE_DISCOVER_REQ</code> replaces the old passive advert scan; nodes respond with name, type, RSSI and SNR data</li>\n<li>Nearby screen: each discovered node is shown as a 2-line boxed card with RSSI, SNR and remote SNR</li>\n<li>Nearby screen: navigate discovered nodes with UP/DOWN; press Enter to open a full-screen detail view showing name, public key (base64), RSSI, SNR, remote SNR and known/new status</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.8",
          "name": "Wio Tracker L1 Firmware v1.15-plus.1.8",
          "datetime": "2026-05-20T08:40:09Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.8",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.8\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Message age in history** — channel and DM history lists now show how old each message is (\"3m\", \"2h\", \">1d\") next to the sender name.\r\n- **Runtime font switcher** — the `font-switcher` build now lets you toggle between the default font and the Lemon font directly in Settings › Display, without flashing a separate firmware. Lemon covers PL, DE, CZ/SK, FR, NO, HU, HR, TR, LT, RU, GR character sets.\r\n\r\n### Changes\r\n\r\n**New features**\r\n- Message age indicator in DM and channel history lists: messages show a compact age string (\"3s\", \"5m\", \"2h\", \">1d\") derived from the RTC timestamp\r\n- Font switcher: `font-switcher` firmware build includes both the default Adafruit font and the Lemon bitmap font; toggle in Settings › Display › Font (saved to flash, takes effect immediately)\r\n\r\n**Bug fixes**\r\n- Missing space after \"Type:\" and \"Seen:\" labels in NearbyScreen detail view\r\n\r\n**Internal**\r\n- CI: `lemon-font` firmware build replaced by `font-switcher` build (from the `font-switcher` branch)",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.8</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Message age in history</strong> — channel and DM history lists now show how old each message is (\"3m\", \"2h\", \"&gt;1d\") next to the sender name.</li>\n<li><strong>Runtime font switcher</strong> — the <code>font-switcher</code> build now lets you toggle between the default font and the Lemon font directly in Settings › Display, without flashing a separate firmware. Lemon covers PL, DE, CZ/SK, FR, NO, HU, HR, TR, LT, RU, GR character sets.</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>Message age indicator in DM and channel history lists: messages show a compact age string (\"3s\", \"5m\", \"2h\", \"&gt;1d\") derived from the RTC timestamp</li>\n<li>Font switcher: <code>font-switcher</code> firmware build includes both the default Adafruit font and the Lemon bitmap font; toggle in Settings › Display › Font (saved to flash, takes effect immediately)</li>\n</ul>\n<p><strong>Bug fixes</strong></p>\n<ul>\n<li>Missing space after \"Type:\" and \"Seen:\" labels in NearbyScreen detail view</li>\n</ul>\n<p><strong>Internal</strong></p>\n<ul>\n<li>CI: <code>lemon-font</code> firmware build replaced by <code>font-switcher</code> build (from the <code>font-switcher</code> branch)</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.7",
          "name": "Wio Tracker L1 Firmware v1.15-plus.1.7",
          "datetime": "2026-05-19T14:00:44Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.7",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.7\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Reply to messages** — long-press Enter on any message in DM or channel history to reply. A \"Reply\" popup appears; confirming pre-fills the keyboard or quick message with `@[nick]` so the recipient is clearly addressed.\r\n- **Reply context in fullscreen view** — when opening a reply message fullscreen, a \"To: nick\" bar is shown under the sender name and the message body is displayed without the address prefix.\r\n- **New font build** - firmware with `lemon-font` name supports extended alphabet range: PL, DE, C/S, FR, NO, HU, HR, TR, LT, RU, GR\r\n\r\n### Changes\r\n\r\n**New features**\r\n- Reply action: long-press Enter on a selected message in DM or channel history to open the Reply popup; works from both the list view and the fullscreen view\r\n- Replying opens the standard message picker — compose via keyboard (pre-filled with `@[nick]`) or choose a quick message (prefix is prepended automatically)\r\n- Fullscreen message view: reply messages show a \"To: nick\" header below the sender; non-ASCII characters in nicks are correctly transliterated for the OLED font\r\n- In Tools menu Char Test lets  you preview all supported letters.\r\n\r\n**Bug fixes**\r\n- AutoLock setting was not persisted across reboots\r\n- Channel bot was responding even when the bot was disabled via `bot_enabled` flag\r\n- Quick-message template expansion buffer was 80 bytes — increased to 140 to match the maximum message length\r\n- Scroll arrows in fullscreen view no longer overlap the last character of wrapped text lines\r\n\r\n**Performance**\r\n- Lock screen sensor dashboard fields now share a single `querySensors()` I2C call per render",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.7</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Reply to messages</strong> — long-press Enter on any message in DM or channel history to reply. A \"Reply\" popup appears; confirming pre-fills the keyboard or quick message with <code>@[nick]</code> so the recipient is clearly addressed.</li>\n<li><strong>Reply context in fullscreen view</strong> — when opening a reply message fullscreen, a \"To: nick\" bar is shown under the sender name and the message body is displayed without the address prefix.</li>\n<li><strong>New font build</strong> - firmware with <code>lemon-font</code> name supports extended alphabet range: PL, DE, C/S, FR, NO, HU, HR, TR, LT, RU, GR</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>Reply action: long-press Enter on a selected message in DM or channel history to open the Reply popup; works from both the list view and the fullscreen view</li>\n<li>Replying opens the standard message picker — compose via keyboard (pre-filled with <code>@[nick]</code>) or choose a quick message (prefix is prepended automatically)</li>\n<li>Fullscreen message view: reply messages show a \"To: nick\" header below the sender; non-ASCII characters in nicks are correctly transliterated for the OLED font</li>\n<li>In Tools menu Char Test lets  you preview all supported letters.</li>\n</ul>\n<p><strong>Bug fixes</strong></p>\n<ul>\n<li>AutoLock setting was not persisted across reboots</li>\n<li>Channel bot was responding even when the bot was disabled via <code>bot_enabled</code> flag</li>\n<li>Quick-message template expansion buffer was 80 bytes — increased to 140 to match the maximum message length</li>\n<li>Scroll arrows in fullscreen view no longer overlap the last character of wrapped text lines</li>\n</ul>\n<p><strong>Performance</strong></p>\n<ul>\n<li>Lock screen sensor dashboard fields now share a single <code>querySensors()</code> I2C call per render</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.6",
          "name": "Wio Tracker L1 Firmware v1.15-plus.1.6",
          "datetime": "2026-05-17T16:44:12Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.6",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.6\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Screen lock** — hold Back + 3× Enter to lock/unlock the device. Locked screen ignores incoming messages, shows clock on button press, and can auto-lock when the display turns off.\r\n- **Extended diacritic support** — UTF-8 transliteration now covers Czech, Slovak, Scandinavian, Hungarian, Romanian, Croatian, Turkish, Baltic, and Icelandic characters in addition to existing Polish/Latin coverage.\r\n\r\n### Changes\r\n\r\n**New features**\r\n- Screen lock: hold Back and press Enter 3 times to lock/unlock; hint popup guides the user through the sequence\r\n- Lock screen displays clock, date, and two configurable sensor values (reuses Dashboard Config fields)\r\n- Settings: new AutoLock toggle — automatically locks when display turns off\r\n- Auto-advert: added 30-second minimum interval option\r\n\r\n**Performance**\r\n- Lock screen: sensor fields now share a single `querySensors()` I2C call per render instead of one call per field\r\n\r\n**Transliteration additions**\r\n- Czech/Slovak: č š ž ř ě ů ď ť ň ľ ĺ ŕ\r\n- Scandinavian: å ø æ\r\n- Hungarian: ő ű\r\n- Romanian: ă ș ț (plus legacy cedilla variant ţ)\r\n- Croatian: đ\r\n- Turkish: ğ ş ı\r\n- Baltic (Lithuanian/Latvian): ā ē ī ū ģ ķ ļ ņ ŗ ų ė į\r\n- Icelandic: ð þ",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.6</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Screen lock</strong> — hold Back + 3× Enter to lock/unlock the device. Locked screen ignores incoming messages, shows clock on button press, and can auto-lock when the display turns off.</li>\n<li><strong>Extended diacritic support</strong> — UTF-8 transliteration now covers Czech, Slovak, Scandinavian, Hungarian, Romanian, Croatian, Turkish, Baltic, and Icelandic characters in addition to existing Polish/Latin coverage.</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>Screen lock: hold Back and press Enter 3 times to lock/unlock; hint popup guides the user through the sequence</li>\n<li>Lock screen displays clock, date, and two configurable sensor values (reuses Dashboard Config fields)</li>\n<li>Settings: new AutoLock toggle — automatically locks when display turns off</li>\n<li>Auto-advert: added 30-second minimum interval option</li>\n</ul>\n<p><strong>Performance</strong></p>\n<ul>\n<li>Lock screen: sensor fields now share a single <code>querySensors()</code> I2C call per render instead of one call per field</li>\n</ul>\n<p><strong>Transliteration additions</strong></p>\n<ul>\n<li>Czech/Slovak: č š ž ř ě ů ď ť ň ľ ĺ ŕ</li>\n<li>Scandinavian: å ø æ</li>\n<li>Hungarian: ő ű</li>\n<li>Romanian: ă ș ț (plus legacy cedilla variant ţ)</li>\n<li>Croatian: đ</li>\n<li>Turkish: ğ ş ı</li>\n<li>Baltic (Lithuanian/Latvian): ā ē ī ū ģ ķ ļ ņ ŗ ų ė į</li>\n<li>Icelandic: ð þ</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.5",
          "name": "Wio Tracker L1 Firmware v1.15-plus.1.5",
          "datetime": "2026-05-16T22:21:11Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.5",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.5\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Polish and Latin diacritic support** — characters like ą, ć, ę, ł, ń, ó, ś, ź, ż (and French, German, Spanish equivalents) are now transliterated to their base ASCII letters instead of rendering as garbage on the display.\r\n- **Bug fixes** — several correctness issues from v1.4 addressed.\r\n\r\n### Changes\r\n\r\n**New features**\r\n- Bot: separate 10-second cooldown for DM replies and channel replies independently\r\n- UTF-8 transliteration in all text display paths (message list, fullscreen view, contact names, channel names)\r\n\r\n**Bug fixes**\r\n- Bot no longer triggers on the sender's nickname — trigger is matched against the message body only\r\n- \"Low Battery / Shutting Down\" text was rendered at size 2, overflowing the screen — fixed to size 1\r\n- Display brightness setting was not applied during the boot loading screen\r\n- Fullscreen message view: scroll arrows `^`/`v` no longer overlap the last characters of wrapped lines\r\n- `FS_LINE_H` corrected from 9 to 8 px to match the Adafruit font cell height (was cutting off the last line)\r\n- `with_sender` buffer in bot channel reply enlarged from 160 to 240 bytes to prevent overflow\r\n\r\n**Performance**\r\n- Static screens (Settings, Nearby, Tools, Bot, etc.) reduced render polling from 300 ms to 2000 ms, lowering unnecessary SPI and CPU activity during idle",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.5</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Polish and Latin diacritic support</strong> — characters like ą, ć, ę, ł, ń, ó, ś, ź, ż (and French, German, Spanish equivalents) are now transliterated to their base ASCII letters instead of rendering as garbage on the display.</li>\n<li><strong>Bug fixes</strong> — several correctness issues from v1.4 addressed.</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>Bot: separate 10-second cooldown for DM replies and channel replies independently</li>\n<li>UTF-8 transliteration in all text display paths (message list, fullscreen view, contact names, channel names)</li>\n</ul>\n<p><strong>Bug fixes</strong></p>\n<ul>\n<li>Bot no longer triggers on the sender's nickname — trigger is matched against the message body only</li>\n<li>\"Low Battery / Shutting Down\" text was rendered at size 2, overflowing the screen — fixed to size 1</li>\n<li>Display brightness setting was not applied during the boot loading screen</li>\n<li>Fullscreen message view: scroll arrows <code>^</code>/<code>v</code> no longer overlap the last characters of wrapped lines</li>\n<li><code>FS_LINE_H</code> corrected from 9 to 8 px to match the Adafruit font cell height (was cutting off the last line)</li>\n<li><code>with_sender</code> buffer in bot channel reply enlarged from 160 to 240 bytes to prevent overflow</li>\n</ul>\n<p><strong>Performance</strong></p>\n<ul>\n<li>Static screens (Settings, Nearby, Tools, Bot, etc.) reduced render polling from 300 ms to 2000 ms, lowering unnecessary SPI and CPU activity during idle</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.4",
          "name": "Wio Tracker L1 Firmware v1.15-plus.1.4",
          "datetime": "2026-05-15T22:40:38Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.4",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.4\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Dual ringtone slots** — compose and store two independent melodies on the device, assign them as notification sounds per message type or override individually per channel and per contact.\r\n- **Working buzzer volume** — volume control now works correctly on nRF52; a preview tone plays on each change so you hear the result immediately.\r\n- **Visual consistency** — buzzer volume bar now matches the display brightness bar in appearance.\r\n\r\n### Changes\r\n\r\n**New features**\r\n- Ringtone Editor: second melody slot (M2), switchable from within the editor\r\n- Settings: DM Melody and Channel Melody — choose built-in, M1, or M2 as notification sound\r\n- Per-channel melody override in channel context menu (long press) — global / M1 / M2\r\n- Per-contact melody override in DM context menu — global / M1 / M2\r\n- Settings: buzzer volume control (1–5) with live preview tone on each change\r\n- Quick reply templates renamed from M1–M10 to Q1–Q10 to avoid confusion with melody slot identifiers\r\n\r\n**Upstream**\r\n- `fix(mesh)`: widen TRACE offset to `uint16` to avoid narrowing conversion",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.4</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Dual ringtone slots</strong> — compose and store two independent melodies on the device, assign them as notification sounds per message type or override individually per channel and per contact.</li>\n<li><strong>Working buzzer volume</strong> — volume control now works correctly on nRF52; a preview tone plays on each change so you hear the result immediately.</li>\n<li><strong>Visual consistency</strong> — buzzer volume bar now matches the display brightness bar in appearance.</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>Ringtone Editor: second melody slot (M2), switchable from within the editor</li>\n<li>Settings: DM Melody and Channel Melody — choose built-in, M1, or M2 as notification sound</li>\n<li>Per-channel melody override in channel context menu (long press) — global / M1 / M2</li>\n<li>Per-contact melody override in DM context menu — global / M1 / M2</li>\n<li>Settings: buzzer volume control (1–5) with live preview tone on each change</li>\n<li>Quick reply templates renamed from M1–M10 to Q1–Q10 to avoid confusion with melody slot identifiers</li>\n</ul>\n<p><strong>Upstream</strong></p>\n<ul>\n<li><code>fix(mesh)</code>: widen TRACE offset to <code>uint16</code> to avoid narrowing conversion</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.3",
          "name": "Wio Tracker L1 Firmware plus.1.3",
          "datetime": "2026-05-14T18:39:13Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.3",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.3\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- **Auto-Advert** — new tool that periodically broadcasts a 0-hop advert with your GPS position.\r\n- **Nearby Nodes overhaul** — Favourites filter, cardinal bearing display (N/NE/E…), last-heard time in detail view, periodic detail refresh. Paired with auto-advert gives you possibility to easily locate your friends.\r\n- **Status bar polish** — node name is now ellipsized to fit, blinking **A** indicator appears left of the BT indicator when Auto-Advert is running.\r\n- **Clock dashboard** — 3 data fields give you ability to display the data you need\r\n- **Sensor placeholders** — keyboard picker and message placeholders now support all available sensor data.\r\n\r\n### Changes\r\n\r\n**New features**\r\n- Auto-Advert tool in Tools screen — periodic 0-hop advert with GPS coordinates\r\n- NearbyScreen: Favourites as default filter, ALL / Companion / Repeater / Room / Sensor filters\r\n- NearbyScreen: bearing shown as degrees + cardinal direction (e.g. `142d (SE)`)\r\n- NearbyScreen: last-heard time (`Seen: 3m ago`) in contact detail view\r\n- NearbyScreen: detail view auto-refreshes every 10 s; returns to list if contact disappears\r\n- Status bar: blinking **A** indicator \r\n- Status bar: node name ellipsized (`longni...`) when status icons would overlap\r\n- Clock dashboard: new \"Messages\" field (total unread DM + channel + room count)\r\n- DM fullscreen view: navigate between messages with left/right (left = newer, right = older)\r\n\r\n**Fixes**\r\n- When connected to the app, message counter is cleared.\r\n- Status bar icons (BT, mute) aligned to correct vertical position; battery icon height corrected\r\n- Channel message view: removed `#` prefix from channel name in title bar\r\n- Various internal refactors: reusable `PopupMenu`, `FullscreenMsgView`, `KeyboardWidget` modules",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.3</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li><strong>Auto-Advert</strong> — new tool that periodically broadcasts a 0-hop advert with your GPS position.</li>\n<li><strong>Nearby Nodes overhaul</strong> — Favourites filter, cardinal bearing display (N/NE/E…), last-heard time in detail view, periodic detail refresh. Paired with auto-advert gives you possibility to easily locate your friends.</li>\n<li><strong>Status bar polish</strong> — node name is now ellipsized to fit, blinking <strong>A</strong> indicator appears left of the BT indicator when Auto-Advert is running.</li>\n<li><strong>Clock dashboard</strong> — 3 data fields give you ability to display the data you need</li>\n<li><strong>Sensor placeholders</strong> — keyboard picker and message placeholders now support all available sensor data.</li>\n</ul>\n<h3>Changes</h3>\n<p><strong>New features</strong></p>\n<ul>\n<li>Auto-Advert tool in Tools screen — periodic 0-hop advert with GPS coordinates</li>\n<li>NearbyScreen: Favourites as default filter, ALL / Companion / Repeater / Room / Sensor filters</li>\n<li>NearbyScreen: bearing shown as degrees + cardinal direction (e.g. <code>142d (SE)</code>)</li>\n<li>NearbyScreen: last-heard time (<code>Seen: 3m ago</code>) in contact detail view</li>\n<li>NearbyScreen: detail view auto-refreshes every 10 s; returns to list if contact disappears</li>\n<li>Status bar: blinking <strong>A</strong> indicator </li>\n<li>Status bar: node name ellipsized (<code>longni...</code>) when status icons would overlap</li>\n<li>Clock dashboard: new \"Messages\" field (total unread DM + channel + room count)</li>\n<li>DM fullscreen view: navigate between messages with left/right (left = newer, right = older)</li>\n</ul>\n<p><strong>Fixes</strong></p>\n<ul>\n<li>When connected to the app, message counter is cleared.</li>\n<li>Status bar icons (BT, mute) aligned to correct vertical position; battery icon height corrected</li>\n<li>Channel message view: removed <code>#</code> prefix from channel name in title bar</li>\n<li>Various internal refactors: reusable <code>PopupMenu</code>, <code>FullscreenMsgView</code>, <code>KeyboardWidget</code> modules</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1.2",
          "name": "Wio Tracker L1 Firmware plus.1.2",
          "datetime": "2026-05-13T20:57:54Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1.2",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1.2\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n- bug fixes and improvements of current features",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1.2</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<ul>\n<li>bug fixes and improvements of current features</li>\n</ul>\n"
        },
        {
          "version": "wio-tracker-v1.15-plus.1",
          "name": "Wio Tracker L1 Firmware plus.1",
          "datetime": "2026-05-12T19:25:55Z",
          "url": "https://github.com/MarekZegare4/MeshCore-Solo/releases/tag/wio-tracker-v1.15-plus.1",
          "prerelease": false,
          "notes": "## Wio Tracker L1 — Plus Firmware v1.15-plus.1\r\n\r\nBased on MeshCore upstream v1.15.\r\n\r\n### Highlights\r\n\r\n**Messages**\r\n- Full channel and DM messaging with on-screen keyboard\r\n- Quick reply templates (10 slots) with `{time}` and `{loc}` placeholders\r\n- Room Servers support alongside DMs and Channels\r\n- Per-channel notification settings via long-press context menu\r\n- Unread badges per category (DM / channel / room)\r\n- Fullscreen message preview with left/right navigation between messages\r\n\r\n**Settings**\r\n- Brightness, auto-off, battery display mode, clock seconds toggle\r\n- Buzzer: On / Off / Auto (auto-mutes when connected via Bluetooth)\r\n- Buzzer volume (5 levels)\r\n- Home page visibility toggles\r\n- TX power, timezone, low battery threshold, GPS interval\r\n- Contact filters (favourites / all) for DMs and Room Servers\r\n\r\n**Clock Screen**\r\n- Dedicated home page with date/time synced from GPS or Bluetooth\r\n- Configurable timezone offset\r\n\r\n**Tools Screen**\r\n- Ringtone editor — step sequencer, up to 32 notes, BPM and duration control\r\n- Auto-Reply Bot — responds to all incoming DMs; optionally monitors a selected channel with a separate reply text; shared trigger word; placeholder support\r\n\r\n**Other**\r\n- LiPo discharge curve for accurate battery percentage\r\n- RTC time persistence across reboots\r\n- Hardware watchdog\r\n- Energy optimizations\r\n- Sensors page with full LPP type support",
          "notesHtml": "<h2>Wio Tracker L1 — Plus Firmware v1.15-plus.1</h2>\n<p>Based on MeshCore upstream v1.15.</p>\n<h3>Highlights</h3>\n<p><strong>Messages</strong></p>\n<ul>\n<li>Full channel and DM messaging with on-screen keyboard</li>\n<li>Quick reply templates (10 slots) with <code>{time}</code> and <code>{loc}</code> placeholders</li>\n<li>Room Servers support alongside DMs and Channels</li>\n<li>Per-channel notification settings via long-press context menu</li>\n<li>Unread badges per category (DM / channel / room)</li>\n<li>Fullscreen message preview with left/right navigation between messages</li>\n</ul>\n<p><strong>Settings</strong></p>\n<ul>\n<li>Brightness, auto-off, battery display mode, clock seconds toggle</li>\n<li>Buzzer: On / Off / Auto (auto-mutes when connected via Bluetooth)</li>\n<li>Buzzer volume (5 levels)</li>\n<li>Home page visibility toggles</li>\n<li>TX power, timezone, low battery threshold, GPS interval</li>\n<li>Contact filters (favourites / all) for DMs and Room Servers</li>\n</ul>\n<p><strong>Clock Screen</strong></p>\n<ul>\n<li>Dedicated home page with date/time synced from GPS or Bluetooth</li>\n<li>Configurable timezone offset</li>\n</ul>\n<p><strong>Tools Screen</strong></p>\n<ul>\n<li>Ringtone editor — step sequencer, up to 32 notes, BPM and duration control</li>\n<li>Auto-Reply Bot — responds to all incoming DMs; optionally monitors a selected channel with a separate reply text; shared trigger word; placeholder support</li>\n</ul>\n<p><strong>Other</strong></p>\n<ul>\n<li>LiPo discharge curve for accurate battery percentage</li>\n<li>RTC time persistence across reboots</li>\n<li>Hardware watchdog</li>\n<li>Energy optimizations</li>\n<li>Sensors page with full LPP type support</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:38.150Z"
    },
    {
      "id": "meshcore-ng",
      "name": "MeshCoreNG",
      "type": "fork",
      "maintainer": "MichTronics",
      "maintainerUrl": "https://github.com/MichTronics",
      "description": "A \"Next Gen\" fork of MeshCore developed in the Netherlands, focused on making repeaters smarter so larger, busier meshes stay stable. It adds a dense-mesh foundation — flood-advert forwarding control, congestion/density stats, hardware CAD channel-busy detection, node-based retransmit spreading and duplicate-hearing suppression — plus an optional internet bridge for linking isolated RF islands, all while staying protocol-compatible with existing MeshCore clients.\n",
      "repository": "https://github.com/MichTronics/MeshCoreNG",
      "website": "https://michtronics.github.io/MeshCoreNG/",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "features": [
        "Dense-mesh repeater foundation",
        "Flood-advert forwarding control (flood.advert.base)",
        "Dense stats / congestion & density measurement",
        "Manual relay probability + dynamic-mode preparation",
        "Hardware CAD channel-busy detection",
        "Node-based retransmit spreading",
        "Duplicate-hearing retransmit suppression",
        "Optional internet bridge (TCP / BLE / RS232 / ESPNow)",
        "Low-battery boot & runtime guard",
        "Web-based flasher",
        "Protocol-compatible with existing MeshCore clients"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "webFlasher": true,
          "ota": true,
          "bleDfu": true
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": false,
          "mqtt": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": true,
          "lowPowerRx": true
        }
      },
      "devices": [
        {
          "id": "ebyte-eora-s3",
          "status": "supported",
          "target": "ebyte_eora_s3",
          "platformio_board": "ebyte_eora-s3"
        },
        {
          "id": "gatiot-gat562-30s",
          "status": "supported",
          "target": "gat562_30s_mesh_kit",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562-evb-pro",
          "status": "supported",
          "target": "gat562_mesh_evb_pro",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562",
          "status": "supported",
          "target": "gat562_mesh_tracker_pro",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562-tracker-pro",
          "status": "supported",
          "target": "gat562_mesh_tracker_pro",
          "platformio_board": "rak4631"
        },
        {
          "id": "gatiot-gat562-watch13",
          "status": "supported",
          "target": "gat562_mesh_watch13",
          "platformio_board": "rak4631"
        },
        {
          "id": "generic-e22",
          "status": "supported",
          "target": "generic-e22",
          "platformio_board": "esp32doit-devkit-v1"
        },
        {
          "id": "generic-espnow",
          "status": "supported",
          "target": "generic_espnow",
          "platformio_board": "esp32-c3-devkitm-1"
        },
        {
          "id": "heltec-ct62",
          "status": "supported",
          "target": "heltec_ct62",
          "platformio_board": "esp32-c3-devkitm-1"
        },
        {
          "id": "heltec-e213",
          "status": "supported",
          "target": "heltec_e213",
          "platformio_board": "heltec_e213"
        },
        {
          "id": "heltec-e290",
          "status": "supported",
          "target": "heltec_e290",
          "platformio_board": "heltec_e290"
        },
        {
          "id": "heltec-mesh-solar",
          "status": "supported",
          "target": "heltec_mesh_solar",
          "platformio_board": "heltec_mesh_solar"
        },
        {
          "id": "heltec-t096",
          "status": "supported",
          "target": "heltec_t096",
          "platformio_board": "heltec_t096"
        },
        {
          "id": "heltec-t1",
          "status": "supported",
          "target": "heltec_t1",
          "platformio_board": "heltec_t1"
        },
        {
          "id": "heltec-t114",
          "status": "supported",
          "target": "heltec_t114",
          "platformio_board": "heltec_t114"
        },
        {
          "id": "heltec-t190",
          "status": "supported",
          "target": "heltec_t190",
          "platformio_board": "heltec_t190"
        },
        {
          "id": "heltec-wt3",
          "status": "supported",
          "target": "heltec_tracker",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "heltec-wt2",
          "status": "supported",
          "target": "heltec_tracker_v2",
          "platformio_board": "heltec_tracker_v2"
        },
        {
          "id": "heltec-v2",
          "status": "supported",
          "target": "heltec_v2",
          "platformio_board": "heltec_wifi_lora_32_V2"
        },
        {
          "id": "heltec-v3",
          "status": "supported",
          "target": "heltec_v3",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "heltec-wsl3",
          "status": "supported",
          "target": "heltec_v3",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "heltec-v4",
          "status": "supported",
          "target": "heltec_v4",
          "platformio_board": "heltec_v4"
        },
        {
          "id": "heltec-v4-exp",
          "status": "supported",
          "target": "heltec_v4",
          "platformio_board": "heltec_v4"
        },
        {
          "id": "heltec-paper",
          "status": "supported",
          "target": "heltec_wireless_paper",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "ikoka-handheld",
          "status": "supported",
          "target": "ikoka_handheld_nrf",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "ikoka-nano",
          "status": "supported",
          "target": "ikoka_nano_nrf",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "ikoka-stick",
          "status": "supported",
          "target": "ikoka_stick_nrf",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "keepteen-lt1",
          "status": "supported",
          "target": "keepteen_lt1",
          "platformio_board": "keepteen_lt1"
        },
        {
          "id": "lilygo-t3-s3-sx126x",
          "status": "supported",
          "target": "lilygo_t3s3",
          "platformio_board": "t3_s3_v1_x"
        },
        {
          "id": "lilygo-t3-s3-sx127x",
          "status": "supported",
          "target": "lilygo_t3s3_sx1276",
          "platformio_board": "t3_s3_v1_x"
        },
        {
          "id": "lilygo-t-impulse-plus",
          "status": "supported",
          "target": "lilygo_t_impulse_plus",
          "platformio_board": "lilygo_t_impulse_plus_nrf52840"
        },
        {
          "id": "lilygo-tbeam-1w",
          "status": "supported",
          "target": "lilygo_tbeam_1w",
          "platformio_board": "t_beam_1w"
        },
        {
          "id": "lilygo-t-beam-sx1262",
          "status": "supported",
          "target": "lilygo_tbeam_SX1262",
          "platformio_board": "ttgo-t-beam"
        },
        {
          "id": "lilygo-t-beam-1-2-sx1276",
          "status": "supported",
          "target": "lilygo_tbeam_SX1276",
          "platformio_board": "ttgo-t-beam"
        },
        {
          "id": "lilygo-tbeam-supreme",
          "status": "supported",
          "target": "lilygo_tbeam_supreme_SX1262",
          "platformio_board": "t_beams3_supreme"
        },
        {
          "id": "lilygo-t-deck-community",
          "status": "supported",
          "target": "lilygo_tdeck",
          "platformio_board": "t-deck"
        },
        {
          "id": "lilygo-t-deck",
          "status": "supported",
          "target": "lilygo_tdeck",
          "platformio_board": "t-deck"
        },
        {
          "id": "lilygo-techo",
          "status": "supported",
          "target": "lilygo_techo",
          "platformio_board": "t-echo"
        },
        {
          "id": "lilygo-techo-card",
          "status": "supported",
          "target": "lilygo_techo_card",
          "platformio_board": "t-echo"
        },
        {
          "id": "lilygo-techo-lite",
          "status": "supported",
          "target": "lilygo_techo_lite",
          "platformio_board": "t-echo"
        },
        {
          "id": "lilygo-teth-elite",
          "status": "supported",
          "target": "lilygo_teth_elite",
          "platformio_board": "esp32s3box"
        },
        {
          "id": "lilygo-tlora-c6",
          "status": "supported",
          "target": "lilygo_tlora_c6",
          "platformio_board": "esp32-c6-devkitm-1"
        },
        {
          "id": "lilygo-tlora-1-6",
          "status": "supported",
          "target": "lilygo_tlora_v2_1",
          "platformio_board": "ttgo-lora32-v1"
        },
        {
          "id": "m5stack-unit-c6l",
          "status": "supported",
          "target": "m5stack_unit_c6l",
          "platformio_board": "esp32-c6-devkitm-1"
        },
        {
          "id": "heltec-meshpocket",
          "status": "supported",
          "target": "mesh_pocket",
          "platformio_board": "heltec_mesh_pocket"
        },
        {
          "id": "meshadventurer",
          "status": "supported",
          "target": "meshadventurer",
          "platformio_board": "esp32doit-devkit-v1"
        },
        {
          "id": "meshtiny",
          "status": "supported",
          "target": "meshtiny",
          "platformio_board": "meshtiny"
        },
        {
          "id": "minewsemi-me25ls01",
          "status": "supported",
          "target": "minewsemi_me25ls01",
          "platformio_board": "minewsemi_me25ls01"
        },
        {
          "id": "muziworks-r1-neo",
          "status": "supported",
          "target": "muziworks_r1_neo",
          "platformio_board": "rak4631"
        },
        {
          "id": "nano-g2",
          "status": "supported",
          "target": "nano_g2_ultra",
          "platformio_board": "nano-g2-ultra"
        },
        {
          "id": "nibble-screen-connect",
          "status": "supported",
          "target": "nibble_screen_connect",
          "platformio_board": "esp32-s3-zero"
        },
        {
          "id": "faketec",
          "status": "supported",
          "target": "promicro",
          "platformio_board": "promicro_nrf52840"
        },
        {
          "id": "rak-11310",
          "status": "supported",
          "target": "rak11310",
          "platformio_board": "rakwireless_rak11300"
        },
        {
          "id": "rak-3112",
          "status": "supported",
          "target": "rak3112",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "rak-13302",
          "status": "supported",
          "target": "rak3401",
          "platformio_board": "rak3401"
        },
        {
          "id": "rak-3x72",
          "status": "supported",
          "target": "rak3x72",
          "platformio_board": "rak3172"
        },
        {
          "id": "rak-4631",
          "status": "supported",
          "target": "rak4631",
          "platformio_board": "rak4631"
        },
        {
          "id": "uart-solar-node-station",
          "status": "supported",
          "target": "rak4631",
          "platformio_board": "rak4631"
        },
        {
          "id": "rak-wismesh-tag",
          "status": "supported",
          "target": "rak_wismesh_tag",
          "platformio_board": "rak4631"
        },
        {
          "id": "rpi-picow",
          "status": "supported",
          "target": "rpi_picow",
          "platformio_board": "rpipicow"
        },
        {
          "id": "sensecap-indicator-espnow",
          "status": "supported",
          "target": "sensecap_indicator-espnow",
          "platformio_board": "esp32-s3-devkitc-1"
        },
        {
          "id": "sensecap-solar-p1",
          "status": "supported",
          "target": "sensecap_solar",
          "platformio_board": "seeed_sensecap_solar"
        },
        {
          "id": "sensecap-solar-p1-pro",
          "status": "supported",
          "target": "sensecap_solar",
          "platformio_board": "seeed_sensecap_solar"
        },
        {
          "id": "station-g2",
          "status": "supported",
          "target": "station_g2",
          "platformio_board": "station-g2"
        },
        {
          "id": "station-g3",
          "status": "supported",
          "target": "station_g3_esp32",
          "platformio_board": "station-g3-esp32"
        },
        {
          "id": "sensecap-t1000e",
          "status": "supported",
          "target": "t1000-e",
          "platformio_board": "tracker-t1000-e"
        },
        {
          "id": "tenstar-c3",
          "status": "supported",
          "target": "tenstar_c3",
          "platformio_board": "esp32-c3-devkitm-1"
        },
        {
          "id": "thinknode-m1",
          "status": "supported",
          "target": "thinknode_m1",
          "platformio_board": "thinknode_m1"
        },
        {
          "id": "thinknode-m2",
          "status": "supported",
          "target": "thinknode_m2",
          "platformio_board": "ESP32-S3-WROOM-1-N4"
        },
        {
          "id": "thinknode-m3",
          "status": "supported",
          "target": "thinknode_m3",
          "platformio_board": "thinknode_m3"
        },
        {
          "id": "thinknode-m5",
          "status": "supported",
          "target": "thinknode_m5",
          "platformio_board": "ESP32-S3-WROOM-1-N4"
        },
        {
          "id": "thinknode-m6",
          "status": "supported",
          "target": "thinknode_m6",
          "platformio_board": "thinknode_m6"
        },
        {
          "id": "tiny-relay",
          "status": "supported",
          "target": "tiny_relay",
          "platformio_board": "tiny_relay"
        },
        {
          "id": "waveshare-rp2040-lora",
          "status": "supported",
          "target": "waveshare_rp2040_lora",
          "platformio_board": "pico"
        },
        {
          "id": "wio-e5-dev",
          "status": "supported",
          "target": "wio-e5-dev",
          "platformio_board": "lora_e5_dev_board"
        },
        {
          "id": "wio-e5-mini",
          "status": "supported",
          "target": "wio-e5-mini",
          "platformio_board": "lora_e5_mini"
        },
        {
          "id": "wio-tracker-l1",
          "status": "supported",
          "target": "wio-tracker-l1",
          "platformio_board": "seeed-wio-tracker-l1"
        },
        {
          "id": "wio-tracker-l1-pro",
          "status": "supported",
          "target": "wio-tracker-l1",
          "platformio_board": "seeed-wio-tracker-l1"
        },
        {
          "id": "wio-tracker-l1-eink",
          "status": "supported",
          "target": "wio-tracker-l1-eink",
          "platformio_board": "seeed-wio-tracker-l1"
        },
        {
          "id": "wio-wm1110",
          "status": "supported",
          "target": "wio_wm1110",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "xiao-esp32c3",
          "status": "supported",
          "target": "xiao_c3",
          "platformio_board": "seeed_xiao_esp32c3"
        },
        {
          "id": "xiao-esp32c6",
          "status": "supported",
          "target": "xiao_c6",
          "platformio_board": "esp32-c6-devkitm-1"
        },
        {
          "id": "xiao-nrf52",
          "status": "supported",
          "target": "xiao_nrf52",
          "platformio_board": "seeed-xiao-afruitnrf52-nrf52840"
        },
        {
          "id": "xiao-rp2040",
          "status": "supported",
          "target": "xiao_rp2040",
          "platformio_board": "seeed_xiao_rp2040"
        },
        {
          "id": "xiao-esp32s3-plain",
          "status": "supported",
          "target": "xiao_s3",
          "platformio_board": "seeed_xiao_esp32s3"
        },
        {
          "id": "xiao-esp32s3",
          "status": "supported",
          "target": "xiao_s3_wio",
          "platformio_board": "seeed_xiao_esp32s3"
        }
      ],
      "latest_version": "1.1.2",
      "released": "2026-06-21",
      "releases": [
        {
          "version": "bridge-tcp-v1.1.2",
          "name": "TCP Bridge Firmware v1.1.2",
          "datetime": "2026-06-21T08:49:45Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-v1.1.2",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-ble-v1.1.2",
          "name": "TCP+BLE Bridge Firmware v1.1.2",
          "datetime": "2026-06-21T08:48:27Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-ble-v1.1.2",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-v1.1.1",
          "name": "TCP Bridge Firmware v1.1.1",
          "datetime": "2026-06-20T10:40:03Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-v1.1.1",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-ble-v1.1.1",
          "name": "TCP+BLE Bridge Firmware v1.1.1",
          "datetime": "2026-06-20T10:41:44Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-ble-v1.1.1",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "room-server-v1.1.0",
          "name": "Room Server Firmware v1.1.0",
          "datetime": "2026-06-18T23:53:33Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/room-server-v1.1.0",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "repeater-v1.1.0",
          "name": "Repeater Firmware v1.1.0",
          "datetime": "2026-06-19T00:35:18Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/repeater-v1.1.0",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-v1.1.0",
          "name": "TCP Bridge Firmware v1.1.0",
          "datetime": "2026-06-18T23:59:09Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-v1.1.0",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-ble-v1.1.0",
          "name": "TCP+BLE Bridge Firmware v1.1.0",
          "datetime": "2026-06-19T00:01:38Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-ble-v1.1.0",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-rs232-v1.1.0",
          "name": "RS232 Bridge Firmware v1.1.0",
          "datetime": "2026-06-19T00:07:03Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-rs232-v1.1.0",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-espnow-v1.1.0",
          "name": "ESPNow Bridge Firmware v1.1.0",
          "datetime": "2026-06-18T23:46:55Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-espnow-v1.1.0",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-ble-v1.1.0",
          "name": "BLE Bridge Firmware v1.1.0",
          "datetime": "2026-06-19T00:31:24Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-ble-v1.1.0",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-v1.0.13",
          "name": "TCP Bridge Firmware v1.0.13",
          "datetime": "2026-06-16T02:23:44Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-v1.0.13",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-ble-v1.0.4",
          "name": "TCP+BLE Bridge Firmware v1.0.4",
          "datetime": "2026-06-16T02:26:33Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-ble-v1.0.4",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-v1.0.12",
          "name": "TCP Bridge Firmware v1.0.12",
          "datetime": "2026-06-15T22:05:20Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-v1.0.12",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-ble-v1.0.3",
          "name": "TCP+BLE Bridge Firmware v1.0.3",
          "datetime": "2026-06-15T22:05:23Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-ble-v1.0.3",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "room-server-v1.0.3",
          "name": "Room Server Firmware v1.0.3",
          "datetime": "2026-06-08T18:32:37Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/room-server-v1.0.3",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "repeater-v1.0.3",
          "name": "Repeater Firmware v1.0.3",
          "datetime": "2026-06-08T18:52:22Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/repeater-v1.0.3",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "companion-v1.0.3",
          "name": "Companion Firmware v1.0.3",
          "datetime": "2026-06-08T20:00:13Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/companion-v1.0.3",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-v1.0.11",
          "name": "TCP Bridge Firmware v1.0.11",
          "datetime": "2026-06-09T00:11:22Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-v1.0.11",
          "prerelease": false,
          "notesHtml": null
        },
        {
          "version": "bridge-tcp-v1.0.10",
          "name": "TCP Bridge Firmware v1.0.10",
          "datetime": "2026-06-08T17:59:47Z",
          "url": "https://github.com/MichTronics/MeshCoreNG/releases/tag/bridge-tcp-v1.0.10",
          "prerelease": false,
          "notesHtml": null
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:35.449Z"
    },
    {
      "id": "meshcoreterm",
      "name": "MeshCoreTerm",
      "type": "fork",
      "maintainer": "dabeani",
      "description": "A retro-themed companion firmware based on MeshCore, featuring a rich on-screen keyboard, hardware navigation (D-pad, joystick, trackball), management features for device name, WiFi, BLE PIN, radio parameters, and GPS configuration. Supports multiple devices with prebuilt binaries and no online update requirement.\n",
      "repository": "https://github.com/dabeani/meshcoreterm",
      "license": "NOASSERTION",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion"
      ],
      "features": [
        "Retro-themed UI",
        "On-screen keyboard with upper/lower/symbol modes",
        "Hardware navigation (D-pad, joystick, T-Deck trackball)",
        "Device management (name, WiFi, BLE PIN, radio params, GPS)",
        "Status bar with transport badges and battery indicator",
        "Persistence via NVS/Preferences"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": false,
          "wifiAp": true
        },
        "operations": {
          "ota": false,
          "webFlasher": false
        },
        "networking": {
          "repeater": false,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-t-deck",
          "status": "supported"
        },
        {
          "id": "sensecap-indicator-espnow",
          "status": "supported",
          "notes": "Seeed SenseCAP Indicator (TFT variant)."
        },
        {
          "id": "heltec-v4",
          "status": "supported"
        },
        {
          "id": "thinknode-m3",
          "status": "supported",
          "notes": "Elecrow 3.5\" ThinkNode M3."
        },
        {
          "id": "thinknode-m5",
          "status": "supported",
          "notes": "Elecrow 7\" ThinkNode M5."
        }
      ],
      "latest_version": "0.9.12.3",
      "released": "2026-05-29",
      "releases": [
        {
          "version": "v0.9.12.3",
          "name": "v0.9.12.3",
          "datetime": "2026-05-29T00:41:47Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.3",
          "prerelease": false,
          "notes": "This is **v0.9.12.3** from **29.05.2026**\r\n\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n**Important** for SenseCap Indicator: You need to install the latest RP2040 Image from the Releases\r\n\r\nNO ONLINE UPDATE available right now - it would only download outdated image!\r\n\r\n## [v0.9.12.3]\r\n\r\n### Fixed\r\n\r\n- Fixed Mgmt → Backup bottom bar layout and touch.\r\n- Switch between BLE / WiFi working again. BLE was stuck!\r\n- Web UI stops on BLE and starts again on WiFi when enabled (boot and transport switch).\r\n- Status bar: BLE badge no longer triggers WiFi; hit boxes match on-screen badges.\r\n- **Discovered** (Contacts long-press): shows companions (USR) and other advert types, not only repeaters.\r\n- **Discovered**: tap row left of **Add** removes entry; **Add** still adds to contacts; discover row requests all node types.\r\n- **Mgmt / Contacts — Auto Add Types**: type filter works when Auto Add is enabled (was inverted: showed **All**, auto-added every type, **Set** only when disabled).\r\n- Mgmt / Backup; Text-Adjustments\r\n- **NTP Timezone:** accepts short forms (`CET`, `UTC+2`, `UTC-5`, `GMT`, `BST`) — converted to POSIX automatically.",
          "notesHtml": "<p>This is <strong>v0.9.12.3</strong> from <strong>29.05.2026</strong></p>\n<p>Please have a look at the filename, to download the correct variant for your device!\n<strong>Important</strong> for SenseCap Indicator: You need to install the latest RP2040 Image from the Releases</p>\n<p>NO ONLINE UPDATE available right now - it would only download outdated image!</p>\n<h2>[v0.9.12.3]</h2>\n<h3>Fixed</h3>\n<ul>\n<li>Fixed Mgmt → Backup bottom bar layout and touch.</li>\n<li>Switch between BLE / WiFi working again. BLE was stuck!</li>\n<li>Web UI stops on BLE and starts again on WiFi when enabled (boot and transport switch).</li>\n<li>Status bar: BLE badge no longer triggers WiFi; hit boxes match on-screen badges.</li>\n<li><strong>Discovered</strong> (Contacts long-press): shows companions (USR) and other advert types, not only repeaters.</li>\n<li><strong>Discovered</strong>: tap row left of <strong>Add</strong> removes entry; <strong>Add</strong> still adds to contacts; discover row requests all node types.</li>\n<li><strong>Mgmt / Contacts — Auto Add Types</strong>: type filter works when Auto Add is enabled (was inverted: showed <strong>All</strong>, auto-added every type, <strong>Set</strong> only when disabled).</li>\n<li>Mgmt / Backup; Text-Adjustments</li>\n<li><strong>NTP Timezone:</strong> accepts short forms (<code>CET</code>, <code>UTC+2</code>, <code>UTC-5</code>, <code>GMT</code>, <code>BST</code>) — converted to POSIX automatically.</li>\n</ul>\n"
        },
        {
          "version": "v0.9.12.2",
          "name": "v0.9.12.2 (HotFix+ReUploaded)",
          "datetime": "2026-05-28T05:57:45Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.2",
          "prerelease": false,
          "notes": "Latest Version v0.9.12.3\r\ngo here -> https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.3\r\n\r\nThis is **v0.9.12.2** from **28.05.2026** (HotFix+ReUploaded)\r\n\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n**Important** for SenseCap Indicator: You need to install the latest RP2040 Image from the Releases\r\n\r\nNO ONLINE UPDATE available right now - it would only download outdated image!\r\n\r\n## [v0.9.12.2]\r\n\r\n### Added\r\n\r\n- **Read** / **Newest** on channel and DM transcript screens. Message threads header now has **Read** (mark all in thread), **Newest** (jump to bottom), plus quick-send and compose — easier after reading on the phone app.\r\n- While Wi‑Fi/BLE companion is connected, incoming messages are stored as already read on the device (fewer false unread badges).\r\n\r\n### Fixed\r\n\r\n- **Channels lost after reboot** when primary storage is the SD card (channels were written to internal flash but loaded from SD).\r\n- **Backup** screen: title centred in header; **New**, **Refresh**, **Restore**, **Delete**, and **Deselect** share one bottom action row (confirm shows only action + **Cancel**).\r\n- **Contact missing** detail view shows a visible **Back** button instead of a blank screen. Stale contact detail auto-closes when the contact was removed while you were on another tab.",
          "notesHtml": "<p>Latest Version v0.9.12.3\ngo here -&gt; <a href=\"https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.3\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.3</a></p>\n<p>This is <strong>v0.9.12.2</strong> from <strong>28.05.2026</strong> (HotFix+ReUploaded)</p>\n<p>Please have a look at the filename, to download the correct variant for your device!\n<strong>Important</strong> for SenseCap Indicator: You need to install the latest RP2040 Image from the Releases</p>\n<p>NO ONLINE UPDATE available right now - it would only download outdated image!</p>\n<h2>[v0.9.12.2]</h2>\n<h3>Added</h3>\n<ul>\n<li><strong>Read</strong> / <strong>Newest</strong> on channel and DM transcript screens. Message threads header now has <strong>Read</strong> (mark all in thread), <strong>Newest</strong> (jump to bottom), plus quick-send and compose — easier after reading on the phone app.</li>\n<li>While Wi‑Fi/BLE companion is connected, incoming messages are stored as already read on the device (fewer false unread badges).</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li><strong>Channels lost after reboot</strong> when primary storage is the SD card (channels were written to internal flash but loaded from SD).</li>\n<li><strong>Backup</strong> screen: title centred in header; <strong>New</strong>, <strong>Refresh</strong>, <strong>Restore</strong>, <strong>Delete</strong>, and <strong>Deselect</strong> share one bottom action row (confirm shows only action + <strong>Cancel</strong>).</li>\n<li><strong>Contact missing</strong> detail view shows a visible <strong>Back</strong> button instead of a blank screen. Stale contact detail auto-closes when the contact was removed while you were on another tab.</li>\n</ul>\n"
        },
        {
          "version": "v0.9.12.1",
          "name": "v0.9.12.1",
          "datetime": "2026-05-27T22:00:54Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.1",
          "prerelease": false,
          "notes": "** NEW HOTFIX v0.9.12.2 **\r\ngo here: https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.2\r\n\r\nThis is **v0.9.12.1** from **27.05.2026**, release for critical bugs in the v0.9.12. The main focus is on fixing the T-Deck Plus keyboard and blink behavior, improving the SD card support and backup/restore flows, and addressing various UI issues and inconsistencies across the on-device UI and WebUI. The update also includes some new features like WiFi Access Point mode per profile and a new boot console screen, as well as improvements to the map rendering and message handling.\r\n\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n\r\n**Important** for SenseCap Indicator: There is a new RP2040 image, which is needed to support the new SD card features. Please make sure to use the correct image for your device when updating.\r\n\r\nNO ONLINE UPDATE available right now - it would only download outdated image!\r\n\r\n## [v0.9.12.1]\r\n\r\n### Changed / Improved\r\n\r\n- Repeater Admin Menu (WebUI): Improved Device, Status, ACL, Neighbors, Regions.\r\n- Mgmt / Global: Firmware update uploader implemented. Take care about the Device-Type.\r\n- **#184** — Light color scheme: clearer outdoor readability across the on-device UI. \r\n- WebUI WebSocket sync: Contacts and Mgmt / Log now stay subscribed in the browser background after the first full sync, so switching tabs does not repeatedly reload the full contacts list. Log and contacts updates use sequence checks with resync on gaps, and normal contact changes are sent as bounded deltas instead of whole-list broadcasts unless a full resync is required.\r\n- Mgmt / Lock and WebUI: added lock-screen PNG upload to `/MCTerm/lockscreen.png` with a visible `?` limits hint. Uploads accept PNG only, require exact current display dimensions, reject files over 512 KiB, enable the picture background after a successful upload, and persist the selected path/color settings through the existing UI prefs flow.\r\n- Mgmt / Lock: lock-screen background selection is now `None` or a bounded PNG picture path, following the SenseCAP photo-demo model without keeping a large image buffer in RAM. The selected PNG must match the active lock-screen dimensions, is capped at 512 KiB, defaults to `/MCTerm/lockscreen.png`, and persists through Internal and SD prefs with WebUI parity. Lock-screen text color selection remains available (White, Blue, Green, Yellow, Orange, Red). Sample Pictures -> [https://github.com/Seeed-Solution/SenseCAP_Indicator_ESP32/tree/main/examples/photo_demo/spiffs](https://github.com/Seeed-Solution/SenseCAP_Indicator_ESP32/tree/main/examples/photo_demo/spiffs)\r\n- **#22** — SD Card support implemented for Backup/Data Storage (needs to be selected in Mgmt / Global -> Primary Disk).\r\n- **#176** — Store all data primarily on SD Card. Mgmt / Backup\r\n- **#177** — Backup and restore to/from SD Card.\r\n- **#238** — Msgs / DM room separation: split room-server chats out of the normal DM list into a dedicated Rooms frame in both the on-device ui-modern Msgs screen and the WebUI, so user DMs and room-server conversations are no longer mixed together (#238).\r\n- **#252** — Mgmt/Channels/Regions: show a distinct \"Max regions reached\" popup (instead of the misleading \"Invalid or duplicate\") when the user attempts to add a region beyond the maximum allowed count, both on-device and in the WebUI (#252). Mgmt/Channels/Regions: raise the maximum number of region scope definitions from 12 to 15 (#252).\r\n- **#125** — Map tab: use each device marker border color for hop count while keeping the marker fill tied to the device type (#125).\r\n- **#199** — Map tab: render 2-byte and 3-byte hash badges on two compact lines so multibyte node markers stay readable without widening as much (#199).\r\n- **#196** — T-Deck Plus sounds: prioritized T-Deck I2S audio refills ahead of WebUI/SD-store work and deferred SD journal flushes until playback ends, eliminating the remaining preview stutter on hardware (#196).\r\n- **\n…",
          "notesHtml": "<p>** NEW HOTFIX v0.9.12.2 **\ngo here: <a href=\"https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.2\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12.2</a></p>\n<p>This is <strong>v0.9.12.1</strong> from <strong>27.05.2026</strong>, release for critical bugs in the v0.9.12. The main focus is on fixing the T-Deck Plus keyboard and blink behavior, improving the SD card support and backup/restore flows, and addressing various UI issues and inconsistencies across the on-device UI and WebUI. The update also includes some new features like WiFi Access Point mode per profile and a new boot console screen, as well as improvements to the map rendering and message handling.</p>\n<p>Please have a look at the filename, to download the correct variant for your device!</p>\n<p><strong>Important</strong> for SenseCap Indicator: There is a new RP2040 image, which is needed to support the new SD card features. Please make sure to use the correct image for your device when updating.</p>\n<p>NO ONLINE UPDATE available right now - it would only download outdated image!</p>\n<h2>[v0.9.12.1]</h2>\n<h3>Changed / Improved</h3>\n<ul>\n<li>Repeater Admin Menu (WebUI): Improved Device, Status, ACL, Neighbors, Regions.</li>\n<li>Mgmt / Global: Firmware update uploader implemented. Take care about the Device-Type.</li>\n<li><strong>#184</strong> — Light color scheme: clearer outdoor readability across the on-device UI. </li>\n<li>WebUI WebSocket sync: Contacts and Mgmt / Log now stay subscribed in the browser background after the first full sync, so switching tabs does not repeatedly reload the full contacts list. Log and contacts updates use sequence checks with resync on gaps, and normal contact changes are sent as bounded deltas instead of whole-list broadcasts unless a full resync is required.</li>\n<li>Mgmt / Lock and WebUI: added lock-screen PNG upload to <code>/MCTerm/lockscreen.png</code> with a visible <code>?</code> limits hint. Uploads accept PNG only, require exact current display dimensions, reject files over 512 KiB, enable the picture background after a successful upload, and persist the selected path/color settings through the existing UI prefs flow.</li>\n<li>Mgmt / Lock: lock-screen background selection is now <code>None</code> or a bounded PNG picture path, following the SenseCAP photo-demo model without keeping a large image buffer in RAM. The selected PNG must match the active lock-screen dimensions, is capped at 512 KiB, defaults to <code>/MCTerm/lockscreen.png</code>, and persists through Internal and SD prefs with WebUI parity. Lock-screen text color selection remains available (White, Blue, Green, Yellow, Orange, Red). Sample Pictures -&gt; <a href=\"https://github.com/Seeed-Solution/SenseCAP_Indicator_ESP32/tree/main/examples/photo_demo/spiffs\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Seeed-Solution/SenseCAP_Indicator_ESP32/tree/main/examples/photo_demo/spiffs</a></li>\n<li><strong>#22</strong> — SD Card support implemented for Backup/Data Storage (needs to be selected in Mgmt / Global -&gt; Primary Disk).</li>\n<li><strong>#176</strong> — Store all data primarily on SD Card. Mgmt / Backup</li>\n<li><strong>#177</strong> — Backup and restore to/from SD Card.</li>\n<li><strong>#238</strong> — Msgs / DM room separation: split room-server chats out of the normal DM list into a dedicated Rooms frame in both the on-device ui-modern Msgs screen and the WebUI, so user DMs and room-server conversations are no longer mixed together (#238).</li>\n<li><strong>#252</strong> — Mgmt/Channels/Regions: show a distinct \"Max regions reached\" popup (instead of the misleading \"Invalid or duplicate\") when the user attempts to add a region beyond the maximum allowed count, both on-device and in the WebUI (#252). Mgmt/Channels/Regions: raise the maximum number of region scope definitions from 12 to 15 (#252).</li>\n<li><strong>#125</strong> — Map tab: use each device marker border color for hop count while keeping the marker fill tied to the device type (#125).</li>\n<li><strong>#199</strong> — Map tab: render 2-byte and 3-byte hash badges on two compact lines so multibyte node markers stay readable without widening as much (#199).</li>\n<li><strong>#196</strong> — T-Deck Plus sounds: prioritized T-Deck I2S audio refills ahead of WebUI/SD-store work and deferred SD journal flushes until playback ends, eliminating the remaining preview stutter on hardware (#196).</li>\n<li>**\n…</li>\n</ul>\n"
        },
        {
          "version": "v0.9.12",
          "name": "v0.9.12 (TDECK/HeltecV4)",
          "datetime": "2026-04-19T22:17:27Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.12",
          "prerelease": false,
          "notes": "This is v0.9.12 from 20.04.2026.\r\nActually this is the release for the TDECK & HeltecV4, the other devices will follow later!\r\nNO ONLINE UPDATE possible right now.\r\n\r\n## [v0.9.12]\r\n\r\n## Elecrow CrowPanel 7\" companion radio support added!\r\n## Upstream base upgraded: MeshCore v1.14.0 → v1.14.1\r\n## Upstream base upgraded: MeshCore v1.14.1 → v1.15.0\r\n## WebUI interface implemented, WIFI needs to be active (http://IP), usr: admin / pass: BLE-code\r\n\r\n### Changed / Improved\r\n- **WebUI message navigation and thread behavior refined**\r\n  - Bottom tab presses now always return to the selected tab's root view, reducing stale nested-state confusion\r\n  - Message list navigation arrows are now visually consistent\r\n  - Channel/DM reply action labels now use \"RPL\" and signal badges display compact RSSI/SNR formatting\r\n- **WebUI message detail page redesigned for faster diagnostics**\r\n  - Message detail now surfaces key delivery and route context first, including clearer hops vs repeats emphasis based on message direction\r\n  - Metadata and raw transport details remain available in a more structured layout\r\n- **WebUI channel management cleanup**\r\n  - The extra key-format helper line was removed from the Regions section to reduce visual noise\r\n- **On-screen light color scheme readability overhaul**\r\n  - Light mode now uses a bright white base with stronger contrast treatment for controls, improving legibility in heavy sunlight\r\n  - Buttons across the on-device UI were visually unified for outdoor use with clearer borders and higher-contrast label rendering\r\n  - Badge and accent colors were adjusted in light mode so critical status indicators remain easy to distinguish on bright backgrounds\r\n  - Contact list rows were tuned for light mode readability with clearer row separation and easier-to-read text treatment\r\n- **MAP marker and badge consistency improvements**\r\n  - Map device hash badges now follow each device's advertised hash width (1-byte, 2-byte, or 3-byte) instead of the local multi-byte hash preference\r\n  - Map device badge colors now match device type coloring used in contact badges (for example SVR and RPT), improving consistency across the UI\r\n- **Management log readability improved** — long entries wrap to available width\r\n- **More consistent device colors across the interface**\r\n- **Channel and DM views stay responsive while browsing larger histories**\r\n- **CrowPanel 7 list readability, alignment, and text size improved across all screens**\r\n- **Build stability follow-up** — stale platform overrides removed; all targets revalidated\r\n- **Contact route badges correctly decode 1-, 2-, and 3-byte multihash paths**\r\n- **DM route hints now survive device restart**\r\n- **Manual location setting now available in MCTerm via GPS menu**\r\n  - WebUI displays 3-state mode selector: Off (no location), GPS (real-time), Manual (fixed coordinates)\r\n  - Set manual location via text input fields for latitude, longitude, altitude\r\n  - Set location from map view using \"Use Map Center\" button\r\n  - Clear location via \"Clear Loc\" button\r\n  - Uses existing firmware protocol (CMD_SET_ADVERT_LATLON) — no companion app protocol changes\r\n  - Matches official companion app behavior for manual location configuration\r\n  - HOWTO: Open Mgmt -> GPS. - Go to Manual Location. - Tap Edit on Manual Lat, enter latitude, confirm. - Tap Edit on Manual Lon, enter longitude, confirm. - Tap Edit on Manual Alt, enter altitude in meters, confirm. - Set Advert Location to Manual (cycle button until it shows Manual), so adverts use your manual coordinates.\r\n\r\n### Added\r\n- **Message detail can now jump directly to map route visualization**\r\n  - Selecting the hop count in message detail opens the map and overlays the known hop path as connected lines between devices\r\n- **T-Deck Plus: Alt+S and SYM key now cycle input modes**\r\n  - Pressing Alt+S on the hardware keyboard cycles through all four input modes: uppercase, lowercase, SYM1, and SYM2\r\n  - Pressing the standalone SYM key jumps \n…",
          "notesHtml": "<p>This is v0.9.12 from 20.04.2026.\nActually this is the release for the TDECK &amp; HeltecV4, the other devices will follow later!\nNO ONLINE UPDATE possible right now.</p>\n<h2>[v0.9.12]</h2>\n<h2>Elecrow CrowPanel 7\" companion radio support added!</h2>\n<h2>Upstream base upgraded: MeshCore v1.14.0 → v1.14.1</h2>\n<h2>Upstream base upgraded: MeshCore v1.14.1 → v1.15.0</h2>\n<h2>WebUI interface implemented, WIFI needs to be active (<a href=\"http://ip/\" target=\"_blank\" rel=\"noopener noreferrer\">http://IP</a>), usr: admin / pass: BLE-code</h2>\n<h3>Changed / Improved</h3>\n<ul>\n<li><strong>WebUI message navigation and thread behavior refined</strong><ul>\n<li>Bottom tab presses now always return to the selected tab's root view, reducing stale nested-state confusion</li>\n<li>Message list navigation arrows are now visually consistent</li>\n<li>Channel/DM reply action labels now use \"RPL\" and signal badges display compact RSSI/SNR formatting</li>\n</ul>\n</li>\n<li><strong>WebUI message detail page redesigned for faster diagnostics</strong><ul>\n<li>Message detail now surfaces key delivery and route context first, including clearer hops vs repeats emphasis based on message direction</li>\n<li>Metadata and raw transport details remain available in a more structured layout</li>\n</ul>\n</li>\n<li><strong>WebUI channel management cleanup</strong><ul>\n<li>The extra key-format helper line was removed from the Regions section to reduce visual noise</li>\n</ul>\n</li>\n<li><strong>On-screen light color scheme readability overhaul</strong><ul>\n<li>Light mode now uses a bright white base with stronger contrast treatment for controls, improving legibility in heavy sunlight</li>\n<li>Buttons across the on-device UI were visually unified for outdoor use with clearer borders and higher-contrast label rendering</li>\n<li>Badge and accent colors were adjusted in light mode so critical status indicators remain easy to distinguish on bright backgrounds</li>\n<li>Contact list rows were tuned for light mode readability with clearer row separation and easier-to-read text treatment</li>\n</ul>\n</li>\n<li><strong>MAP marker and badge consistency improvements</strong><ul>\n<li>Map device hash badges now follow each device's advertised hash width (1-byte, 2-byte, or 3-byte) instead of the local multi-byte hash preference</li>\n<li>Map device badge colors now match device type coloring used in contact badges (for example SVR and RPT), improving consistency across the UI</li>\n</ul>\n</li>\n<li><strong>Management log readability improved</strong> — long entries wrap to available width</li>\n<li><strong>More consistent device colors across the interface</strong></li>\n<li><strong>Channel and DM views stay responsive while browsing larger histories</strong></li>\n<li><strong>CrowPanel 7 list readability, alignment, and text size improved across all screens</strong></li>\n<li><strong>Build stability follow-up</strong> — stale platform overrides removed; all targets revalidated</li>\n<li><strong>Contact route badges correctly decode 1-, 2-, and 3-byte multihash paths</strong></li>\n<li><strong>DM route hints now survive device restart</strong></li>\n<li><strong>Manual location setting now available in MCTerm via GPS menu</strong><ul>\n<li>WebUI displays 3-state mode selector: Off (no location), GPS (real-time), Manual (fixed coordinates)</li>\n<li>Set manual location via text input fields for latitude, longitude, altitude</li>\n<li>Set location from map view using \"Use Map Center\" button</li>\n<li>Clear location via \"Clear Loc\" button</li>\n<li>Uses existing firmware protocol (CMD_SET_ADVERT_LATLON) — no companion app protocol changes</li>\n<li>Matches official companion app behavior for manual location configuration</li>\n<li>HOWTO: Open Mgmt -&gt; GPS. - Go to Manual Location. - Tap Edit on Manual Lat, enter latitude, confirm. - Tap Edit on Manual Lon, enter longitude, confirm. - Tap Edit on Manual Alt, enter altitude in meters, confirm. - Set Advert Location to Manual (cycle button until it shows Manual), so adverts use your manual coordinates.</li>\n</ul>\n</li>\n</ul>\n<h3>Added</h3>\n<ul>\n<li><strong>Message detail can now jump directly to map route visualization</strong><ul>\n<li>Selecting the hop count in message detail opens the map and overlays the known hop path as connected lines between devices</li>\n</ul>\n</li>\n<li><strong>T-Deck Plus: Alt+S and SYM key now cycle input modes</strong><ul>\n<li>Pressing Alt+S on the hardware keyboard cycles through all four input modes: uppercase, lowercase, SYM1, and SYM2</li>\n<li>Pressing the standalone SYM key jumps \n…</li>\n</ul>\n</li>\n</ul>\n"
        },
        {
          "version": "v0.9.11",
          "name": "v0.9.11",
          "datetime": "2026-03-15T21:27:53Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.11",
          "prerelease": false,
          "notes": "This is v0.9.11 from 15.03.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n\r\n* Since this version there are 2 new Devices supported!\r\n* Heltec v4 (TFT+GPS) and Elecrow CrowPanel 3.5 HMI + LoRa!\r\n\r\nThere was no change for the indicator-rp2040 module.\r\n\r\n## [v0.9.11]\r\n\r\n### Upstream base upgraded: MeshCore v1.13 → v1.14\r\n### Implemented device support for Heltec V4 with TFT +GPS\r\n### Implemented device support for Elecrow CrowPanel 3.5 TFT +SDCard\r\n\r\n### unfinished\r\n- MAP is still WIP!\r\n\r\n### Added\r\n- Radio activity LED: a small round dot in the top status bar (left of the device name) that flashes green for 250 ms on LoRa RX activity (including CRC-error receptions) and flashes red for 250 ms on LoRa TX activity. The dot shows an idle ring outline when quiet.\r\n- Map last-known-position auto-save: when GPS gets a valid fix, coordinates are persisted to flash immediately so the map restores the true latest position after reboot. Ongoing writes are still throttled (max once every 5 minutes) and only occur when coordinates change.\r\n- Map contact markers now show the node 1-byte ID prefix (2-digit hex, e.g. `1E`) instead of plain squares, using the same existing marker background coloring (hop color / selected highlight) with automatic black-or-white foreground contrast for readability. (still under construction)\r\n\r\n### Changed / Improved\r\n- Mgmt → WiFi now supports saved WiFi Profiles: you can create multiple named profiles, keep separate SSID/password pairs per profile, switch the active profile from a dedicated saved-profile picker, delete saved profiles directly in that picker.\r\n- Mgmt → Global is leaner: compile-time rows for `MAX_GROUP_CHANNELS` and `OFFLINE_QUEUE_SIZE` are gone, `MAX_CONTACTS` moved to Mgmt → Contacts as `ACT/MAX Contacts`, and the Global `Reboot` / `Update & Upgrade` actions now use the compact side-by-side button style.\r\n- Mgmt → Contacts now includes `Manual add contact`, using the existing edit overlay for a two-step `Public Key` then `Name` flow with clipboard paste support in both fields.\r\n- MAP tile cache handling is quieter and more efficient: missing SD tiles are negatively cached briefly, repeated open attempts are avoided while offline, and tiles are retried automatically once Wi-Fi connectivity returns.\r\n- MAP marker tap behavior: tapping a ByteID marker now keeps selection on the map and shows a left-bottom info box with `Name`, `Age`, and `Distance` (km), without a separate floating name box.\r\n- MAP marker double-tap behavior: double-tapping the same ByteID marker opens that contact directly in Contact Detail.\r\n- Mgmt → Advert → Scan Neighbor Repeaters now shows an Add button only for repeaters not yet in Contacts, and tapping a repeater row opens Contact Detail instead of adding on name/row tap.\r\n- Mgmt → Advert now includes `Path Hash Mode`, and Mgmt → Contacts now includes `AutoAdd Max Hops`, matching the MeshCore v1.14 companion settings on-device. (be careful other repeaters/companions need minumum MeshCore v1.14+ to avoid compatibility issues when these settings are changed)\r\n- Mgmt → Contacts → `AutoAdd Max Hops` now opens an Edit field for manual numeric entry with validation across the full MeshCore v1.14 range `0..64`: `0 = No Limit`, `1 = Direct (0 hops)`, and `N = up to N-1 hops`.\r\n- DM message detail now shows delivery state for sent messages (Pending / Delivered / Not delivered), including ACK-based delivered updates.\r\n- Mgmt → Channels now treats the built-in `Public` channel like any other joined channel, including Share/Delete actions.\r\n- If the default `Public` channel was deleted, Mgmt → Channels → Join now shows a `Public` button that recreates it automatically only when it is currently missing.\r\n- T-Deck Text editor now scrolls with the cursor when moving left into long input, so the beginning of the text remains visible while editing.\r\n- Text edit overlay uses smaller message-input text with wrapped visible lines for easier long-\n…",
          "notesHtml": "<p>This is v0.9.11 from 15.03.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<ul>\n<li>Since this version there are 2 new Devices supported!</li>\n<li>Heltec v4 (TFT+GPS) and Elecrow CrowPanel 3.5 HMI + LoRa!</li>\n</ul>\n<p>There was no change for the indicator-rp2040 module.</p>\n<h2>[v0.9.11]</h2>\n<h3>Upstream base upgraded: MeshCore v1.13 → v1.14</h3>\n<h3>Implemented device support for Heltec V4 with TFT +GPS</h3>\n<h3>Implemented device support for Elecrow CrowPanel 3.5 TFT +SDCard</h3>\n<h3>unfinished</h3>\n<ul>\n<li>MAP is still WIP!</li>\n</ul>\n<h3>Added</h3>\n<ul>\n<li>Radio activity LED: a small round dot in the top status bar (left of the device name) that flashes green for 250 ms on LoRa RX activity (including CRC-error receptions) and flashes red for 250 ms on LoRa TX activity. The dot shows an idle ring outline when quiet.</li>\n<li>Map last-known-position auto-save: when GPS gets a valid fix, coordinates are persisted to flash immediately so the map restores the true latest position after reboot. Ongoing writes are still throttled (max once every 5 minutes) and only occur when coordinates change.</li>\n<li>Map contact markers now show the node 1-byte ID prefix (2-digit hex, e.g. <code>1E</code>) instead of plain squares, using the same existing marker background coloring (hop color / selected highlight) with automatic black-or-white foreground contrast for readability. (still under construction)</li>\n</ul>\n<h3>Changed / Improved</h3>\n<ul>\n<li>Mgmt → WiFi now supports saved WiFi Profiles: you can create multiple named profiles, keep separate SSID/password pairs per profile, switch the active profile from a dedicated saved-profile picker, delete saved profiles directly in that picker.</li>\n<li>Mgmt → Global is leaner: compile-time rows for <code>MAX_GROUP_CHANNELS</code> and <code>OFFLINE_QUEUE_SIZE</code> are gone, <code>MAX_CONTACTS</code> moved to Mgmt → Contacts as <code>ACT/MAX Contacts</code>, and the Global <code>Reboot</code> / <code>Update &amp; Upgrade</code> actions now use the compact side-by-side button style.</li>\n<li>Mgmt → Contacts now includes <code>Manual add contact</code>, using the existing edit overlay for a two-step <code>Public Key</code> then <code>Name</code> flow with clipboard paste support in both fields.</li>\n<li>MAP tile cache handling is quieter and more efficient: missing SD tiles are negatively cached briefly, repeated open attempts are avoided while offline, and tiles are retried automatically once Wi-Fi connectivity returns.</li>\n<li>MAP marker tap behavior: tapping a ByteID marker now keeps selection on the map and shows a left-bottom info box with <code>Name</code>, <code>Age</code>, and <code>Distance</code> (km), without a separate floating name box.</li>\n<li>MAP marker double-tap behavior: double-tapping the same ByteID marker opens that contact directly in Contact Detail.</li>\n<li>Mgmt → Advert → Scan Neighbor Repeaters now shows an Add button only for repeaters not yet in Contacts, and tapping a repeater row opens Contact Detail instead of adding on name/row tap.</li>\n<li>Mgmt → Advert now includes <code>Path Hash Mode</code>, and Mgmt → Contacts now includes <code>AutoAdd Max Hops</code>, matching the MeshCore v1.14 companion settings on-device. (be careful other repeaters/companions need minumum MeshCore v1.14+ to avoid compatibility issues when these settings are changed)</li>\n<li>Mgmt → Contacts → <code>AutoAdd Max Hops</code> now opens an Edit field for manual numeric entry with validation across the full MeshCore v1.14 range <code>0..64</code>: <code>0 = No Limit</code>, <code>1 = Direct (0 hops)</code>, and <code>N = up to N-1 hops</code>.</li>\n<li>DM message detail now shows delivery state for sent messages (Pending / Delivered / Not delivered), including ACK-based delivered updates.</li>\n<li>Mgmt → Channels now treats the built-in <code>Public</code> channel like any other joined channel, including Share/Delete actions.</li>\n<li>If the default <code>Public</code> channel was deleted, Mgmt → Channels → Join now shows a <code>Public</code> button that recreates it automatically only when it is currently missing.</li>\n<li>T-Deck Text editor now scrolls with the cursor when moving left into long input, so the beginning of the text remains visible while editing.</li>\n<li>Text edit overlay uses smaller message-input text with wrapped visible lines for easier long-\n…</li>\n</ul>\n"
        },
        {
          "version": "v0.9.10",
          "name": "v0.9.10",
          "datetime": "2026-02-21T01:37:06Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.10",
          "prerelease": false,
          "notes": "This is v0.9.10 from 21.02.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n\r\nThere was no change for the indicator-rp2040 module.\r\n\r\n## [v0.9.10]\r\n\r\n### Changed / Improved\r\n- Smoothed battery voltage display using averaging to reduce rapid value jumps in the status area.\r\n- Battery/Duty-cycle toggle now reliably shows percentage mode (including while charging) instead of repeating volts.\r\n- Mgmt/GPS now includes an AutoBaud toggle (enabled by default); Baud editing is blocked while AutoBaud is enabled.\r\n- Mgmt/GPS now shows progress popups while switching AutoBaud and while restarting GPS, so long-running actions no longer look stuck.\r\n- In timeout-only mode (autolock disabled), keyboard keys no longer wake the display; wake remains on recessed trackball press/click to reduce accidental pocket wake-ups.\r\n- Internal clipboard is now mirrored to SD at `/clipboard.txt` (where SD is available), allowing out-of-band import/export and clipboard persistence across reboot.\r\n- Text edit fields now support press-and-hold paste in addition to double-tap paste.\r\n- Copy popups now specify what was copied (for example: channel secret, selection, word, PubKey) instead of only showing a generic \"Copied\" message.\r\n- In chat views, press-and-hold now copies text directly from the touched message/detail line (broader \"copy any text\" behavior in transcripts/details).\r\n- Press-and-hold copy is also available in Contacts rows and selected Mgmt text rows (RxRaw log + telemetry rows).\r\n- Mgmt/Global rows now support press-and-hold copy as well (name/device ID/public key/constants/admin info/storage).\r\n- Press-and-hold copy now also covers Mgmt/WiFi, Mgmt/BLE, and Mgmt/GPS rows.\r\n- Manual display-off (single recessed trackball/button click) now wakes only on another recessed trackball/button click when autolock is disabled; with autolock enabled, existing wake behavior remains unchanged.\r\n- On T-Deck navigation, trackball movement is now ignored while the display is off/soft-off or while the lockscreen is active.\r\n\r\n\r\n### Fixed\r\n- Transport switch confirm no longer freezes the UI/device when enabling BLE from transport-off mode; live BLE re-enable from OFF is now handled safely.\r\n- Transport switching no longer freezes on BLE -> WiFi -> BLE round-trips; BLE is kept initialized during live transport toggles.\r\n- Message rendering now respects embedded line breaks (`\\n`) from incoming text (for example bot messages), showing each break on a new line.\r\n- Room server session transcript no longer draws the topmost message through the message-window top boundary when scrolled.\r\n- Channel messages now synchronize both ways between device GUI and companion app over WiFi (app->device and device->app).\r\n- BLE PIN edit now accepts valid 6-digit values that start with zero (for example, 012345).\r\n- Mgmt/GPS button row rendering and touch hitboxes are aligned again (including Defaults and Restart GPS rows).\r\n- Mgmt/GPS AutoBaud now keeps scanning past noisy false-positive baud hits, and the displayed Baud value now reflects the detected runtime baud after AutoBaud evaluation.\r\n- Mgmt/Advert touch mapping is corrected: Advert-Direct and Advert-Flood buttons now trigger the intended send mode consistently.\r\n- DM detail \"Del\" button hit area is corrected; deletion now triggers when tapping inside the visible button.\r\n- Screen timeout now turns the display fully off on touch devices (instead of only dimming to zero brightness).\r\n- Mgmt/UI scrolling now clamps correctly at the bottom and no longer scrolls into empty space.\r\n\r\n---",
          "notesHtml": "<p>This is v0.9.10 from 21.02.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<p>There was no change for the indicator-rp2040 module.</p>\n<h2>[v0.9.10]</h2>\n<h3>Changed / Improved</h3>\n<ul>\n<li>Smoothed battery voltage display using averaging to reduce rapid value jumps in the status area.</li>\n<li>Battery/Duty-cycle toggle now reliably shows percentage mode (including while charging) instead of repeating volts.</li>\n<li>Mgmt/GPS now includes an AutoBaud toggle (enabled by default); Baud editing is blocked while AutoBaud is enabled.</li>\n<li>Mgmt/GPS now shows progress popups while switching AutoBaud and while restarting GPS, so long-running actions no longer look stuck.</li>\n<li>In timeout-only mode (autolock disabled), keyboard keys no longer wake the display; wake remains on recessed trackball press/click to reduce accidental pocket wake-ups.</li>\n<li>Internal clipboard is now mirrored to SD at <code>/clipboard.txt</code> (where SD is available), allowing out-of-band import/export and clipboard persistence across reboot.</li>\n<li>Text edit fields now support press-and-hold paste in addition to double-tap paste.</li>\n<li>Copy popups now specify what was copied (for example: channel secret, selection, word, PubKey) instead of only showing a generic \"Copied\" message.</li>\n<li>In chat views, press-and-hold now copies text directly from the touched message/detail line (broader \"copy any text\" behavior in transcripts/details).</li>\n<li>Press-and-hold copy is also available in Contacts rows and selected Mgmt text rows (RxRaw log + telemetry rows).</li>\n<li>Mgmt/Global rows now support press-and-hold copy as well (name/device ID/public key/constants/admin info/storage).</li>\n<li>Press-and-hold copy now also covers Mgmt/WiFi, Mgmt/BLE, and Mgmt/GPS rows.</li>\n<li>Manual display-off (single recessed trackball/button click) now wakes only on another recessed trackball/button click when autolock is disabled; with autolock enabled, existing wake behavior remains unchanged.</li>\n<li>On T-Deck navigation, trackball movement is now ignored while the display is off/soft-off or while the lockscreen is active.</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>Transport switch confirm no longer freezes the UI/device when enabling BLE from transport-off mode; live BLE re-enable from OFF is now handled safely.</li>\n<li>Transport switching no longer freezes on BLE -&gt; WiFi -&gt; BLE round-trips; BLE is kept initialized during live transport toggles.</li>\n<li>Message rendering now respects embedded line breaks (<code>\\n</code>) from incoming text (for example bot messages), showing each break on a new line.</li>\n<li>Room server session transcript no longer draws the topmost message through the message-window top boundary when scrolled.</li>\n<li>Channel messages now synchronize both ways between device GUI and companion app over WiFi (app-&gt;device and device-&gt;app).</li>\n<li>BLE PIN edit now accepts valid 6-digit values that start with zero (for example, 012345).</li>\n<li>Mgmt/GPS button row rendering and touch hitboxes are aligned again (including Defaults and Restart GPS rows).</li>\n<li>Mgmt/GPS AutoBaud now keeps scanning past noisy false-positive baud hits, and the displayed Baud value now reflects the detected runtime baud after AutoBaud evaluation.</li>\n<li>Mgmt/Advert touch mapping is corrected: Advert-Direct and Advert-Flood buttons now trigger the intended send mode consistently.</li>\n<li>DM detail \"Del\" button hit area is corrected; deletion now triggers when tapping inside the visible button.</li>\n<li>Screen timeout now turns the display fully off on touch devices (instead of only dimming to zero brightness).</li>\n<li>Mgmt/UI scrolling now clamps correctly at the bottom and no longer scrolls into empty space.</li>\n</ul>\n<hr />\n"
        },
        {
          "version": "v0.9.9",
          "name": "v0.9.9",
          "datetime": "2026-02-15T16:50:26Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.9",
          "prerelease": false,
          "notes": "This is v0.9.9 from 11.02.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n* There was no change for the indicator-rp2040 module.\r\n* needed to reupload, version-string was wrong!\r\n\r\n## [v0.9.9]\r\n\r\n### Changed / Improved\r\n- updated to mescore v1.13.0\r\n- Initialize T-Deck I2S buzzer at boot (keeps it quiet when disabled) to avoid driver install from touch handlers and prevent UI lockups on LilyGo T-Deck.\r\n- Accept login-OK responses from alternate sender identities when the response matches expected formats (fixes repeater login stuck cases).\r\n- Adjusted conservative repeater request/timeout values and improved local CLI reply handling.\r\n- Repeater + RoomServer pending waits: Flood min 30s, Direct min 15s (applies to login and other admin requests).\r\n- Reduce idle CPU usage by yielding in the main loop (adaptive delay when screen is soft-off/no companion app connected) to improve power draw without changing functionality.\r\n- Add separate keyboard backlight timeout setting in Mgmt/UI (T-Deck Plus), independent of screen timeout and autolock.\r\n- Smooth fade when display/keyboard backlight turns off (soft-off / keyboard timeout) instead of snapping to black.\r\n- Persist Map \"info bar\" (altitude bar) toggle (T key) across reboots.\r\n- Moved \"Custom QuickSend\" configuration from Mgmt/UI to Mgmt/Messages.\r\n- reduce power use in display off/soft-off state by increasing idle sleep and skipping non-essential touch/gesture processing until wake.\r\n\r\n### Fixed\r\n- Prevent UI freeze when toggling \"All Sounds\" after reboot on LilyGo T-Deck builds by ensuring I2S/buzzer hardware is initialized safely at boot.\r\n- Fix repeater login hanging when the OK response arrives from a different sender identity.\r\n- Harden Mgmt/Global \"Reboot\" to always restart on ESP32 (adds esp_restart() fallback and avoids sticky UI states).",
          "notesHtml": "<p>This is v0.9.9 from 11.02.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<ul>\n<li>There was no change for the indicator-rp2040 module.</li>\n<li>needed to reupload, version-string was wrong!</li>\n</ul>\n<h2>[v0.9.9]</h2>\n<h3>Changed / Improved</h3>\n<ul>\n<li>updated to mescore v1.13.0</li>\n<li>Initialize T-Deck I2S buzzer at boot (keeps it quiet when disabled) to avoid driver install from touch handlers and prevent UI lockups on LilyGo T-Deck.</li>\n<li>Accept login-OK responses from alternate sender identities when the response matches expected formats (fixes repeater login stuck cases).</li>\n<li>Adjusted conservative repeater request/timeout values and improved local CLI reply handling.</li>\n<li>Repeater + RoomServer pending waits: Flood min 30s, Direct min 15s (applies to login and other admin requests).</li>\n<li>Reduce idle CPU usage by yielding in the main loop (adaptive delay when screen is soft-off/no companion app connected) to improve power draw without changing functionality.</li>\n<li>Add separate keyboard backlight timeout setting in Mgmt/UI (T-Deck Plus), independent of screen timeout and autolock.</li>\n<li>Smooth fade when display/keyboard backlight turns off (soft-off / keyboard timeout) instead of snapping to black.</li>\n<li>Persist Map \"info bar\" (altitude bar) toggle (T key) across reboots.</li>\n<li>Moved \"Custom QuickSend\" configuration from Mgmt/UI to Mgmt/Messages.</li>\n<li>reduce power use in display off/soft-off state by increasing idle sleep and skipping non-essential touch/gesture processing until wake.</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>Prevent UI freeze when toggling \"All Sounds\" after reboot on LilyGo T-Deck builds by ensuring I2S/buzzer hardware is initialized safely at boot.</li>\n<li>Fix repeater login hanging when the OK response arrives from a different sender identity.</li>\n<li>Harden Mgmt/Global \"Reboot\" to always restart on ESP32 (adds esp_restart() fallback and avoids sticky UI states).</li>\n</ul>\n"
        },
        {
          "version": "v0.9.8",
          "name": "v0.9.8",
          "datetime": "2026-02-11T17:22:43Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.8",
          "prerelease": false,
          "notes": "This is v0.9.8 from 11.02.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n* There was no change for the indicator-rp2040 module.\r\n* needed to reupload, version-string was wrong!\r\n\r\n## [v0.9.8]\r\n\r\n### Added\r\n- Contacts / Room Server; added room login + Room Console (transcript + send + logout) under Contact Detail.\r\n- UI; added horizontal drag in text input fields to move the cursor (caret).\r\n- Contacts: added small `RSTPath` button in Contact Detail to reset a contact's route/path.\r\n- Power: added `PowerStatus` struct and `MainBoard::getPowerStatus()` helper; UI now reads consolidated power state for battery/charging/usb.\r\n- Power (T-Deck Plus): added configurable ADC multiplier / VBAT divider ratio support (`adc.multiplier`) to allow per-device calibration.\r\n- Mgmt / Contacts; added \"Purge w/o favs\" (purge all contacts except favourites).\r\n- Mgmt / GPS; show UBX accuracy estimate (hAcc) when available.\r\n- MAP (T-Deck Plus); added keyboard controls: W/A/S/D for panning, O/I for zoom in/out, R to recenter on self, T to toggle GPS/Zoom info window.\r\n- MAP; added zoom level indicator overlay that displays briefly when zoom changes (keyboard or touch).\r\n- MAP; added GPS info window (top-left) showing altitude, speed (km/h), and current zoom level in a compact 3-line display (toggleable with T key on T-Deck Plus).\r\n- UI; added autolock feature - can be configured in Mgmt / UI -> LOCK to automatically lock the UI after a period of inactivity. Unlock by holding the unlock button or touching and holding the screen for 2 seconds.\r\n- Mgmt / UI; added LOCK section with configurable Autolock toggle and Autolock Timer (seconds).\r\n\r\n### Changed / Improved\r\n- Contacts; service contacts are no longer treated like normal DM targets:\r\n\t- Repeaters now route to Repeater Admin.\r\n\t- Room Servers now route to the Room Console.\r\n- UI; horizontal swipes that switch higher-level frames now require an edge swipe (keeps left/right scrolling available for the focused element).\r\n- UI (T-Deck Plus); trackball left/right no longer switches the bottom menu tabs.\r\n- UI (T-Deck Plus); when editing a text field, trackball left/right moves the text cursor (caret).\r\n- MAP; scroll/pan inputs now operate on the map view itself (instead of page-level scrolling).\r\n- Mgmt / UI Zoom can now be changed with \"^\" or \"v\" buttons.\r\n- Mgmt / Contacts; Auto Add Types can now be set with freely combinable toggles (USR/RPT/SRV/SNS/OW) when Auto Add is disabled.\r\n- Mgmt / Contacts; Auto Add Types now shows clearer labels (e.g., \"USR (Users)\").\r\n- Contacts / Repeater Admin; reorganized Login screen layout to prevent status text overlap and improve readability.\r\n- Contacts / Repeater Admin; added live login status lines (Direct/Flood send mode, wait countdown, result, role).\r\n- GNSS; u-blox M10 nav tuning (portable dynModel + auto fixMode) and 1Hz rate for weak-signal stability.\r\n- Mgmt / UI -> UI Zoom; improved zoom step granularity for finer control with extra buttons for more/less zoom.\r\n- MAP; zoom level now automatically persists when changed (via keyboard or touch), eliminating the need for manual default zoom configuration.\r\n- MAP; removed \"Def. Zoom Lvl\" setting from Mgmt / UI as zoom now auto-saves and restores on startup.\r\n- MAP; moved zoom level indicator to top-left position (stacks under GPS info window when active).\r\n- MAP; GPS accuracy circle now renders as an unfilled light-blue ring instead of a solid fill for better map visibility.\r\n- UI; autolock is now disabled by default and only engages when enabled in Mgmt / UI -> LOCK.\r\n\r\n### Fixed\r\n- Contacts / Room Console; fixed transcript drawing over the \"Room Console\" title (partial refresh artifacts) and added a bordered transcript viewport.\r\n- MAP (T-Deck Plus); fixed reversed zoom hotkeys: I now zooms in and O zooms out.\r\n- DM editor; fixed being able to send DMs to Repeaters/Room Servers via existing DM threads (now blocked and redirected to the proper flow).\r\n- Mgmt / \n…",
          "notesHtml": "<p>This is v0.9.8 from 11.02.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<ul>\n<li>There was no change for the indicator-rp2040 module.</li>\n<li>needed to reupload, version-string was wrong!</li>\n</ul>\n<h2>[v0.9.8]</h2>\n<h3>Added</h3>\n<ul>\n<li>Contacts / Room Server; added room login + Room Console (transcript + send + logout) under Contact Detail.</li>\n<li>UI; added horizontal drag in text input fields to move the cursor (caret).</li>\n<li>Contacts: added small <code>RSTPath</code> button in Contact Detail to reset a contact's route/path.</li>\n<li>Power: added <code>PowerStatus</code> struct and <code>MainBoard::getPowerStatus()</code> helper; UI now reads consolidated power state for battery/charging/usb.</li>\n<li>Power (T-Deck Plus): added configurable ADC multiplier / VBAT divider ratio support (<code>adc.multiplier</code>) to allow per-device calibration.</li>\n<li>Mgmt / Contacts; added \"Purge w/o favs\" (purge all contacts except favourites).</li>\n<li>Mgmt / GPS; show UBX accuracy estimate (hAcc) when available.</li>\n<li>MAP (T-Deck Plus); added keyboard controls: W/A/S/D for panning, O/I for zoom in/out, R to recenter on self, T to toggle GPS/Zoom info window.</li>\n<li>MAP; added zoom level indicator overlay that displays briefly when zoom changes (keyboard or touch).</li>\n<li>MAP; added GPS info window (top-left) showing altitude, speed (km/h), and current zoom level in a compact 3-line display (toggleable with T key on T-Deck Plus).</li>\n<li>UI; added autolock feature - can be configured in Mgmt / UI -&gt; LOCK to automatically lock the UI after a period of inactivity. Unlock by holding the unlock button or touching and holding the screen for 2 seconds.</li>\n<li>Mgmt / UI; added LOCK section with configurable Autolock toggle and Autolock Timer (seconds).</li>\n</ul>\n<h3>Changed / Improved</h3>\n<ul>\n<li>Contacts; service contacts are no longer treated like normal DM targets:<ul>\n<li>Repeaters now route to Repeater Admin.</li>\n<li>Room Servers now route to the Room Console.</li>\n</ul>\n</li>\n<li>UI; horizontal swipes that switch higher-level frames now require an edge swipe (keeps left/right scrolling available for the focused element).</li>\n<li>UI (T-Deck Plus); trackball left/right no longer switches the bottom menu tabs.</li>\n<li>UI (T-Deck Plus); when editing a text field, trackball left/right moves the text cursor (caret).</li>\n<li>MAP; scroll/pan inputs now operate on the map view itself (instead of page-level scrolling).</li>\n<li>Mgmt / UI Zoom can now be changed with \"^\" or \"v\" buttons.</li>\n<li>Mgmt / Contacts; Auto Add Types can now be set with freely combinable toggles (USR/RPT/SRV/SNS/OW) when Auto Add is disabled.</li>\n<li>Mgmt / Contacts; Auto Add Types now shows clearer labels (e.g., \"USR (Users)\").</li>\n<li>Contacts / Repeater Admin; reorganized Login screen layout to prevent status text overlap and improve readability.</li>\n<li>Contacts / Repeater Admin; added live login status lines (Direct/Flood send mode, wait countdown, result, role).</li>\n<li>GNSS; u-blox M10 nav tuning (portable dynModel + auto fixMode) and 1Hz rate for weak-signal stability.</li>\n<li>Mgmt / UI -&gt; UI Zoom; improved zoom step granularity for finer control with extra buttons for more/less zoom.</li>\n<li>MAP; zoom level now automatically persists when changed (via keyboard or touch), eliminating the need for manual default zoom configuration.</li>\n<li>MAP; removed \"Def. Zoom Lvl\" setting from Mgmt / UI as zoom now auto-saves and restores on startup.</li>\n<li>MAP; moved zoom level indicator to top-left position (stacks under GPS info window when active).</li>\n<li>MAP; GPS accuracy circle now renders as an unfilled light-blue ring instead of a solid fill for better map visibility.</li>\n<li>UI; autolock is now disabled by default and only engages when enabled in Mgmt / UI -&gt; LOCK.</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>Contacts / Room Console; fixed transcript drawing over the \"Room Console\" title (partial refresh artifacts) and added a bordered transcript viewport.</li>\n<li>MAP (T-Deck Plus); fixed reversed zoom hotkeys: I now zooms in and O zooms out.</li>\n<li>DM editor; fixed being able to send DMs to Repeaters/Room Servers via existing DM threads (now blocked and redirected to the proper flow).</li>\n<li>Mgmt / \n…</li>\n</ul>\n"
        },
        {
          "version": "v0.9.7",
          "name": "v0.9.7",
          "datetime": "2026-01-30T22:32:45Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.7",
          "prerelease": false,
          "notes": "This is v0.9.7 from 30.01.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n\r\n## [v0.9.7]\r\n\r\n * Updated MeshCore Base to latest v1.12.0!\r\n\r\n### Added\r\n- Mgmt / UI -> Map; Added Map Show Zoom Buttons toggle (On/Off).\r\n- Mgmt / UI -> Map; Added Map Show Navigation Buttons toggle (On/Off).\r\n- Mgmt / UI -> Map; Added Map Default Follow Me toggle (On/Off).\r\n- Mgmt / UI -> Map; Added Map Default Zoom Level setting (1-20).\r\n- long Tap on Contacts Tab button; toggles between normal Contacts view and Discovered Nodes view to be able to add nodes when you do not activate in Mgmt / Channels the Auto Add Contacts option.\r\n- Repeater Admin Menu; Implemented role-based gating (Guest/Admin) across Repeater Admin, Overview now visually disables admin-only buttons (ACL, CLI, Reboot, Passwords) when role isn’t Admin, and taps show a short popup instead of entering the screen. Device/Status/Telemetry overlays allow read-only viewing for Guest/RO, but write actions (edits/toggles/off/sync/reboot) are disabled visually and blocked on tap with a “RW/Admin required” popup.\r\n- Indicator; (NEW IMAGE for RP2040 needed) Sound is now Supported & can be configured in Mgmt / UI -> Sound settings and will be processesd on the RP2040 coprocessor.\r\n- Indicator; (NEW IMAGE for RP2040 needed) Added SenseCAP RP2040 SDCARD Support for remote SD access (read/write/list) does not yet offer direct services but will be used in future updates.\r\n- Indicator; (NEW IMAGE for RP2040 needed) Added SenseCAP RP2040 Sensor Support for Temperature, Humidity, CO2, TVOC telemetry values (when RP2040 firmware is flashed with the new coprocessor image).\r\n- MAP; tiles now can be donwloaded while you are connected to WiFi (when enabled in Mgmt / UI -> Map). If there is a SDCard present, it will automatically cache the tiles on the SDCard in the correct folder structure for offline use! (Indicator not yet supported!)\r\n- Mgmt / UI -> Map; added info text about tile caching when WiFi is connected.\r\n- Mgmt / UI -> Map; changed Map Tile folder structure from SD-Card.\r\n- Mgmt / Messages; Addeed Auto Retry / Auto Reset Path / Direct Message Acks / Mark Delivered faster (like you know from the companion APP) but need to be setup separately because not connected to companion!\r\n- MSGs / new button in Message \"Reply\" to quickly reply to the last DM or Channel message sender.\r\n- Sync settings to SDCard and load from SDCard on boot (if present) for easy backup/restore of settings.\r\n- MAP; GPS Accuracy Circle Implementation - when GPS accuracy is available, a light blue circle is drawn around the GPS position indicating the accuracy radius (HDOP-based accuracy estimation (HDOP × 2.0 meters)).\r\n\r\n### Changed / Improved\r\n- MAP; improved hop-count display in Contact detail view (shows \"Direct\" for 0 hops now and \"1 hop\", \"2 hops\", ... for others).\r\n- Mgmt / Advert; neighbor adverts refactored to show more relevant information, and added the possibility to add discovered nodes as Contacts directly from the neighbor adverts list.\r\n- Mgmt / Advert; changed button text \"Advert Zero Hop\" to \"Advert - Direct\"\r\n- Mgmt / UI - moved Sound settings to Mgmt / UI for better grouping.\r\n- Mgmt / Global - moved Mgmt / Admin into this menu for better grouping.\r\n- Mgmt; changed some Texts&Buttons for better clarity (toggle, enabled/disabled)\r\n- GUI; finally you can switch between BLE / WiFi or turn both completely off (without reboot!).\r\n- Repeater Admin Menu / Advert; when disable both advert types, a warning popup (yes/no) is shown to inform the user that no adverts will be sent out anymore when accepted.\r\n- MSGS; changed the top statusbar text from \"msgs\" to \"Channels\" and from \"users\" to \"DMs\" for better clarity.\r\n- Contacts / soting; when you tap the contacts tab to cycle through sort orders, the view will automatically scroll to the top of the newly sorted list, making it much more user-friendly!\r\n- Mgmt / CLI; fixed an issue while switching away from CLI breaks the t\n…",
          "notesHtml": "<p>This is v0.9.7 from 30.01.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<h2>[v0.9.7]</h2>\n<ul>\n<li>Updated MeshCore Base to latest v1.12.0!</li>\n</ul>\n<h3>Added</h3>\n<ul>\n<li>Mgmt / UI -&gt; Map; Added Map Show Zoom Buttons toggle (On/Off).</li>\n<li>Mgmt / UI -&gt; Map; Added Map Show Navigation Buttons toggle (On/Off).</li>\n<li>Mgmt / UI -&gt; Map; Added Map Default Follow Me toggle (On/Off).</li>\n<li>Mgmt / UI -&gt; Map; Added Map Default Zoom Level setting (1-20).</li>\n<li>long Tap on Contacts Tab button; toggles between normal Contacts view and Discovered Nodes view to be able to add nodes when you do not activate in Mgmt / Channels the Auto Add Contacts option.</li>\n<li>Repeater Admin Menu; Implemented role-based gating (Guest/Admin) across Repeater Admin, Overview now visually disables admin-only buttons (ACL, CLI, Reboot, Passwords) when role isn’t Admin, and taps show a short popup instead of entering the screen. Device/Status/Telemetry overlays allow read-only viewing for Guest/RO, but write actions (edits/toggles/off/sync/reboot) are disabled visually and blocked on tap with a “RW/Admin required” popup.</li>\n<li>Indicator; (NEW IMAGE for RP2040 needed) Sound is now Supported &amp; can be configured in Mgmt / UI -&gt; Sound settings and will be processesd on the RP2040 coprocessor.</li>\n<li>Indicator; (NEW IMAGE for RP2040 needed) Added SenseCAP RP2040 SDCARD Support for remote SD access (read/write/list) does not yet offer direct services but will be used in future updates.</li>\n<li>Indicator; (NEW IMAGE for RP2040 needed) Added SenseCAP RP2040 Sensor Support for Temperature, Humidity, CO2, TVOC telemetry values (when RP2040 firmware is flashed with the new coprocessor image).</li>\n<li>MAP; tiles now can be donwloaded while you are connected to WiFi (when enabled in Mgmt / UI -&gt; Map). If there is a SDCard present, it will automatically cache the tiles on the SDCard in the correct folder structure for offline use! (Indicator not yet supported!)</li>\n<li>Mgmt / UI -&gt; Map; added info text about tile caching when WiFi is connected.</li>\n<li>Mgmt / UI -&gt; Map; changed Map Tile folder structure from SD-Card.</li>\n<li>Mgmt / Messages; Addeed Auto Retry / Auto Reset Path / Direct Message Acks / Mark Delivered faster (like you know from the companion APP) but need to be setup separately because not connected to companion!</li>\n<li>MSGs / new button in Message \"Reply\" to quickly reply to the last DM or Channel message sender.</li>\n<li>Sync settings to SDCard and load from SDCard on boot (if present) for easy backup/restore of settings.</li>\n<li>MAP; GPS Accuracy Circle Implementation - when GPS accuracy is available, a light blue circle is drawn around the GPS position indicating the accuracy radius (HDOP-based accuracy estimation (HDOP × 2.0 meters)).</li>\n</ul>\n<h3>Changed / Improved</h3>\n<ul>\n<li>MAP; improved hop-count display in Contact detail view (shows \"Direct\" for 0 hops now and \"1 hop\", \"2 hops\", ... for others).</li>\n<li>Mgmt / Advert; neighbor adverts refactored to show more relevant information, and added the possibility to add discovered nodes as Contacts directly from the neighbor adverts list.</li>\n<li>Mgmt / Advert; changed button text \"Advert Zero Hop\" to \"Advert - Direct\"</li>\n<li>Mgmt / UI - moved Sound settings to Mgmt / UI for better grouping.</li>\n<li>Mgmt / Global - moved Mgmt / Admin into this menu for better grouping.</li>\n<li>Mgmt; changed some Texts&amp;Buttons for better clarity (toggle, enabled/disabled)</li>\n<li>GUI; finally you can switch between BLE / WiFi or turn both completely off (without reboot!).</li>\n<li>Repeater Admin Menu / Advert; when disable both advert types, a warning popup (yes/no) is shown to inform the user that no adverts will be sent out anymore when accepted.</li>\n<li>MSGS; changed the top statusbar text from \"msgs\" to \"Channels\" and from \"users\" to \"DMs\" for better clarity.</li>\n<li>Contacts / soting; when you tap the contacts tab to cycle through sort orders, the view will automatically scroll to the top of the newly sorted list, making it much more user-friendly!</li>\n<li>Mgmt / CLI; fixed an issue while switching away from CLI breaks the t\n…</li>\n</ul>\n"
        },
        {
          "version": "v0.9.5",
          "name": "v0.9.5",
          "datetime": "2026-01-23T23:00:03Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.5",
          "prerelease": false,
          "notes": "This is v0.9.5 from 23.01.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n\r\n## [v0.9.5] — 2026-01-23\r\n\r\n### Added\r\n- Repeater; Added new Repeater Admin Overview Menu when you select in Contacts a Repeater -> login -> new menu with Repeater Admin options.\r\n- Repeater; Added Reboot Repeater option in Repeater Admin Menu -> Device.\r\n- Repeater; Added Repeater Device Info option in Repeater Admin Menu -> Device.\r\n- Repeater; Added Repeater Radio Info option in Repeater Admin Menu -> Device.\r\n- Repeater; Added Repeater TX Power Info option in Repeater Admin Menu.\r\n- Repeater; Added Repeater Firmware Version Info option in Repeater Admin Menu.\r\n- Repeater; Added Repeater CLI option in Repeater Admin Menu -> CLI.\r\n- Repeater; Added proper output formatting for Repeater Neighbor Scan results.\r\n- Repeater; Added ability to add/remove Contacts to/from Repeater ACL.\r\n- Mgmt / Global -> Soundes; Added Sounds for various events (On/Off) and Volume Control.\r\n- Mgmt / UI -> Light; Added Keyboard Blink on messages (Ch:1, DM:2) and Display Blink duration setting.\r\n- Mgmt / UI -> Light; Added Display Auto Off timeout setting (5s, 15s, 30s, 1min, 5min, Never).\r\n\r\n### Changed / Improved\r\n- Bootlogo now shows new Firmware name [M(esh)C(ore) Term].\r\n- Mgmt / Log; Autoscroll is now enabled by default.\r\n- Mgmt / Channels; separated Add/Join Channel into separate Buttons.\r\n- Contacts; adapted text in statusbar \"filter\" to \"sort\" for clarity.\r\n- Contacts; sort \"favs\" now shows favs on top (a-z), then rest a-z.\r\n- Repeater; improved Neighbor Scan output formatting.\r\n\r\n### Fixed\r\n- Repeater Login in Companion App: fixed an issue where login to a repeater from the Companion App did not work properly.\r\n- Timezone was not working as expected: updated with a proper implementation using Proleptic Format for TZ strings (manual configuration step).\r\n- Contacts with Emoji in their name could not send us DMs — fixed.\r\n- Contacts; sorting of \"last heard\" was not working properly — fixed.\r\n- Repeater; Telemetry request from Repeater contacts was not working properly — fixed.\r\n- UI; Sound playback now continues even when the display turns off.\r\n- Copy to Clipboard was not working properly in some cases — fixed.\r\n- GPS renewed and improved detection and initialization process (should work more reliable now).",
          "notesHtml": "<p>This is v0.9.5 from 23.01.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<h2>[v0.9.5] — 2026-01-23</h2>\n<h3>Added</h3>\n<ul>\n<li>Repeater; Added new Repeater Admin Overview Menu when you select in Contacts a Repeater -&gt; login -&gt; new menu with Repeater Admin options.</li>\n<li>Repeater; Added Reboot Repeater option in Repeater Admin Menu -&gt; Device.</li>\n<li>Repeater; Added Repeater Device Info option in Repeater Admin Menu -&gt; Device.</li>\n<li>Repeater; Added Repeater Radio Info option in Repeater Admin Menu -&gt; Device.</li>\n<li>Repeater; Added Repeater TX Power Info option in Repeater Admin Menu.</li>\n<li>Repeater; Added Repeater Firmware Version Info option in Repeater Admin Menu.</li>\n<li>Repeater; Added Repeater CLI option in Repeater Admin Menu -&gt; CLI.</li>\n<li>Repeater; Added proper output formatting for Repeater Neighbor Scan results.</li>\n<li>Repeater; Added ability to add/remove Contacts to/from Repeater ACL.</li>\n<li>Mgmt / Global -&gt; Soundes; Added Sounds for various events (On/Off) and Volume Control.</li>\n<li>Mgmt / UI -&gt; Light; Added Keyboard Blink on messages (Ch:1, DM:2) and Display Blink duration setting.</li>\n<li>Mgmt / UI -&gt; Light; Added Display Auto Off timeout setting (5s, 15s, 30s, 1min, 5min, Never).</li>\n</ul>\n<h3>Changed / Improved</h3>\n<ul>\n<li>Bootlogo now shows new Firmware name [M(esh)C(ore) Term].</li>\n<li>Mgmt / Log; Autoscroll is now enabled by default.</li>\n<li>Mgmt / Channels; separated Add/Join Channel into separate Buttons.</li>\n<li>Contacts; adapted text in statusbar \"filter\" to \"sort\" for clarity.</li>\n<li>Contacts; sort \"favs\" now shows favs on top (a-z), then rest a-z.</li>\n<li>Repeater; improved Neighbor Scan output formatting.</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>Repeater Login in Companion App: fixed an issue where login to a repeater from the Companion App did not work properly.</li>\n<li>Timezone was not working as expected: updated with a proper implementation using Proleptic Format for TZ strings (manual configuration step).</li>\n<li>Contacts with Emoji in their name could not send us DMs — fixed.</li>\n<li>Contacts; sorting of \"last heard\" was not working properly — fixed.</li>\n<li>Repeater; Telemetry request from Repeater contacts was not working properly — fixed.</li>\n<li>UI; Sound playback now continues even when the display turns off.</li>\n<li>Copy to Clipboard was not working properly in some cases — fixed.</li>\n<li>GPS renewed and improved detection and initialization process (should work more reliable now).</li>\n</ul>\n"
        },
        {
          "version": "v0.9.4",
          "name": "v0.9.4",
          "datetime": "2026-01-21T22:52:40Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v0.9.4",
          "prerelease": false,
          "notes": "This is v0.9.4 from 21.01.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n\r\n## [v0.9.4] — 2026-01-21\r\n\r\n### Added\r\n- Mgmt / \"Date/Time\": set Date, Time, Timezone, NTP server, Time from GPS toggle.\r\n- Mgmt / Contacts: ondevice Purge contacts now possible (deletes all contacts except self).\r\n- Contacts: added repeater login feature — request login to a repeater from Contact detail view; Additional remote repeater features - Neighbors, ACLs\r\n- Autoupdater(t-deck): initial implementation — Mgmt → Admin → Update & Upgrade; check for new firmware versions and apply OTA updates from Github releases of this Firmware.\r\n- Repeater: CLI command support — send CLI commands to a repeater from Contact detail view; output like in a Terminal UI.\r\n- Repeater: password-protected admin access — repeater can be configured to require password for admin commands (login, neighbor scan, ACL management).\r\n- Repeater: neighbor scan support — request neighbor scan from Contact detail view; results shown in Contact detail.\r\n- Repeater: ACL management — add/remove contacts to/from repeater ACL from Contact detail view\r\n- Repeater: saved credentials — when logging into a repeater, credentials could be saved for future sessions.\r\n- Channels: Join/Add channel via Key (base64) or via #hashtag name when pressing long on \"Msgs\" Menu button or in the Mgmt / Channels page.\r\n- Mgmt: new overview page implemented to easy&fast navigate to the needed page.\r\n- Mgmt / Contacts: Added toggle row Auto Add Contacts (On/Off) + a short info row (“Adds from adverts”).\r\n- Mgmt / Channels: Added new Page for adding Channels / delete Channels.\r\n- Mgmt / Stats: Added live SNR, RSSI, Noise floor = Link Margin display (updated every second in a separate layer).\r\n- Added Cyrillic characters.\r\n- MAP: Added \"Follow Me\" button — centers map on own GPS position and keeps following until user pans the map manually.\r\n- renamed \"Channels\" to \"Msgs\" in the main menu for clarity.\r\n- Channels: Jump to first unread message — when opening a Channel with unread messages, the message list now auto-scrolls to the first unread message.\r\n- Channels: red indicator line for unread messages — in Channel message view, a red line now marks the position of the first unread message. Opens automatically to the first unread message!\r\n- In Repeater Admin → CLI (direct typing, not the modal editor): Enter still sends immediately (unchanged). Ctrl+L (byte 0x0C, same as the old Alt+C code) now clears the CLI output window  “screen clear”) and keeps you in CLI. Ctrl+U (byte 0x15) clears just the current input line.\r\n- Channels / DMs: improved message detail view — better layout, fixed scrolling behavior.\r\n- Channels / DMs: as long as there is no message written in a DM, and you go back to the DMs overview only when there was a message written, the DM will be created/saved.\r\n- Channels / DMs: long-press Back clears the current transcript (bulk delete all messages in channel/DM).\r\n- Contacts: Added filter option “Favs only” — show only favourite contacts.\r\n- Mgmt / Admin: Added Firmware Version display (incl. Mod FW).\r\n- Contacts: The Statusbar RED Mail indicator is now visible in the Contacts Page next to the User who was writing the last unread message to you.\r\n- Msgs: (for devices with physical Keyboard) if you are in a Channel, or in a DM, you now can start typing a message directly without having to press the Send button first to open the input field. But show the Send Button anyways!\r\n- Implemented a confirmation window when switching between WiFi and BLE modes (which requires a reboot).\r\n- Msgs: show how many channels (slots) are in use, and how many are free (e.g., \"3/10\").\r\n- Msgs: in Channels / DMs when there are unread messages, you now will \"read\" messages while scrolling to the last message, no need for extra opening the messages to mark them as read.\r\n- small Code cleanups and optimizations (never ending story :)).\r\n\r\n### Changed / Improved\r\n- Cyrillic Let\n…",
          "notesHtml": "<p>This is v0.9.4 from 21.01.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<h2>[v0.9.4] — 2026-01-21</h2>\n<h3>Added</h3>\n<ul>\n<li>Mgmt / \"Date/Time\": set Date, Time, Timezone, NTP server, Time from GPS toggle.</li>\n<li>Mgmt / Contacts: ondevice Purge contacts now possible (deletes all contacts except self).</li>\n<li>Contacts: added repeater login feature — request login to a repeater from Contact detail view; Additional remote repeater features - Neighbors, ACLs</li>\n<li>Autoupdater(t-deck): initial implementation — Mgmt → Admin → Update &amp; Upgrade; check for new firmware versions and apply OTA updates from Github releases of this Firmware.</li>\n<li>Repeater: CLI command support — send CLI commands to a repeater from Contact detail view; output like in a Terminal UI.</li>\n<li>Repeater: password-protected admin access — repeater can be configured to require password for admin commands (login, neighbor scan, ACL management).</li>\n<li>Repeater: neighbor scan support — request neighbor scan from Contact detail view; results shown in Contact detail.</li>\n<li>Repeater: ACL management — add/remove contacts to/from repeater ACL from Contact detail view</li>\n<li>Repeater: saved credentials — when logging into a repeater, credentials could be saved for future sessions.</li>\n<li>Channels: Join/Add channel via Key (base64) or via #hashtag name when pressing long on \"Msgs\" Menu button or in the Mgmt / Channels page.</li>\n<li>Mgmt: new overview page implemented to easy&amp;fast navigate to the needed page.</li>\n<li>Mgmt / Contacts: Added toggle row Auto Add Contacts (On/Off) + a short info row (“Adds from adverts”).</li>\n<li>Mgmt / Channels: Added new Page for adding Channels / delete Channels.</li>\n<li>Mgmt / Stats: Added live SNR, RSSI, Noise floor = Link Margin display (updated every second in a separate layer).</li>\n<li>Added Cyrillic characters.</li>\n<li>MAP: Added \"Follow Me\" button — centers map on own GPS position and keeps following until user pans the map manually.</li>\n<li>renamed \"Channels\" to \"Msgs\" in the main menu for clarity.</li>\n<li>Channels: Jump to first unread message — when opening a Channel with unread messages, the message list now auto-scrolls to the first unread message.</li>\n<li>Channels: red indicator line for unread messages — in Channel message view, a red line now marks the position of the first unread message. Opens automatically to the first unread message!</li>\n<li>In Repeater Admin → CLI (direct typing, not the modal editor): Enter still sends immediately (unchanged). Ctrl+L (byte 0x0C, same as the old Alt+C code) now clears the CLI output window  “screen clear”) and keeps you in CLI. Ctrl+U (byte 0x15) clears just the current input line.</li>\n<li>Channels / DMs: improved message detail view — better layout, fixed scrolling behavior.</li>\n<li>Channels / DMs: as long as there is no message written in a DM, and you go back to the DMs overview only when there was a message written, the DM will be created/saved.</li>\n<li>Channels / DMs: long-press Back clears the current transcript (bulk delete all messages in channel/DM).</li>\n<li>Contacts: Added filter option “Favs only” — show only favourite contacts.</li>\n<li>Mgmt / Admin: Added Firmware Version display (incl. Mod FW).</li>\n<li>Contacts: The Statusbar RED Mail indicator is now visible in the Contacts Page next to the User who was writing the last unread message to you.</li>\n<li>Msgs: (for devices with physical Keyboard) if you are in a Channel, or in a DM, you now can start typing a message directly without having to press the Send button first to open the input field. But show the Send Button anyways!</li>\n<li>Implemented a confirmation window when switching between WiFi and BLE modes (which requires a reboot).</li>\n<li>Msgs: show how many channels (slots) are in use, and how many are free (e.g., \"3/10\").</li>\n<li>Msgs: in Channels / DMs when there are unread messages, you now will \"read\" messages while scrolling to the last message, no need for extra opening the messages to mark them as read.</li>\n<li>small Code cleanups and optimizations (never ending story :)).</li>\n</ul>\n<h3>Changed / Improved</h3>\n<ul>\n<li>Cyrillic Let\n…</li>\n</ul>\n"
        },
        {
          "version": "v8",
          "name": "v8 - 2026-01-14",
          "datetime": "2026-01-15T19:36:40Z",
          "url": "https://github.com/dabeani/meshcoreterm/releases/tag/v8",
          "prerelease": false,
          "notes": "This is v8 from 14.01.2026.\r\nPlease have a look at the filename, to download the correct variant for your device!\r\n\r\n## [v8] — 2026-01-14\r\n\r\n### Added\r\n- Channels: Custom Command — configure via Mgmt → UI.\r\n- Mgmt: Tele page — compact self-telemetry panel (VBAT, GPS, env values).\r\n- Admin: System section — uptime, heap, PSRAM, flash/sketch usage, CPU, chip model/rev/cores, reset reason.\r\n- Radio presets — predefined presets in Mgmt → Radio; selecting a preset applies settings and reboots.\r\n\r\n### Changed / Improved\r\n- Channels UI — redesigned layout; scroll-to-newest now marks all messages read.\r\n- Mgmt / Log — layout updated to Channels-style with extended information.\r\n- Mgmt / GPS — added RX/TX/Baud custom values.\r\n- Battery press — short press toggles Volts ↔ Percent; long press still opens power popup; realtime duty-cycle display added.\r\n- Contacts tab button — short press cycles filters (A–Z → Last heard → Last msg) and shows a 5s statusbar overlay; long press jumps to top.\r\n- SenseCap — default text size increased (adjustable via ZOOM).\r\n- Nick coloring — colored device names across UI (resets on reboot).\r\n\r\n### Fixed\r\n- Neighbor discovery — refactored and working.",
          "notesHtml": "<p>This is v8 from 14.01.2026.\nPlease have a look at the filename, to download the correct variant for your device!</p>\n<h2>[v8] — 2026-01-14</h2>\n<h3>Added</h3>\n<ul>\n<li>Channels: Custom Command — configure via Mgmt → UI.</li>\n<li>Mgmt: Tele page — compact self-telemetry panel (VBAT, GPS, env values).</li>\n<li>Admin: System section — uptime, heap, PSRAM, flash/sketch usage, CPU, chip model/rev/cores, reset reason.</li>\n<li>Radio presets — predefined presets in Mgmt → Radio; selecting a preset applies settings and reboots.</li>\n</ul>\n<h3>Changed / Improved</h3>\n<ul>\n<li>Channels UI — redesigned layout; scroll-to-newest now marks all messages read.</li>\n<li>Mgmt / Log — layout updated to Channels-style with extended information.</li>\n<li>Mgmt / GPS — added RX/TX/Baud custom values.</li>\n<li>Battery press — short press toggles Volts ↔ Percent; long press still opens power popup; realtime duty-cycle display added.</li>\n<li>Contacts tab button — short press cycles filters (A–Z → Last heard → Last msg) and shows a 5s statusbar overlay; long press jumps to top.</li>\n<li>SenseCap — default text size increased (adjustable via ZOOM).</li>\n<li>Nick coloring — colored device names across UI (resets on reboot).</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>Neighbor discovery — refactored and working.</li>\n</ul>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:38.909Z"
    },
    {
      "id": "offband-mesh",
      "name": "Offband Mesh",
      "type": "fork",
      "maintainer": "OffbandMesh",
      "description": "A MeshCore fork for cross-role firmware enhancements and optimization. Active roles include companion/observer with WiFi+MQTT observation publishing, NimBLE migration, web UI, and repeater with MQTT-to-Mosquitto bridging, burst-WiFi telemetry, heap and power tuning.\n",
      "repository": "https://github.com/OffbandMesh/meshcore-firmware",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "observer"
      ],
      "features": [
        "Companion/observer with WiFi+MQTT observation publishing",
        "NimBLE migration (off Bluedroid)",
        "CrashLog / boot-survival diagnostics",
        "MQTT-to-Mosquitto bridging (repeater)",
        "Burst-WiFi telemetry",
        "Heap and power optimization for ESP32-S3",
        "Web UI"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": false,
          "observer": true,
          "mqtt": true,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "heltec-v4",
          "status": "supported"
        },
        {
          "id": "heltec-v3",
          "status": "supported"
        },
        {
          "id": "xiao-esp32s3",
          "status": "supported"
        }
      ],
      "latest_version": "1.0.0",
      "released": "2026-06-18",
      "releases": [
        {
          "version": "offband-v1.0.0",
          "name": "Offband offband-v1.0.0",
          "datetime": "2026-06-18T00:46:24Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/offband-v1.0.0",
          "prerelease": false,
          "notes": "First production-stable Offband release — companion, observer, and repeater roles\nall working and hardware-verified. Built on the **MeshCore 1.16.0** base.\n\n### Base\n- **MeshCore 1.16.0 base-update** (#126) — the fork is rebased onto upstream MeshCore\n  1.16.0, smoke-verified across all three active roles (Companion, Observer, Repeater)\n  on Heltec V3/V4 + RAK3401.\n\n### Added\n- **RAK3401 (WisMesh 1W) GPS** (#104) — the RAK12500 (u-blox ZOE-M8Q) I²C GPS now works\n  in Slot D. Companion and repeater acquire a position fix. (Position only; the I²C\n  path does not sync the clock.)\n- **Display always-on toggle** (#141) — `display always on` keeps a USB/mains-powered\n  observer's screen lit; `display normal` restores the 15 s timeout. Persists across\n  reboots, applies immediately. Heltec V3, V4 OLED, V4 TFT observers.\n- **Display rotation (0/180)** (#148) — `display rotate 0/180` / `display flip` over the\n  `_sys` channel; persists, applies immediately. **Verified on the OLED observers\n  (Heltec V3, V4 OLED).** Displays without a verified rotation driver (the V4 TFT)\n  report `rotation not supported on this display` rather than silently no-op'ing; TFT\n  rotation is tracked separately.\n\n### Known issues\n- **Heltec V4 observer GPS position unverified** (#149) — an attached UART GPS doesn't\n  yet surface a position on the V4 observer (reads 0,0). Observer time (NTP/SNTP) and all\n  other function are unaffected; GPS only adds the device's own map-position dot.\n\n\n---\n\n### Which file do I download?\n\n| File | What it is | When to use it |\n|---|---|---|\n| `*-merged.bin` (ESP32 — Heltec V3/V4, XIAO) | **Full image** — bootloader + partition table + app in one, flashed at `0x0` after a chip erase. Self-contained, works on a blank chip. | **First install / clean setup.** In a web flasher this is the **\"Full Firmware\"** option. |\n| `*.bin` (ESP32) | **App only** — flashed at the app offset (`0x10000`); the bootloader must already be on the chip. | **Updating** an existing node — OTA / **\"Update Only.\"** Keeps the device identity + WiFi/MQTT config. |\n| `*.uf2` (nRF52 — RAK, T-Echo, XIAO nRF52) | Complete self-contained image. | **First install *and* updates** — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.) |\n\n> ⚠️ **ESP32:** the app-only `*.bin` will **not boot** if flashed at `0x0` — use `*-merged.bin` for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, **never** a routine update.\n\n\n## What's Changed\n* epic(#126): MeshCore 1.16.0 base-update (integration) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/134\n\n\n**Full Changelog**: https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.1...offband-v1.0.0",
          "notesHtml": "<p>First production-stable Offband release — companion, observer, and repeater roles\nall working and hardware-verified. Built on the <strong>MeshCore 1.16.0</strong> base.</p>\n<h3>Base</h3>\n<ul>\n<li><strong>MeshCore 1.16.0 base-update</strong> (#126) — the fork is rebased onto upstream MeshCore\n1.16.0, smoke-verified across all three active roles (Companion, Observer, Repeater)\non Heltec V3/V4 + RAK3401.</li>\n</ul>\n<h3>Added</h3>\n<ul>\n<li><strong>RAK3401 (WisMesh 1W) GPS</strong> (#104) — the RAK12500 (u-blox ZOE-M8Q) I²C GPS now works\nin Slot D. Companion and repeater acquire a position fix. (Position only; the I²C\npath does not sync the clock.)</li>\n<li><strong>Display always-on toggle</strong> (#141) — <code>display always on</code> keeps a USB/mains-powered\nobserver's screen lit; <code>display normal</code> restores the 15 s timeout. Persists across\nreboots, applies immediately. Heltec V3, V4 OLED, V4 TFT observers.</li>\n<li><strong>Display rotation (0/180)</strong> (#148) — <code>display rotate 0/180</code> / <code>display flip</code> over the\n<code>_sys</code> channel; persists, applies immediately. <strong>Verified on the OLED observers\n(Heltec V3, V4 OLED).</strong> Displays without a verified rotation driver (the V4 TFT)\nreport <code>rotation not supported on this display</code> rather than silently no-op'ing; TFT\nrotation is tracked separately.</li>\n</ul>\n<h3>Known issues</h3>\n<ul>\n<li><strong>Heltec V4 observer GPS position unverified</strong> (#149) — an attached UART GPS doesn't\nyet surface a position on the V4 observer (reads 0,0). Observer time (NTP/SNTP) and all\nother function are unaffected; GPS only adds the device's own map-position dot.</li>\n</ul>\n<hr />\n<h3>Which file do I download?</h3>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>What it is</th>\n<th>When to use it</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>*-merged.bin</code> (ESP32 — Heltec V3/V4, XIAO)</td>\n<td><strong>Full image</strong> — bootloader + partition table + app in one, flashed at <code>0x0</code> after a chip erase. Self-contained, works on a blank chip.</td>\n<td><strong>First install / clean setup.</strong> In a web flasher this is the <strong>\"Full Firmware\"</strong> option.</td>\n</tr>\n<tr>\n<td><code>*.bin</code> (ESP32)</td>\n<td><strong>App only</strong> — flashed at the app offset (<code>0x10000</code>); the bootloader must already be on the chip.</td>\n<td><strong>Updating</strong> an existing node — OTA / <strong>\"Update Only.\"</strong> Keeps the device identity + WiFi/MQTT config.</td>\n</tr>\n<tr>\n<td><code>*.uf2</code> (nRF52 — RAK, T-Echo, XIAO nRF52)</td>\n<td>Complete self-contained image.</td>\n<td><strong>First install <em>and</em> updates</strong> — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.)</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p>⚠️ <strong>ESP32:</strong> the app-only <code>*.bin</code> will <strong>not boot</strong> if flashed at <code>0x0</code> — use <code>*-merged.bin</code> for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, <strong>never</strong> a routine update.</p>\n</blockquote>\n<h2>What's Changed</h2>\n<ul>\n<li>epic(#126): MeshCore 1.16.0 base-update (integration) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/134\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/134</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.1...offband-v1.0.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.1...offband-v1.0.0</a></p>\n"
        },
        {
          "version": "offband-v0.19.0-rc1",
          "name": "Offband offband-v0.19.0-rc1",
          "datetime": "2026-06-16T04:06:18Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/offband-v0.19.0-rc1",
          "prerelease": true,
          "notes": "## Display `_sys` enhancements (RC1 — for testing)\r\n\r\nTwo new observer/companion display controls over the `_sys` channel:\r\n\r\n- **Display always-on** (#141) — `display always on` keeps the screen lit; `display normal` restores the 15 s blank. *(Verified: V3/V4 OLED + V4 TFT.)*\r\n- **Display rotation 0/180** (#148) — `display rotate 0` / `display rotate 180` / `display flip` flip the screen for upside-down mounting. *(Verified: V3/V4 OLED.)*\r\n\r\n> ⚠️ **TFT 180° rotation is UNVERIFIED — this is the thing to test.** On the Heltec V4 **TFT** (`heltec_v4_tft_companion_observer_wifi`), `display rotate 180` uses a best-guess MADCTL combo (`flipScreenVertically`). Please confirm it gives a clean **180° flip** (upside-down but readable), not a mirror or garbled image. `display rotate 0` should return to normal; `display flip` should toggle. Report back — it's a one-line fix if the combo is wrong.\r\n\r\n**TFT flash:** `heltec_v4_tft_companion_observer_wifi-v0.19.0-rc1-14bc32d-merged.bin` (full image — web-flasher **\"Full Firmware\"** for a fresh install), or the `.bin` (app-only) to update an existing node and keep its identity/config.\r\n\r\n---\r\n\r\n### Which file do I download?\r\n\r\n| File | What it is | When to use it |\r\n|---|---|---|\r\n| `*-merged.bin` (ESP32 — Heltec V3/V4, XIAO) | **Full image** — bootloader + partition table + app in one, flashed at `0x0` after a chip erase. Self-contained, works on a blank chip. | **First install / clean setup.** In a web flasher this is the **\"Full Firmware\"** option. |\r\n| `*.bin` (ESP32) | **App only** — flashed at the app offset (`0x10000`); the bootloader must already be on the chip. | **Updating** an existing node — OTA / **\"Update Only.\"** Keeps the device identity + WiFi/MQTT config. |\r\n| `*.uf2` (nRF52 — RAK, T-Echo, XIAO nRF52) | Complete self-contained image. | **First install *and* updates** — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.) |\r\n\r\n> ⚠️ **ESP32:** the app-only `*.bin` will **not boot** if flashed at `0x0` — use `*-merged.bin` for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, **never** a routine update.\r\n\r\n\r\n**Full Changelog**: https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.1...offband-v0.19.0-rc1",
          "notesHtml": "<h2>Display <code>_sys</code> enhancements (RC1 — for testing)</h2>\n<p>Two new observer/companion display controls over the <code>_sys</code> channel:</p>\n<ul>\n<li><strong>Display always-on</strong> (#141) — <code>display always on</code> keeps the screen lit; <code>display normal</code> restores the 15 s blank. <em>(Verified: V3/V4 OLED + V4 TFT.)</em></li>\n<li><strong>Display rotation 0/180</strong> (#148) — <code>display rotate 0</code> / <code>display rotate 180</code> / <code>display flip</code> flip the screen for upside-down mounting. <em>(Verified: V3/V4 OLED.)</em></li>\n</ul>\n<blockquote>\n<p>⚠️ <strong>TFT 180° rotation is UNVERIFIED — this is the thing to test.</strong> On the Heltec V4 <strong>TFT</strong> (<code>heltec_v4_tft_companion_observer_wifi</code>), <code>display rotate 180</code> uses a best-guess MADCTL combo (<code>flipScreenVertically</code>). Please confirm it gives a clean <strong>180° flip</strong> (upside-down but readable), not a mirror or garbled image. <code>display rotate 0</code> should return to normal; <code>display flip</code> should toggle. Report back — it's a one-line fix if the combo is wrong.</p>\n</blockquote>\n<p><strong>TFT flash:</strong> <code>heltec_v4_tft_companion_observer_wifi-v0.19.0-rc1-14bc32d-merged.bin</code> (full image — web-flasher <strong>\"Full Firmware\"</strong> for a fresh install), or the <code>.bin</code> (app-only) to update an existing node and keep its identity/config.</p>\n<hr />\n<h3>Which file do I download?</h3>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>What it is</th>\n<th>When to use it</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>*-merged.bin</code> (ESP32 — Heltec V3/V4, XIAO)</td>\n<td><strong>Full image</strong> — bootloader + partition table + app in one, flashed at <code>0x0</code> after a chip erase. Self-contained, works on a blank chip.</td>\n<td><strong>First install / clean setup.</strong> In a web flasher this is the <strong>\"Full Firmware\"</strong> option.</td>\n</tr>\n<tr>\n<td><code>*.bin</code> (ESP32)</td>\n<td><strong>App only</strong> — flashed at the app offset (<code>0x10000</code>); the bootloader must already be on the chip.</td>\n<td><strong>Updating</strong> an existing node — OTA / <strong>\"Update Only.\"</strong> Keeps the device identity + WiFi/MQTT config.</td>\n</tr>\n<tr>\n<td><code>*.uf2</code> (nRF52 — RAK, T-Echo, XIAO nRF52)</td>\n<td>Complete self-contained image.</td>\n<td><strong>First install <em>and</em> updates</strong> — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.)</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p>⚠️ <strong>ESP32:</strong> the app-only <code>*.bin</code> will <strong>not boot</strong> if flashed at <code>0x0</code> — use <code>*-merged.bin</code> for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, <strong>never</strong> a routine update.</p>\n</blockquote>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.1...offband-v0.19.0-rc1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.1...offband-v0.19.0-rc1</a></p>\n"
        },
        {
          "version": "offband-v0.18.1",
          "name": "Offband offband-v0.18.1",
          "datetime": "2026-06-15T03:08:16Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/offband-v0.18.1",
          "prerelease": false,
          "notes": "### Fixed\n- **WiFi password confirmation wording** — `set wifi.pwd` now replies\n  `wifi.pwd set (N chars entered)` instead of `wifi.pwd set (length=N)`, which was\n  being misread as a 17-character maximum. The reply reports the length of what was\n  *entered* (never the secret PSK); it is not a cap. WiFi passwords accept the full\n  WPA2 range (8–63 chars).\n\n\n---\n\n### Which file do I download?\n\n| File | What it is | When to use it |\n|---|---|---|\n| `*-merged.bin` (ESP32 — Heltec V3/V4, XIAO) | **Full image** — bootloader + partition table + app in one, flashed at `0x0` after a chip erase. Self-contained, works on a blank chip. | **First install / clean setup.** In a web flasher this is the **\"Full Firmware\"** option. |\n| `*.bin` (ESP32) | **App only** — flashed at the app offset (`0x10000`); the bootloader must already be on the chip. | **Updating** an existing node — OTA / **\"Update Only.\"** Keeps the device identity + WiFi/MQTT config. |\n| `*.uf2` (nRF52 — RAK, T-Echo, XIAO nRF52) | Complete self-contained image. | **First install *and* updates** — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.) |\n\n> ⚠️ **ESP32:** the app-only `*.bin` will **not boot** if flashed at `0x0` — use `*-merged.bin` for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, **never** a routine update.\n\n\n## What's Changed\n* fix(observer): wifi.pwd confirmation wording (0.18.1) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/139\n\n\n**Full Changelog**: https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.0...offband-v0.18.1",
          "notesHtml": "<h3>Fixed</h3>\n<ul>\n<li><strong>WiFi password confirmation wording</strong> — <code>set wifi.pwd</code> now replies\n<code>wifi.pwd set (N chars entered)</code> instead of <code>wifi.pwd set (length=N)</code>, which was\nbeing misread as a 17-character maximum. The reply reports the length of what was\n<em>entered</em> (never the secret PSK); it is not a cap. WiFi passwords accept the full\nWPA2 range (8–63 chars).</li>\n</ul>\n<hr />\n<h3>Which file do I download?</h3>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>What it is</th>\n<th>When to use it</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>*-merged.bin</code> (ESP32 — Heltec V3/V4, XIAO)</td>\n<td><strong>Full image</strong> — bootloader + partition table + app in one, flashed at <code>0x0</code> after a chip erase. Self-contained, works on a blank chip.</td>\n<td><strong>First install / clean setup.</strong> In a web flasher this is the <strong>\"Full Firmware\"</strong> option.</td>\n</tr>\n<tr>\n<td><code>*.bin</code> (ESP32)</td>\n<td><strong>App only</strong> — flashed at the app offset (<code>0x10000</code>); the bootloader must already be on the chip.</td>\n<td><strong>Updating</strong> an existing node — OTA / <strong>\"Update Only.\"</strong> Keeps the device identity + WiFi/MQTT config.</td>\n</tr>\n<tr>\n<td><code>*.uf2</code> (nRF52 — RAK, T-Echo, XIAO nRF52)</td>\n<td>Complete self-contained image.</td>\n<td><strong>First install <em>and</em> updates</strong> — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.)</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p>⚠️ <strong>ESP32:</strong> the app-only <code>*.bin</code> will <strong>not boot</strong> if flashed at <code>0x0</code> — use <code>*-merged.bin</code> for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, <strong>never</strong> a routine update.</p>\n</blockquote>\n<h2>What's Changed</h2>\n<ul>\n<li>fix(observer): wifi.pwd confirmation wording (0.18.1) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/139\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/139</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.0...offband-v0.18.1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.18.0...offband-v0.18.1</a></p>\n"
        },
        {
          "version": "offband-v0.18.0",
          "name": "Offband offband-v0.18.0",
          "datetime": "2026-06-15T02:56:19Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/offband-v0.18.0",
          "prerelease": false,
          "notes": "### Added\n- **Heltec V4 TFT observer build** (`heltec_v4_tft_companion_observer_wifi`) — the\n  observer role on the TFT (ST7789) display variant, switched to the NimBLE stack\n  the observer requires. Added to the CI build matrix and the release env set so it\n  **always builds and ships**.\n\n### Changed\n- **Firmware download clarity** — a \"Which file?\" table in the README and a static\n  footer appended to every GitHub Release, explaining `-merged.bin` (first install)\n  vs `.bin` (update) vs `.uf2` (nRF52).\n\n### Fixed\n- **`pio-flash` device matching** — `find_in_registry` prefers an exact\n  DeviceID-instance match over a class-only label, so a registered chip is no longer\n  shadowed by a same-class device with null discriminators (fixes nRF52/ESP32\n  mislabels where two boards share a VID:PID).\n\n### Internal\n- Wire a gitignored `HARDWARE.local.md` (symlink to the LoRa hardware inventory) plus\n  a CLAUDE.md \"read before any hardware work\" pointer.\n\n\n---\n\n### Which file do I download?\n\n| File | What it is | When to use it |\n|---|---|---|\n| `*-merged.bin` (ESP32 — Heltec V3/V4, XIAO) | **Full image** — bootloader + partition table + app in one, flashed at `0x0` after a chip erase. Self-contained, works on a blank chip. | **First install / clean setup.** In a web flasher this is the **\"Full Firmware\"** option. |\n| `*.bin` (ESP32) | **App only** — flashed at the app offset (`0x10000`); the bootloader must already be on the chip. | **Updating** an existing node — OTA / **\"Update Only.\"** Keeps the device identity + WiFi/MQTT config. |\n| `*.uf2` (nRF52 — RAK, T-Echo, XIAO nRF52) | Complete self-contained image. | **First install *and* updates** — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.) |\n\n> ⚠️ **ESP32:** the app-only `*.bin` will **not boot** if flashed at `0x0` — use `*-merged.bin` for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, **never** a routine update.\n\n\n## What's Changed\n* docs(#127): MeshCore 1.16.0 base-update merge plan by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/133\n* feat: Heltec V4 TFT observer build (always-build) + flash docs & tooling by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/138\n\n\n**Full Changelog**: https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.17.0...offband-v0.18.0",
          "notesHtml": "<h3>Added</h3>\n<ul>\n<li><strong>Heltec V4 TFT observer build</strong> (<code>heltec_v4_tft_companion_observer_wifi</code>) — the\nobserver role on the TFT (ST7789) display variant, switched to the NimBLE stack\nthe observer requires. Added to the CI build matrix and the release env set so it\n<strong>always builds and ships</strong>.</li>\n</ul>\n<h3>Changed</h3>\n<ul>\n<li><strong>Firmware download clarity</strong> — a \"Which file?\" table in the README and a static\nfooter appended to every GitHub Release, explaining <code>-merged.bin</code> (first install)\nvs <code>.bin</code> (update) vs <code>.uf2</code> (nRF52).</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li><strong><code>pio-flash</code> device matching</strong> — <code>find_in_registry</code> prefers an exact\nDeviceID-instance match over a class-only label, so a registered chip is no longer\nshadowed by a same-class device with null discriminators (fixes nRF52/ESP32\nmislabels where two boards share a VID:PID).</li>\n</ul>\n<h3>Internal</h3>\n<ul>\n<li>Wire a gitignored <code>HARDWARE.local.md</code> (symlink to the LoRa hardware inventory) plus\na CLAUDE.md \"read before any hardware work\" pointer.</li>\n</ul>\n<hr />\n<h3>Which file do I download?</h3>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>What it is</th>\n<th>When to use it</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>*-merged.bin</code> (ESP32 — Heltec V3/V4, XIAO)</td>\n<td><strong>Full image</strong> — bootloader + partition table + app in one, flashed at <code>0x0</code> after a chip erase. Self-contained, works on a blank chip.</td>\n<td><strong>First install / clean setup.</strong> In a web flasher this is the <strong>\"Full Firmware\"</strong> option.</td>\n</tr>\n<tr>\n<td><code>*.bin</code> (ESP32)</td>\n<td><strong>App only</strong> — flashed at the app offset (<code>0x10000</code>); the bootloader must already be on the chip.</td>\n<td><strong>Updating</strong> an existing node — OTA / <strong>\"Update Only.\"</strong> Keeps the device identity + WiFi/MQTT config.</td>\n</tr>\n<tr>\n<td><code>*.uf2</code> (nRF52 — RAK, T-Echo, XIAO nRF52)</td>\n<td>Complete self-contained image.</td>\n<td><strong>First install <em>and</em> updates</strong> — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.)</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p>⚠️ <strong>ESP32:</strong> the app-only <code>*.bin</code> will <strong>not boot</strong> if flashed at <code>0x0</code> — use <code>*-merged.bin</code> for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, <strong>never</strong> a routine update.</p>\n</blockquote>\n<h2>What's Changed</h2>\n<ul>\n<li>docs(#127): MeshCore 1.16.0 base-update merge plan by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/133\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/133</a></li>\n<li>feat: Heltec V4 TFT observer build (always-build) + flash docs &amp; tooling by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/138\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/138</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.17.0...offband-v0.18.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.17.0...offband-v0.18.0</a></p>\n"
        },
        {
          "version": "offband-v0.17.0",
          "name": "Offband offband-v0.17.0",
          "datetime": "2026-06-14T07:31:59Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/offband-v0.17.0",
          "prerelease": false,
          "notes": "First release under **OffbandMesh/meshcore-firmware**. Bundles the 0.16.0 observer\nwork below (which landed on `firmware-base` but was never separately tagged) with\nthe Crosswire→Offband rebrand and the OffbandMesh org cutover. *(Version pending\nowner confirmation; the tag is hardware-gated per VERSIONING.md.)*\n\n### Changed\n- **Rebranded the fork from Crosswire to Offband** (GitHub org `OffbandMesh`):\n  the C++ namespace, build macros, embedded identity blob, version prefix\n  (`offband-v*`), MQTT / flash-audit identity fields (`offband_*`), brand\n  strings (serial banner, `version` command, OLED splash, Home Assistant\n  manufacturer), and the WiFi setup-AP SSID (`Offband-Observer-`). Historical\n  `crosswire-v*` release tags are preserved; the `_sys` PSK domain separator\n  and the MeshCore interop topic namespace are intentionally unchanged. (#100)\n- **Repo / board / working-dir cutover to OffbandMesh** — repo\n  `OffbandMesh/meshcore-firmware`, OffbandMesh org Projects board, and the\n  preflight / CLAUDE.md / label-sync workflow re-pointed; removed the stale\n  upstream `CNAME`. (#107, #111)\n\n### Docs\n- Finished the rebrand reference cleanup across docs + code comments. (#113, #114)\n- Release-readiness pass: README getting-started + multi-role positioning, the\n  docs index surfaces the observer guides, and observer `_sys` CLI reference\n  corrections. (#117)\n\n\n\n## What's Changed\n* feat: observer MQTT connectivity (crosswire-v0.15.0) — #53 #48 #63 #68 by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/72\n* docs: fix README license link (LICENSE.txt -> license.txt) — #73 by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/74\n* docs: 2026-06-10 observer-MQTT session handoff — #75 by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/76\n* chore: relocate to C:/Dev/Crosswire — canonical hook sync + AM repin by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/78\n* docs(#79): correct stale active-agents line in CLAUDE.md by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/80\n* Observer: time arbiter (#69) + position in /status (#31) + _sys CLI grammar (#45) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/91\n* Observer follow-ups: arbiter decouple + held-state (#87) + /status radio from runtime prefs (#88) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/92\n* docs: README/CHANGELOG 0.16.0 (#93) + observer instructions (#94) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/99\n* #95: observer MQTT broker pre-config + per-device auth by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/105\n* #98: mqtt view + mqtt clear (broker config inspection) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/106\n* Offband rebrand: Crosswire -> Offband (code + docs) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/108\n* chore(#107): finish OffbandMesh local cutover (preflight, CLAUDE.md, board #1) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/109\n* chore(#111): remove stale upstream CNAME (docs.meshcore.nz) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/112\n* docs(#113): finish rebrand — Strycher/Crosswire refs + CLAUDE.md PROJECT_PAT note by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/115\n* chore(#114): update stale Strycher/Crosswire# refs in code comments -> #N by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/116\n* epic(#117): Offband release-readiness — docs, observer reference, CHANGELOG prep by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/125\n\n\n**Full Changelog**: https://github.com/OffbandMesh/meshcore-firmware/compare/crosswire-v0.14.0...offband-v0.17.0",
          "notesHtml": "<p>First release under <strong>OffbandMesh/meshcore-firmware</strong>. Bundles the 0.16.0 observer\nwork below (which landed on <code>firmware-base</code> but was never separately tagged) with\nthe Crosswire→Offband rebrand and the OffbandMesh org cutover. <em>(Version pending\nowner confirmation; the tag is hardware-gated per VERSIONING.md.)</em></p>\n<h3>Changed</h3>\n<ul>\n<li><strong>Rebranded the fork from Crosswire to Offband</strong> (GitHub org <code>OffbandMesh</code>):\nthe C++ namespace, build macros, embedded identity blob, version prefix\n(<code>offband-v*</code>), MQTT / flash-audit identity fields (<code>offband_*</code>), brand\nstrings (serial banner, <code>version</code> command, OLED splash, Home Assistant\nmanufacturer), and the WiFi setup-AP SSID (<code>Offband-Observer-</code>). Historical\n<code>crosswire-v*</code> release tags are preserved; the <code>_sys</code> PSK domain separator\nand the MeshCore interop topic namespace are intentionally unchanged. (#100)</li>\n<li><strong>Repo / board / working-dir cutover to OffbandMesh</strong> — repo\n<code>OffbandMesh/meshcore-firmware</code>, OffbandMesh org Projects board, and the\npreflight / CLAUDE.md / label-sync workflow re-pointed; removed the stale\nupstream <code>CNAME</code>. (#107, #111)</li>\n</ul>\n<h3>Docs</h3>\n<ul>\n<li>Finished the rebrand reference cleanup across docs + code comments. (#113, #114)</li>\n<li>Release-readiness pass: README getting-started + multi-role positioning, the\ndocs index surfaces the observer guides, and observer <code>_sys</code> CLI reference\ncorrections. (#117)</li>\n</ul>\n<h2>What's Changed</h2>\n<ul>\n<li>feat: observer MQTT connectivity (crosswire-v0.15.0) — #53 #48 #63 #68 by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/72\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/72</a></li>\n<li>docs: fix README license link (LICENSE.txt -&gt; license.txt) — #73 by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/74\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/74</a></li>\n<li>docs: 2026-06-10 observer-MQTT session handoff — #75 by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/76\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/76</a></li>\n<li>chore: relocate to C:/Dev/Crosswire — canonical hook sync + AM repin by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/78\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/78</a></li>\n<li>docs(#79): correct stale active-agents line in CLAUDE.md by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/80\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/80</a></li>\n<li>Observer: time arbiter (#69) + position in /status (#31) + _sys CLI grammar (#45) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/91\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/91</a></li>\n<li>Observer follow-ups: arbiter decouple + held-state (#87) + /status radio from runtime prefs (#88) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/92\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/92</a></li>\n<li>docs: README/CHANGELOG 0.16.0 (#93) + observer instructions (#94) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/99\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/99</a></li>\n<li>#95: observer MQTT broker pre-config + per-device auth by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/105\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/105</a></li>\n<li>#98: mqtt view + mqtt clear (broker config inspection) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/106\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/106</a></li>\n<li>Offband rebrand: Crosswire -&gt; Offband (code + docs) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/108\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/108</a></li>\n<li>chore(#107): finish OffbandMesh local cutover (preflight, CLAUDE.md, board #1) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/109\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/109</a></li>\n<li>chore(#111): remove stale upstream CNAME (docs.meshcore.nz) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/112\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/112</a></li>\n<li>docs(#113): finish rebrand — Strycher/Crosswire refs + CLAUDE.md PROJECT_PAT note by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/115\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/115</a></li>\n<li>chore(#114): update stale Strycher/Crosswire# refs in code comments -&gt; #N by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/116\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/116</a></li>\n<li>epic(#117): Offband release-readiness — docs, observer reference, CHANGELOG prep by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/125\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/125</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/OffbandMesh/meshcore-firmware/compare/crosswire-v0.14.0...offband-v0.17.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/compare/crosswire-v0.14.0...offband-v0.17.0</a></p>\n"
        },
        {
          "version": "offband-v0.18.0-rc1",
          "name": "Offband offband-v0.18.0-rc1",
          "datetime": "2026-06-14T22:46:08Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/offband-v0.18.0-rc1",
          "prerelease": true,
          "notes": "(No CHANGELOG entry for v0.18.0-rc1.)\n\n---\n\n### Which file do I download?\n\n| File | What it is | When to use it |\n|---|---|---|\n| `*-merged.bin` (ESP32 — Heltec V3/V4, XIAO) | **Full image** — bootloader + partition table + app in one, flashed at `0x0` after a chip erase. Self-contained, works on a blank chip. | **First install / clean setup.** In a web flasher this is the **\"Full Firmware\"** option. |\n| `*.bin` (ESP32) | **App only** — flashed at the app offset (`0x10000`); the bootloader must already be on the chip. | **Updating** an existing node — OTA / **\"Update Only.\"** Keeps the device identity + WiFi/MQTT config. |\n| `*.uf2` (nRF52 — RAK, T-Echo, XIAO nRF52) | Complete self-contained image. | **First install *and* updates** — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.) |\n\n> ⚠️ **ESP32:** the app-only `*.bin` will **not boot** if flashed at `0x0` — use `*-merged.bin` for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, **never** a routine update.\n\n\n## What's Changed\n* docs(#127): MeshCore 1.16.0 base-update merge plan by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/133\n* feat: Heltec V4 TFT observer build (always-build) + flash docs & tooling by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/138\n\n\n**Full Changelog**: https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.17.0...offband-v0.18.0-rc1",
          "notesHtml": "<p>(No CHANGELOG entry for v0.18.0-rc1.)</p>\n<hr />\n<h3>Which file do I download?</h3>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>What it is</th>\n<th>When to use it</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>*-merged.bin</code> (ESP32 — Heltec V3/V4, XIAO)</td>\n<td><strong>Full image</strong> — bootloader + partition table + app in one, flashed at <code>0x0</code> after a chip erase. Self-contained, works on a blank chip.</td>\n<td><strong>First install / clean setup.</strong> In a web flasher this is the <strong>\"Full Firmware\"</strong> option.</td>\n</tr>\n<tr>\n<td><code>*.bin</code> (ESP32)</td>\n<td><strong>App only</strong> — flashed at the app offset (<code>0x10000</code>); the bootloader must already be on the chip.</td>\n<td><strong>Updating</strong> an existing node — OTA / <strong>\"Update Only.\"</strong> Keeps the device identity + WiFi/MQTT config.</td>\n</tr>\n<tr>\n<td><code>*.uf2</code> (nRF52 — RAK, T-Echo, XIAO nRF52)</td>\n<td>Complete self-contained image.</td>\n<td><strong>First install <em>and</em> updates</strong> — double-tap reset, then drag-drop onto the USB drive. (nRF52 has no merged/app split.)</td>\n</tr>\n</tbody></table>\n<blockquote>\n<p>⚠️ <strong>ESP32:</strong> the app-only <code>*.bin</code> will <strong>not boot</strong> if flashed at <code>0x0</code> — use <code>*-merged.bin</code> for a fresh install. A full erase / \"Full Firmware\" wipes the device's identity + saved config, so use it only for a first install or recovery, <strong>never</strong> a routine update.</p>\n</blockquote>\n<h2>What's Changed</h2>\n<ul>\n<li>docs(#127): MeshCore 1.16.0 base-update merge plan by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/133\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/133</a></li>\n<li>feat: Heltec V4 TFT observer build (always-build) + flash docs &amp; tooling by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/138\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/138</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.17.0...offband-v0.18.0-rc1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/compare/offband-v0.17.0...offband-v0.18.0-rc1</a></p>\n"
        },
        {
          "version": "offband-v0.17.0-rc1",
          "name": "Offband offband-v0.17.0-rc1",
          "datetime": "2026-06-14T07:15:36Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/offband-v0.17.0-rc1",
          "prerelease": true,
          "notes": "(No CHANGELOG entry for v0.17.0-rc1.)\n\n\n## What's Changed\n* feat: observer MQTT connectivity (crosswire-v0.15.0) — #53 #48 #63 #68 by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/72\n* docs: fix README license link (LICENSE.txt -> license.txt) — #73 by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/74\n* docs: 2026-06-10 observer-MQTT session handoff — #75 by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/76\n* chore: relocate to C:/Dev/Crosswire — canonical hook sync + AM repin by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/78\n* docs(#79): correct stale active-agents line in CLAUDE.md by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/80\n* Observer: time arbiter (#69) + position in /status (#31) + _sys CLI grammar (#45) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/91\n* Observer follow-ups: arbiter decouple + held-state (#87) + /status radio from runtime prefs (#88) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/92\n* docs: README/CHANGELOG 0.16.0 (#93) + observer instructions (#94) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/99\n* #95: observer MQTT broker pre-config + per-device auth by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/105\n* #98: mqtt view + mqtt clear (broker config inspection) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/106\n* Offband rebrand: Crosswire -> Offband (code + docs) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/108\n* chore(#107): finish OffbandMesh local cutover (preflight, CLAUDE.md, board #1) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/109\n* chore(#111): remove stale upstream CNAME (docs.meshcore.nz) by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/112\n* docs(#113): finish rebrand — Strycher/Crosswire refs + CLAUDE.md PROJECT_PAT note by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/115\n* chore(#114): update stale Strycher/Crosswire# refs in code comments -> #N by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/116\n* epic(#117): Offband release-readiness — docs, observer reference, CHANGELOG prep by @Strycher in https://github.com/OffbandMesh/meshcore-firmware/pull/125\n\n\n**Full Changelog**: https://github.com/OffbandMesh/meshcore-firmware/compare/crosswire-v0.14.0...offband-v0.17.0-rc1",
          "notesHtml": "<p>(No CHANGELOG entry for v0.17.0-rc1.)</p>\n<h2>What's Changed</h2>\n<ul>\n<li>feat: observer MQTT connectivity (crosswire-v0.15.0) — #53 #48 #63 #68 by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/72\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/72</a></li>\n<li>docs: fix README license link (LICENSE.txt -&gt; license.txt) — #73 by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/74\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/74</a></li>\n<li>docs: 2026-06-10 observer-MQTT session handoff — #75 by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/76\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/76</a></li>\n<li>chore: relocate to C:/Dev/Crosswire — canonical hook sync + AM repin by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/78\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/78</a></li>\n<li>docs(#79): correct stale active-agents line in CLAUDE.md by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/80\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/80</a></li>\n<li>Observer: time arbiter (#69) + position in /status (#31) + _sys CLI grammar (#45) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/91\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/91</a></li>\n<li>Observer follow-ups: arbiter decouple + held-state (#87) + /status radio from runtime prefs (#88) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/92\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/92</a></li>\n<li>docs: README/CHANGELOG 0.16.0 (#93) + observer instructions (#94) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/99\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/99</a></li>\n<li>#95: observer MQTT broker pre-config + per-device auth by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/105\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/105</a></li>\n<li>#98: mqtt view + mqtt clear (broker config inspection) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/106\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/106</a></li>\n<li>Offband rebrand: Crosswire -&gt; Offband (code + docs) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/108\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/108</a></li>\n<li>chore(#107): finish OffbandMesh local cutover (preflight, CLAUDE.md, board #1) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/109\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/109</a></li>\n<li>chore(#111): remove stale upstream CNAME (docs.meshcore.nz) by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/112\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/112</a></li>\n<li>docs(#113): finish rebrand — Strycher/Crosswire refs + CLAUDE.md PROJECT_PAT note by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/115\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/115</a></li>\n<li>chore(#114): update stale Strycher/Crosswire# refs in code comments -&gt; #N by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/116\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/116</a></li>\n<li>epic(#117): Offband release-readiness — docs, observer reference, CHANGELOG prep by @Strycher in <a href=\"https://github.com/OffbandMesh/meshcore-firmware/pull/125\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/pull/125</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/OffbandMesh/meshcore-firmware/compare/crosswire-v0.14.0...offband-v0.17.0-rc1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OffbandMesh/meshcore-firmware/compare/crosswire-v0.14.0...offband-v0.17.0-rc1</a></p>\n"
        },
        {
          "version": "crosswire-v0.15.0",
          "name": "Crosswire crosswire-v0.15.0",
          "datetime": "2026-06-10T23:43:44Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/crosswire-v0.15.0",
          "prerelease": false,
          "notes": "Observer MQTT connectivity -- hardware-validated against three brokers\n(CoreScope / W8OOF tcp-anon, eastme.sh wss/jwt, LetsMesh-US wss/jwt).\n\n### Added\n- Owner broker registry: seed the default 6-slot broker set with an `iata=HAO`\n  default; per-broker GTS Root R4 + ISRG Root X2 CA certificates added and\n  mapped, registry cert-names corrected. (#48)\n- Per-broker JWT identity claims `jwt_owner` / `jwt_email`\n  (`set mqtt.broker.<N>.jwt_owner|jwt_email`), surfaced in `mqtt status`. (#63)\n- Multi-frame `mqtt status` over the BLE `_sys` channel: the per-slot broker\n  table spans multiple frames instead of truncating. (#48)\n\n### Fixed\n- BLE `_sys` command channel no longer hangs when `set mqtt.broker.*` runs. The\n  blocking `esp_mqtt` lifecycle ops (connect / destroy) moved off `loopTask` to a\n  dedicated `mqtt_worker` task with a per-broker lock and a per-slot reconcile\n  flag. (#53)\n- wss/JWT broker authentication: send the MQTT CONNECT username\n  `v1_<UPPERCASE pubkey>` (was a null username) so eastme.sh / LetsMesh accept\n  the connection -- the broker verifies the token's `publicKey` claim against it\n  and rejects a null username (CONNACK rc=5) even with an otherwise-valid token.\n  (#68)\n\n\n\n## What's Changed\n* fix(#27): pio-flash firmware_dir -> repo root + --firmware-dir override by @Strycher in https://github.com/Strycher/Crosswire/pull/28\n* pio-flash artifact-flash: flash CI release artifacts through the identity gate (#29, #34) by @Strycher in https://github.com/Strycher/Crosswire/pull/35\n* fix(#33): OLED splash carries pre-release identifier (v0.14.0-rc1, not v0.14.0+0) by @Strycher in https://github.com/Strycher/Crosswire/pull/37\n* chore(#38): gitignore __pycache__/ by @Strycher in https://github.com/Strycher/Crosswire/pull/40\n* feat(#42): strip observer companion to minima + delete dead ring buffer by @Strycher in https://github.com/Strycher/Crosswire/pull/50\n* docs: pin Crosswire project identity (Citadel + Agent Mail keys) (#55) by @Strycher in https://github.com/Strycher/Crosswire/pull/56\n* docs(#32): position-to-map pipeline architecture draft by @Strycher in https://github.com/Strycher/Crosswire/pull/57\n* docs: MeshCore 1.16.0 base-update impact assessment (spike #54) by @Strycher in https://github.com/Strycher/Crosswire/pull/58\n* chore(#59): port /work + session-state.py compaction-recovery hook into Crosswire by @Strycher in https://github.com/Strycher/Crosswire/pull/60\n* docs(#61): correct CLAUDE.md build/flash + migration-status after meshcore-firmware retire by @Strycher in https://github.com/Strycher/Crosswire/pull/62\n* feat: observer MQTT connectivity (crosswire-v0.15.0) — #53 #48 #63 #68 by @Strycher in https://github.com/Strycher/Crosswire/pull/72\n\n\n**Full Changelog**: https://github.com/Strycher/Crosswire/compare/crosswire-v0.14.0-rc1...crosswire-v0.15.0",
          "notesHtml": "<p>Observer MQTT connectivity -- hardware-validated against three brokers\n(CoreScope / W8OOF tcp-anon, eastme.sh wss/jwt, LetsMesh-US wss/jwt).</p>\n<h3>Added</h3>\n<ul>\n<li>Owner broker registry: seed the default 6-slot broker set with an <code>iata=HAO</code>\ndefault; per-broker GTS Root R4 + ISRG Root X2 CA certificates added and\nmapped, registry cert-names corrected. (#48)</li>\n<li>Per-broker JWT identity claims <code>jwt_owner</code> / <code>jwt_email</code>\n(<code>set mqtt.broker.&lt;N&gt;.jwt_owner|jwt_email</code>), surfaced in <code>mqtt status</code>. (#63)</li>\n<li>Multi-frame <code>mqtt status</code> over the BLE <code>_sys</code> channel: the per-slot broker\ntable spans multiple frames instead of truncating. (#48)</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>BLE <code>_sys</code> command channel no longer hangs when <code>set mqtt.broker.*</code> runs. The\nblocking <code>esp_mqtt</code> lifecycle ops (connect / destroy) moved off <code>loopTask</code> to a\ndedicated <code>mqtt_worker</code> task with a per-broker lock and a per-slot reconcile\nflag. (#53)</li>\n<li>wss/JWT broker authentication: send the MQTT CONNECT username\n<code>v1_&lt;UPPERCASE pubkey&gt;</code> (was a null username) so eastme.sh / LetsMesh accept\nthe connection -- the broker verifies the token's <code>publicKey</code> claim against it\nand rejects a null username (CONNACK rc=5) even with an otherwise-valid token.\n(#68)</li>\n</ul>\n<h2>What's Changed</h2>\n<ul>\n<li>fix(#27): pio-flash firmware_dir -&gt; repo root + --firmware-dir override by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/28\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/28</a></li>\n<li>pio-flash artifact-flash: flash CI release artifacts through the identity gate (#29, #34) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/35\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/35</a></li>\n<li>fix(#33): OLED splash carries pre-release identifier (v0.14.0-rc1, not v0.14.0+0) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/37\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/37</a></li>\n<li>chore(#38): gitignore <strong>pycache</strong>/ by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/40\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/40</a></li>\n<li>feat(#42): strip observer companion to minima + delete dead ring buffer by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/50\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/50</a></li>\n<li>docs: pin Crosswire project identity (Citadel + Agent Mail keys) (#55) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/56\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/56</a></li>\n<li>docs(#32): position-to-map pipeline architecture draft by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/57\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/57</a></li>\n<li>docs: MeshCore 1.16.0 base-update impact assessment (spike #54) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/58\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/58</a></li>\n<li>chore(#59): port /work + session-state.py compaction-recovery hook into Crosswire by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/60\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/60</a></li>\n<li>docs(#61): correct CLAUDE.md build/flash + migration-status after meshcore-firmware retire by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/62\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/62</a></li>\n<li>feat: observer MQTT connectivity (crosswire-v0.15.0) — #53 #48 #63 #68 by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/72\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/72</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/Strycher/Crosswire/compare/crosswire-v0.14.0-rc1...crosswire-v0.15.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/compare/crosswire-v0.14.0-rc1...crosswire-v0.15.0</a></p>\n"
        },
        {
          "version": "crosswire-v0.14.0",
          "name": "Crosswire crosswire-v0.14.0",
          "datetime": "2026-06-10T23:45:36Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/crosswire-v0.14.0",
          "prerelease": false,
          "notes": "### Added\n- CI release pipeline (epic #14): dev-channel firmware artifacts on every\n  `firmware-base` push / PR (`ci.yml`), and a `release.yml` workflow that builds\n  the curated community board set from `crosswire-v*` tags and publishes a\n  GitHub Release (pre-release for `-rc*`, \"Latest\" for stable). Curated env set\n  in `.github/release-envs.txt` (72 envs; `heltec_v4_repeater_telemetry` gated on\n  #20). Design of record: `docs/architecture/2026-06-06-ci-release-pipeline.md`.\n  (#15, #16, #17)\n\n### Changed\n- Reconciled inherited CI workflows: removed 7 dead/superseded\n  (`pr-build-check`, `auto-promote`, `github-pages`, the three upstream-tag\n  `build-*-firmwares`, `branch-cleanup`); kept `build-safeboot-firmwares` +\n  `sync-labels-to-board`. (#18)\n\n\n\n## What's Changed\n* fix(#27): pio-flash firmware_dir -> repo root + --firmware-dir override by @Strycher in https://github.com/Strycher/Crosswire/pull/28\n* pio-flash artifact-flash: flash CI release artifacts through the identity gate (#29, #34) by @Strycher in https://github.com/Strycher/Crosswire/pull/35\n* fix(#33): OLED splash carries pre-release identifier (v0.14.0-rc1, not v0.14.0+0) by @Strycher in https://github.com/Strycher/Crosswire/pull/37\n* chore(#38): gitignore __pycache__/ by @Strycher in https://github.com/Strycher/Crosswire/pull/40\n* feat(#42): strip observer companion to minima + delete dead ring buffer by @Strycher in https://github.com/Strycher/Crosswire/pull/50\n* docs: pin Crosswire project identity (Citadel + Agent Mail keys) (#55) by @Strycher in https://github.com/Strycher/Crosswire/pull/56\n* docs(#32): position-to-map pipeline architecture draft by @Strycher in https://github.com/Strycher/Crosswire/pull/57\n* docs: MeshCore 1.16.0 base-update impact assessment (spike #54) by @Strycher in https://github.com/Strycher/Crosswire/pull/58\n* chore(#59): port /work + session-state.py compaction-recovery hook into Crosswire by @Strycher in https://github.com/Strycher/Crosswire/pull/60\n* docs(#61): correct CLAUDE.md build/flash + migration-status after meshcore-firmware retire by @Strycher in https://github.com/Strycher/Crosswire/pull/62\n\n\n**Full Changelog**: https://github.com/Strycher/Crosswire/compare/crosswire-v0.14.0-rc1...crosswire-v0.14.0",
          "notesHtml": "<h3>Added</h3>\n<ul>\n<li>CI release pipeline (epic #14): dev-channel firmware artifacts on every\n<code>firmware-base</code> push / PR (<code>ci.yml</code>), and a <code>release.yml</code> workflow that builds\nthe curated community board set from <code>crosswire-v*</code> tags and publishes a\nGitHub Release (pre-release for <code>-rc*</code>, \"Latest\" for stable). Curated env set\nin <code>.github/release-envs.txt</code> (72 envs; <code>heltec_v4_repeater_telemetry</code> gated on\n#20). Design of record: <code>docs/architecture/2026-06-06-ci-release-pipeline.md</code>.\n(#15, #16, #17)</li>\n</ul>\n<h3>Changed</h3>\n<ul>\n<li>Reconciled inherited CI workflows: removed 7 dead/superseded\n(<code>pr-build-check</code>, <code>auto-promote</code>, <code>github-pages</code>, the three upstream-tag\n<code>build-*-firmwares</code>, <code>branch-cleanup</code>); kept <code>build-safeboot-firmwares</code> +\n<code>sync-labels-to-board</code>. (#18)</li>\n</ul>\n<h2>What's Changed</h2>\n<ul>\n<li>fix(#27): pio-flash firmware_dir -&gt; repo root + --firmware-dir override by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/28\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/28</a></li>\n<li>pio-flash artifact-flash: flash CI release artifacts through the identity gate (#29, #34) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/35\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/35</a></li>\n<li>fix(#33): OLED splash carries pre-release identifier (v0.14.0-rc1, not v0.14.0+0) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/37\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/37</a></li>\n<li>chore(#38): gitignore <strong>pycache</strong>/ by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/40\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/40</a></li>\n<li>feat(#42): strip observer companion to minima + delete dead ring buffer by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/50\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/50</a></li>\n<li>docs: pin Crosswire project identity (Citadel + Agent Mail keys) (#55) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/56\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/56</a></li>\n<li>docs(#32): position-to-map pipeline architecture draft by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/57\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/57</a></li>\n<li>docs: MeshCore 1.16.0 base-update impact assessment (spike #54) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/58\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/58</a></li>\n<li>chore(#59): port /work + session-state.py compaction-recovery hook into Crosswire by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/60\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/60</a></li>\n<li>docs(#61): correct CLAUDE.md build/flash + migration-status after meshcore-firmware retire by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/62\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/62</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/Strycher/Crosswire/compare/crosswire-v0.14.0-rc1...crosswire-v0.14.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/compare/crosswire-v0.14.0-rc1...crosswire-v0.14.0</a></p>\n"
        },
        {
          "version": "crosswire-v0.14.0-rc1",
          "name": "Crosswire crosswire-v0.14.0-rc1",
          "datetime": "2026-06-07T21:22:48Z",
          "url": "https://github.com/OffbandMesh/meshcore-firmware/releases/tag/crosswire-v0.14.0-rc1",
          "prerelease": true,
          "notes": "(No CHANGELOG entry for v0.14.0-rc1.)\n\n\n## What's Changed\n* docs: adopt versioning + CHANGELOG + release-channel discipline (#11) by @Strycher in https://github.com/Strycher/Crosswire/pull/12\n* chore: roll CHANGELOG to v0.13.2 + fix em-dashes to ASCII (#11) by @Strycher in https://github.com/Strycher/Crosswire/pull/13\n* epic(#14): CI release pipeline -- dev artifacts + crosswire-v* releases by @Strycher in https://github.com/Strycher/Crosswire/pull/24\n* docs(#25): roll CHANGELOG to [0.14.0] (CI release pipeline) by @Strycher in https://github.com/Strycher/Crosswire/pull/26\n\n## New Contributors\n* @Strycher made their first contribution in https://github.com/Strycher/Crosswire/pull/12\n\n**Full Changelog**: https://github.com/Strycher/Crosswire/commits/crosswire-v0.14.0-rc1",
          "notesHtml": "<p>(No CHANGELOG entry for v0.14.0-rc1.)</p>\n<h2>What's Changed</h2>\n<ul>\n<li>docs: adopt versioning + CHANGELOG + release-channel discipline (#11) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/12\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/12</a></li>\n<li>chore: roll CHANGELOG to v0.13.2 + fix em-dashes to ASCII (#11) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/13\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/13</a></li>\n<li>epic(#14): CI release pipeline -- dev artifacts + crosswire-v* releases by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/24\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/24</a></li>\n<li>docs(#25): roll CHANGELOG to [0.14.0] (CI release pipeline) by @Strycher in <a href=\"https://github.com/Strycher/Crosswire/pull/26\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/26</a></li>\n</ul>\n<h2>New Contributors</h2>\n<ul>\n<li>@Strycher made their first contribution in <a href=\"https://github.com/Strycher/Crosswire/pull/12\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/pull/12</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/Strycher/Crosswire/commits/crosswire-v0.14.0-rc1\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/Strycher/Crosswire/commits/crosswire-v0.14.0-rc1</a></p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:39.988Z"
    },
    {
      "id": "saitama",
      "name": "Saitama",
      "type": "fork",
      "maintainer": "868meshbot",
      "description": "An open-source standalone firmware for LoRa mesh devices built on MeshCore, designed for the LilyGo T-Deck and T-Deck Plus. Provides smartphone-grade messaging, GPS maps, encrypted comms, and more — all running directly on the device with no phone, internet, or license required.\n",
      "repository": "https://github.com/868meshbot/Saitama",
      "license": "GPL-3.0",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "standalone-ui"
      ],
      "features": [
        "Standalone messaging (no phone needed)",
        "GPS maps",
        "Encrypted communications",
        "Channel and direct messaging",
        "No accounts or licensing"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": false,
          "wifiAp": false
        },
        "operations": {
          "ota": false,
          "webFlasher": false
        },
        "networking": {
          "repeater": false,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-t-deck",
          "status": "supported",
          "notes": "T-Deck Plus — primary target, compiled and hardware-tested."
        }
      ],
      "latest_version": "1.0.0",
      "released": "2026-06-12",
      "releases": [
        {
          "version": "v1.0.0",
          "name": "v1.0.0",
          "datetime": "2026-06-12T08:36:39Z",
          "url": "https://github.com/868meshbot/Saitama/releases/tag/v1.0.0",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.17...v1.0.0",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.17...v1.0.0\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.17...v1.0.0</a></p>\n"
        },
        {
          "version": "v0.1.0-beta.17",
          "name": "v0.1.0-beta.17",
          "datetime": "2026-06-10T08:49:03Z",
          "url": "https://github.com/868meshbot/Saitama/releases/tag/v0.1.0-beta.17",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.16...v0.1.0-beta.17",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.16...v0.1.0-beta.17\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.16...v0.1.0-beta.17</a></p>\n"
        },
        {
          "version": "v0.1.0-beta.16",
          "name": "v0.1.0-beta.16",
          "datetime": "2026-06-10T07:50:48Z",
          "url": "https://github.com/868meshbot/Saitama/releases/tag/v0.1.0-beta.16",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.15...v0.1.0-beta.16",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.15...v0.1.0-beta.16\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.15...v0.1.0-beta.16</a></p>\n"
        },
        {
          "version": "v0.1.0-beta.15",
          "name": "v0.1.0-beta.15",
          "datetime": "2026-06-10T07:06:29Z",
          "url": "https://github.com/868meshbot/Saitama/releases/tag/v0.1.0-beta.15",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.14...v0.1.0-beta.15",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.14...v0.1.0-beta.15\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.14...v0.1.0-beta.15</a></p>\n"
        },
        {
          "version": "v0.1.0-beta.14",
          "name": "v0.1.0-beta.14",
          "datetime": "2026-06-09T13:01:55Z",
          "url": "https://github.com/868meshbot/Saitama/releases/tag/v0.1.0-beta.14",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.13...v0.1.0-beta.14",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.13...v0.1.0-beta.14\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.13...v0.1.0-beta.14</a></p>\n"
        },
        {
          "version": "v0.1.0-beta.13",
          "name": "v0.1.0-beta.13",
          "datetime": "2026-06-09T12:36:14Z",
          "url": "https://github.com/868meshbot/Saitama/releases/tag/v0.1.0-beta.13",
          "prerelease": false,
          "notes": "**Full Changelog**: https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.12...v0.1.0-beta.13",
          "notesHtml": "<p><strong>Full Changelog</strong>: <a href=\"https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.12...v0.1.0-beta.13\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/compare/v0.1.0-beta.12...v0.1.0-beta.13</a></p>\n"
        },
        {
          "version": "v0.1.0-beta.10",
          "name": "v0.1.0-beta.10",
          "datetime": "2026-06-05T09:55:04Z",
          "url": "https://github.com/868meshbot/Saitama/releases/tag/v0.1.0-beta.10",
          "prerelease": false,
          "notes": "## What's Changed\n* adds github actions CI build and artifacts archiving by @t413 in https://github.com/868meshbot/Saitama/pull/3\n\n## New Contributors\n* @t413 made their first contribution in https://github.com/868meshbot/Saitama/pull/3\n\n**Full Changelog**: https://github.com/868meshbot/Saitama/commits/v0.1.0-beta.10",
          "notesHtml": "<h2>What's Changed</h2>\n<ul>\n<li>adds github actions CI build and artifacts archiving by @t413 in <a href=\"https://github.com/868meshbot/Saitama/pull/3\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/pull/3</a></li>\n</ul>\n<h2>New Contributors</h2>\n<ul>\n<li>@t413 made their first contribution in <a href=\"https://github.com/868meshbot/Saitama/pull/3\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/pull/3</a></li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/868meshbot/Saitama/commits/v0.1.0-beta.10\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/868meshbot/Saitama/commits/v0.1.0-beta.10</a></p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:40.359Z"
    },
    {
      "id": "wadamesh",
      "name": "Wadamesh",
      "type": "fork",
      "maintainer": "ALLFATHER-BV",
      "description": "A touch-UI MeshCore firmware for the LilyGo T-Deck / T-Deck Plus and Heltec V4 TFT (ESP32-S3), built with LVGL. Split out from meshcomod. Provides a full touch-driven companion experience with on-screen keyboard and WiFi connectivity.\n",
      "repository": "https://github.com/ALLFATHER-BV/wadamesh",
      "license": "GPL-3.0",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion"
      ],
      "features": [
        "LVGL touch UI",
        "On-screen keyboard",
        "WiFi companion connectivity",
        "USB + TCP transports",
        "Split from meshcomod (same maintainer)"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": false,
          "webFlasher": false
        },
        "networking": {
          "repeater": false,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-t-deck",
          "status": "supported"
        },
        {
          "id": "heltec-v4",
          "status": "supported"
        }
      ],
      "latest_version": "beta_9",
      "released": "2026-06-20",
      "releases": [
        {
          "version": "beta_9",
          "name": "wadamesh beta_9",
          "datetime": "2026-06-20T13:18:47Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_9",
          "prerelease": false,
          "notes": "# wadamesh beta_9\n\nA reliability-focused drop — Wi-Fi recovery, a self-healing chat-history fix, crash-report export, plus room-server, map, contacts and app-drawer improvements.\n\n**Install / update:** flash from [flasher.wadamesh.com](https://flasher.wadamesh.com), grab it in LauncherHub, or use the on-device update check (Settings → About).\n\n## Stability\n- **Wi-Fi now reconnects on its own** after the link drops — no more rebooting to get back online.\n- **Fixed reboot-on-every-received-message:** a corrupted chat-history file could make the device reboot whenever a message arrived (and hide your messages). The bad file is now detected and reset automatically, so it recovers on its own.\n- **Boot hardening:** NULL-guards on the display draw buffer so a unit with quirky/limited memory degrades gracefully instead of getting stuck on the boot logo.\n\n## Crash reports\n- After a crash, **Settings → About** shows an **\"Export crash report\"** button that saves the crash dump to the **microSD card** — so you can send it to the devs and get the bug fixed.\n\n## Chat & room servers\n- Room-server messages now show the **time each message was actually sent**, not when it arrived.\n- Room-server messages now show **who sent them**.\n- **Sharing your contact QR** now produces a valid `meshcore://contact/add?…` code that the **MeshCore phone app can scan and import**.\n- Unread counts show **\"99+\"** instead of an alarming raw number on busy channels.\n\n## Map\n- The **reload button for corrupt tiles** now actually clears the cached tiles — **including when you're offline** — and the missing/blank \"twilight zone\" tiles re-download on their own.\n- Fixed tiles not re-fetching at **zoom levels 13–15**.\n\n## Contacts\n- **Favourited contacts always appear** in the contact list now, even with hundreds of similarly-named contacts (they used to stay hidden until you searched).\n\n## App drawer\n- **New icon-size setting** — tap the **cog** at the top-right of the app drawer to switch between **Compact** and **Large** (bigger icons + labels, easier to read).\n- **Smoother scrolling** through the app list and the other scrollable lists.\n\n---\n**Assets:** `*-merged.bin` = full image (flash at 0x0 / erase). Plain `*.bin` = app-only (OTA / Launcher side-load). T-Deck = `wadamesh-tdeck*`, Heltec V4 TFT = `wadamesh-heltec-v4-tft*`.",
          "notesHtml": "<h1>wadamesh beta_9</h1>\n<p>A reliability-focused drop — Wi-Fi recovery, a self-healing chat-history fix, crash-report export, plus room-server, map, contacts and app-drawer improvements.</p>\n<p><strong>Install / update:</strong> flash from <a href=\"https://flasher.wadamesh.com/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.wadamesh.com</a>, grab it in LauncherHub, or use the on-device update check (Settings → About).</p>\n<h2>Stability</h2>\n<ul>\n<li><strong>Wi-Fi now reconnects on its own</strong> after the link drops — no more rebooting to get back online.</li>\n<li><strong>Fixed reboot-on-every-received-message:</strong> a corrupted chat-history file could make the device reboot whenever a message arrived (and hide your messages). The bad file is now detected and reset automatically, so it recovers on its own.</li>\n<li><strong>Boot hardening:</strong> NULL-guards on the display draw buffer so a unit with quirky/limited memory degrades gracefully instead of getting stuck on the boot logo.</li>\n</ul>\n<h2>Crash reports</h2>\n<ul>\n<li>After a crash, <strong>Settings → About</strong> shows an <strong>\"Export crash report\"</strong> button that saves the crash dump to the <strong>microSD card</strong> — so you can send it to the devs and get the bug fixed.</li>\n</ul>\n<h2>Chat &amp; room servers</h2>\n<ul>\n<li>Room-server messages now show the <strong>time each message was actually sent</strong>, not when it arrived.</li>\n<li>Room-server messages now show <strong>who sent them</strong>.</li>\n<li><strong>Sharing your contact QR</strong> now produces a valid <code>meshcore://contact/add?…</code> code that the <strong>MeshCore phone app can scan and import</strong>.</li>\n<li>Unread counts show <strong>\"99+\"</strong> instead of an alarming raw number on busy channels.</li>\n</ul>\n<h2>Map</h2>\n<ul>\n<li>The <strong>reload button for corrupt tiles</strong> now actually clears the cached tiles — <strong>including when you're offline</strong> — and the missing/blank \"twilight zone\" tiles re-download on their own.</li>\n<li>Fixed tiles not re-fetching at <strong>zoom levels 13–15</strong>.</li>\n</ul>\n<h2>Contacts</h2>\n<ul>\n<li><strong>Favourited contacts always appear</strong> in the contact list now, even with hundreds of similarly-named contacts (they used to stay hidden until you searched).</li>\n</ul>\n<h2>App drawer</h2>\n<ul>\n<li><strong>New icon-size setting</strong> — tap the <strong>cog</strong> at the top-right of the app drawer to switch between <strong>Compact</strong> and <strong>Large</strong> (bigger icons + labels, easier to read).</li>\n<li><strong>Smoother scrolling</strong> through the app list and the other scrollable lists.</li>\n</ul>\n<hr />\n<p><strong>Assets:</strong> <code>*-merged.bin</code> = full image (flash at 0x0 / erase). Plain <code>*.bin</code> = app-only (OTA / Launcher side-load). T-Deck = <code>wadamesh-tdeck*</code>, Heltec V4 TFT = <code>wadamesh-heltec-v4-tft*</code>.</p>\n"
        },
        {
          "version": "beta_8",
          "name": "wadamesh beta_8",
          "datetime": "2026-06-19T12:39:54Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_8",
          "prerelease": false,
          "notes": "# wadamesh beta_8\n\nPolish + fixes for the touch UI — a faster chat acknowledgement, map readout controls, and an internal-memory trim.\n\n**Install / update:** flash from [flasher.wadamesh.com](https://flasher.wadamesh.com), grab it in LauncherHub, or use the on-device update check (Settings → About).\n\n## Chat\n- **Quick replies insert at the cursor** instead of replacing whatever you'd already typed.\n- **New one-tap \"Ack\"** — long-press any message and tap *Ack*. It drops a ready-to-send reply into the composer with that message's **signal strength (SNR/RSSI)** and the **route** it took (hop codes), so you can instantly confirm someone's test came through. On a channel it `@`-mentions the sender. You review and send — it's never auto-sent.\n- Fixed the message action menu (**Ack / Copy / Info / Mention / Block**) running off the bottom of the screen — it now fits, and scrolls if it ever needs to.\n\n## Map\n- The zoom button now shows a clear **\"+/-\"** icon.\n- **Show or hide each on-map readout independently** in Map settings — the coordinates line, the tile x/y/z line, and the contact markers.\n- Map settings reorganised: the **microSD-tiles** switch sits at the top under its own heading, separated from the new visibility toggles.\n- **New auto-refresh button** — turn it on and the map re-centres on you automatically whenever your position changes, with an on-screen *Auto-refresh on/off* confirmation.\n- Fixed the close (**X**) in Map settings overlapping the switches when the panel was scrolled.\n\n## Performance\n- Reclaimed **~19 KB of internal RAM** (scratch buffers moved to PSRAM), leaving more headroom for Wi-Fi and trimming the idle-memory growth seen in recent betas.\n\n---\n**Assets:** `*-merged.bin` = full image (flash at 0x0 / erase). Plain `*.bin` = app-only (OTA / Launcher side-load). T-Deck = `wadamesh-tdeck*`, Heltec V4 TFT = `wadamesh-heltec-v4-tft*`.",
          "notesHtml": "<h1>wadamesh beta_8</h1>\n<p>Polish + fixes for the touch UI — a faster chat acknowledgement, map readout controls, and an internal-memory trim.</p>\n<p><strong>Install / update:</strong> flash from <a href=\"https://flasher.wadamesh.com/\" target=\"_blank\" rel=\"noopener noreferrer\">flasher.wadamesh.com</a>, grab it in LauncherHub, or use the on-device update check (Settings → About).</p>\n<h2>Chat</h2>\n<ul>\n<li><strong>Quick replies insert at the cursor</strong> instead of replacing whatever you'd already typed.</li>\n<li><strong>New one-tap \"Ack\"</strong> — long-press any message and tap <em>Ack</em>. It drops a ready-to-send reply into the composer with that message's <strong>signal strength (SNR/RSSI)</strong> and the <strong>route</strong> it took (hop codes), so you can instantly confirm someone's test came through. On a channel it <code>@</code>-mentions the sender. You review and send — it's never auto-sent.</li>\n<li>Fixed the message action menu (<strong>Ack / Copy / Info / Mention / Block</strong>) running off the bottom of the screen — it now fits, and scrolls if it ever needs to.</li>\n</ul>\n<h2>Map</h2>\n<ul>\n<li>The zoom button now shows a clear <strong>\"+/-\"</strong> icon.</li>\n<li><strong>Show or hide each on-map readout independently</strong> in Map settings — the coordinates line, the tile x/y/z line, and the contact markers.</li>\n<li>Map settings reorganised: the <strong>microSD-tiles</strong> switch sits at the top under its own heading, separated from the new visibility toggles.</li>\n<li><strong>New auto-refresh button</strong> — turn it on and the map re-centres on you automatically whenever your position changes, with an on-screen <em>Auto-refresh on/off</em> confirmation.</li>\n<li>Fixed the close (<strong>X</strong>) in Map settings overlapping the switches when the panel was scrolled.</li>\n</ul>\n<h2>Performance</h2>\n<ul>\n<li>Reclaimed <strong>~19 KB of internal RAM</strong> (scratch buffers moved to PSRAM), leaving more headroom for Wi-Fi and trimming the idle-memory growth seen in recent betas.</li>\n</ul>\n<hr />\n<p><strong>Assets:</strong> <code>*-merged.bin</code> = full image (flash at 0x0 / erase). Plain <code>*.bin</code> = app-only (OTA / Launcher side-load). T-Deck = <code>wadamesh-tdeck*</code>, Heltec V4 TFT = <code>wadamesh-heltec-v4-tft*</code>.</p>\n"
        },
        {
          "version": "beta_7",
          "name": "wadamesh beta_7",
          "datetime": "2026-06-18T10:25:46Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_7",
          "prerelease": false,
          "notes": "**wadamesh beta_7** for the LilyGo T-Deck and Heltec V4 TFT.\n\n🔧 **Flash in your browser:** https://flasher.wadamesh.com — or update on-device (Settings → check for update), or side-load `wadamesh-tdeck.bin` through Launcher.\n\n> 🙌 **Most of this release was built by the community.** [@Vybo](https://github.com/Vybo) (Dan Vybiral) contributed the lion's share in [#12](https://github.com/ALLFATHER-BV/wadamesh/pull/12) — the Snake game, battery & telemetry history, map night mode, the PNG/BMP image viewer, and the entire status-bar toolkit. [@tun0](https://github.com/tun0) (Ruben Laban) fixed unread badges and chat-history persistence in [#15](https://github.com/ALLFATHER-BV/wadamesh/pull/15). Thank you both. 🎉\n\n### 🐍 Snake game — by [@Vybo](https://github.com/Vybo) (#12)\nA Snake game in the app drawer — steer by swiping the screen or with the T-Deck trackball, with pause/resume and restart after a game over. (Touch now stays inside the game and doesn't leak to the screen behind it.)\n\n### 🔋 Battery & telemetry — by [@Vybo](https://github.com/Vybo) (#12)\n- **Tap the battery** in the status bar for a **24-hour history chart** with an estimated time-left readout (logged every 5 minutes).\n- **Per-node telemetry window** — poll a node's battery, temperature and humidity, watch them on a live chart, and keep a per-node log.\n\n### 🗺️ Map — by [@Vybo](https://github.com/Vybo) (#12)\n- **Night mode** — the status bar and tab bar invert to match the dark map.\n- Live **zoom-level readout** above the zoom slider, and a proper magnifier icon on the zoom button.\n- New **\"Show on map\"** contact action that centres the map on that node.\n\n### 📊 Status bar & tools — by [@Vybo](https://github.com/Vybo) (#12)\n- A **microSD activity LED** that lights on card access (including file-manager reads/copies).\n- An **activity spinner** while a telemetry / admin / ping / trace / range / sightline request is in flight.\n- Option to **hide the device name** and move the clock left.\n- **Hold the status bar** to save a full-screen screenshot to SD.\n\n### 🖼️ Files & images — by [@Vybo](https://github.com/Vybo) (#12)\nThe file browser now previews **PNG and BMP** images (not just JPEG), with no stale image when opening several in a row.\n\n### 💬 Chat reliability\n- **Fixed garbled / duplicated messages** — chat text is no longer corrupted in transit, so messages arrive intact and duplicates are filtered out correctly. Thanks to [@marcelverdult](https://github.com/marcelverdult) for the precise report ([#13](https://github.com/ALLFATHER-BV/wadamesh/issues/13)).\n- **Accurate unread badges** and **more chat history kept across reboots** — by [@tun0](https://github.com/tun0) ([#15](https://github.com/ALLFATHER-BV/wadamesh/pull/15)).\n\n### ✨ Also in this release\n- **Lock-screen wallpaper from Files** — view any JPEG on your SD card and tap \"Set as wallpaper\".\n- **Set your own Bluetooth pairing code** in Settings.\n- The app drawer **fits all the apps** again (no clipped bottom row) and shows a **scrollbar** when there's more to scroll.\n- Fixed map-tile caching (false \"storage full\"); black/missing tiles re-download. `@`-reply no longer overwrites text you were typing. Fixed an out-of-memory crash and made notification audio more reliable.\n\n---\n\n**Contributors:** [@Vybo](https://github.com/Vybo) (Dan Vybiral) · [@tun0](https://github.com/tun0) (Ruben Laban) · [@marcelverdult](https://github.com/marcelverdult) (reported #13).\n\n**Boards:** T-Deck → `wadamesh-tdeck*.bin` · Heltec V4 TFT → `wadamesh-heltec-v4-tft*.bin`. Use `-merged.bin` for a full flash at 0x0 (web flasher / esptool), or the plain `.bin` for on-device update / Launcher.",
          "notesHtml": "<p><strong>wadamesh beta_7</strong> for the LilyGo T-Deck and Heltec V4 TFT.</p>\n<p>🔧 <strong>Flash in your browser:</strong> <a href=\"https://flasher.wadamesh.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.wadamesh.com</a> — or update on-device (Settings → check for update), or side-load <code>wadamesh-tdeck.bin</code> through Launcher.</p>\n<blockquote>\n<p>🙌 <strong>Most of this release was built by the community.</strong> <a href=\"https://github.com/Vybo\" target=\"_blank\" rel=\"noopener noreferrer\">@Vybo</a> (Dan Vybiral) contributed the lion's share in <a href=\"https://github.com/ALLFATHER-BV/wadamesh/pull/12\" target=\"_blank\" rel=\"noopener noreferrer\">#12</a> — the Snake game, battery &amp; telemetry history, map night mode, the PNG/BMP image viewer, and the entire status-bar toolkit. <a href=\"https://github.com/tun0\" target=\"_blank\" rel=\"noopener noreferrer\">@tun0</a> (Ruben Laban) fixed unread badges and chat-history persistence in <a href=\"https://github.com/ALLFATHER-BV/wadamesh/pull/15\" target=\"_blank\" rel=\"noopener noreferrer\">#15</a>. Thank you both. 🎉</p>\n</blockquote>\n<h3>🐍 Snake game — by <a href=\"https://github.com/Vybo\" target=\"_blank\" rel=\"noopener noreferrer\">@Vybo</a> (#12)</h3>\n<p>A Snake game in the app drawer — steer by swiping the screen or with the T-Deck trackball, with pause/resume and restart after a game over. (Touch now stays inside the game and doesn't leak to the screen behind it.)</p>\n<h3>🔋 Battery &amp; telemetry — by <a href=\"https://github.com/Vybo\" target=\"_blank\" rel=\"noopener noreferrer\">@Vybo</a> (#12)</h3>\n<ul>\n<li><strong>Tap the battery</strong> in the status bar for a <strong>24-hour history chart</strong> with an estimated time-left readout (logged every 5 minutes).</li>\n<li><strong>Per-node telemetry window</strong> — poll a node's battery, temperature and humidity, watch them on a live chart, and keep a per-node log.</li>\n</ul>\n<h3>🗺️ Map — by <a href=\"https://github.com/Vybo\" target=\"_blank\" rel=\"noopener noreferrer\">@Vybo</a> (#12)</h3>\n<ul>\n<li><strong>Night mode</strong> — the status bar and tab bar invert to match the dark map.</li>\n<li>Live <strong>zoom-level readout</strong> above the zoom slider, and a proper magnifier icon on the zoom button.</li>\n<li>New <strong>\"Show on map\"</strong> contact action that centres the map on that node.</li>\n</ul>\n<h3>📊 Status bar &amp; tools — by <a href=\"https://github.com/Vybo\" target=\"_blank\" rel=\"noopener noreferrer\">@Vybo</a> (#12)</h3>\n<ul>\n<li>A <strong>microSD activity LED</strong> that lights on card access (including file-manager reads/copies).</li>\n<li>An <strong>activity spinner</strong> while a telemetry / admin / ping / trace / range / sightline request is in flight.</li>\n<li>Option to <strong>hide the device name</strong> and move the clock left.</li>\n<li><strong>Hold the status bar</strong> to save a full-screen screenshot to SD.</li>\n</ul>\n<h3>🖼️ Files &amp; images — by <a href=\"https://github.com/Vybo\" target=\"_blank\" rel=\"noopener noreferrer\">@Vybo</a> (#12)</h3>\n<p>The file browser now previews <strong>PNG and BMP</strong> images (not just JPEG), with no stale image when opening several in a row.</p>\n<h3>💬 Chat reliability</h3>\n<ul>\n<li><strong>Fixed garbled / duplicated messages</strong> — chat text is no longer corrupted in transit, so messages arrive intact and duplicates are filtered out correctly. Thanks to <a href=\"https://github.com/marcelverdult\" target=\"_blank\" rel=\"noopener noreferrer\">@marcelverdult</a> for the precise report (<a href=\"https://github.com/ALLFATHER-BV/wadamesh/issues/13\" target=\"_blank\" rel=\"noopener noreferrer\">#13</a>).</li>\n<li><strong>Accurate unread badges</strong> and <strong>more chat history kept across reboots</strong> — by <a href=\"https://github.com/tun0\" target=\"_blank\" rel=\"noopener noreferrer\">@tun0</a> (<a href=\"https://github.com/ALLFATHER-BV/wadamesh/pull/15\" target=\"_blank\" rel=\"noopener noreferrer\">#15</a>).</li>\n</ul>\n<h3>✨ Also in this release</h3>\n<ul>\n<li><strong>Lock-screen wallpaper from Files</strong> — view any JPEG on your SD card and tap \"Set as wallpaper\".</li>\n<li><strong>Set your own Bluetooth pairing code</strong> in Settings.</li>\n<li>The app drawer <strong>fits all the apps</strong> again (no clipped bottom row) and shows a <strong>scrollbar</strong> when there's more to scroll.</li>\n<li>Fixed map-tile caching (false \"storage full\"); black/missing tiles re-download. <code>@</code>-reply no longer overwrites text you were typing. Fixed an out-of-memory crash and made notification audio more reliable.</li>\n</ul>\n<hr />\n<p><strong>Contributors:</strong> <a href=\"https://github.com/Vybo\" target=\"_blank\" rel=\"noopener noreferrer\">@Vybo</a> (Dan Vybiral) · <a href=\"https://github.com/tun0\" target=\"_blank\" rel=\"noopener noreferrer\">@tun0</a> (Ruben Laban) · <a href=\"https://github.com/marcelverdult\" target=\"_blank\" rel=\"noopener noreferrer\">@marcelverdult</a> (reported #13).</p>\n<p><strong>Boards:</strong> T-Deck → <code>wadamesh-tdeck*.bin</code> · Heltec V4 TFT → <code>wadamesh-heltec-v4-tft*.bin</code>. Use <code>-merged.bin</code> for a full flash at 0x0 (web flasher / esptool), or the plain <code>.bin</code> for on-device update / Launcher.</p>\n"
        },
        {
          "version": "beta_6",
          "name": "wadamesh beta_6",
          "datetime": "2026-06-16T22:40:43Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_6",
          "prerelease": false,
          "notes": "Touch firmware **beta_6** for the **LilyGo T-Deck** and **Heltec V4 + TFT**.\n\nInstall or update via the web flasher → **https://flasher.wadamesh.com** (or flash the `*-merged.bin` at `0x0` with esptool). Devices on beta_5 will see beta_6 on their next update check.\n\n---\n\n### New: RF Monitor app\n- A new **Monitor** app on the app drawer — a live RF sniffer that shows exactly what your node is pulling out of the air in real time.\n- A **\"Recently heard\"** feed lists recent received frames by type (text, advert, ack, route-trace…) with **RSSI, SNR and hop count**, colour-coded by type.\n- A **link-margin** readout grades how much headroom your last packet had (green / amber / red), alongside a live **packet rate** and a **noise-floor + peak-hold RSSI scope with an on-screen dBm scale**.\n- Lays out cleanly in both **portrait and landscape**, so it's readable on the Heltec V4 and the T-Deck.\n\n### Chat & contacts\n- Direct-message chats now show a **person icon** and channels a **group icon** (instead of the old loop / envelope).\n- **Block a non-contact sender by name** — handy for silencing an automated room or repeater bot you couldn't block before.\n- Opening a chat or channel **no longer jumps to the newest message** — it keeps your scroll position.\n- The contacts **Sort & Filter** popup now closes after you pick a sort option.\n- Fixed the chat/channel **long-press popup**: the close ✕ no longer overlaps the buttons while you scroll it.\n\n### Time & timezone\n- New **time-zone picker** with named zones (no longer CET-only) — set yours in **Settings → System**.\n- Fixed the clock getting **stuck at 1902** and channels showing 1969–1970 dates: GPS no longer clobbers the clock with an invalid date, and the time now **survives a reboot**.\n\n### Launcher & Wi-Fi\n- **Map tiles now download under Launcher** (the tile cache was wrongly reported as full).\n- **GPS now gets a fix under Launcher.**\n- The setup-wizard **Wi-Fi scan no longer comes up empty** — modem sleep is deferred until after you're connected.\n\n### Bluetooth\n- Bluetooth now **advertises under your node / profile name** instead of \"NimBLE\".\n- The **Bluetooth PIN no longer resets** on its own — it's saved and reused across reboots.\n\n### Power & performance\n- Turning the screen off now **downclocks the CPU** and enables Wi-Fi modem sleep to save power.\n- On the map, your **position dot is drawn before the tiles** so it no longer lags behind when panning.\n\n### Community\n- Merged map-server and SD-tile rendering fixes contributed by **Vybo** (#11). Thanks!",
          "notesHtml": "<p>Touch firmware <strong>beta_6</strong> for the <strong>LilyGo T-Deck</strong> and <strong>Heltec V4 + TFT</strong>.</p>\n<p>Install or update via the web flasher → <strong><a href=\"https://flasher.wadamesh.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.wadamesh.com</a></strong> (or flash the <code>*-merged.bin</code> at <code>0x0</code> with esptool). Devices on beta_5 will see beta_6 on their next update check.</p>\n<hr />\n<h3>New: RF Monitor app</h3>\n<ul>\n<li>A new <strong>Monitor</strong> app on the app drawer — a live RF sniffer that shows exactly what your node is pulling out of the air in real time.</li>\n<li>A <strong>\"Recently heard\"</strong> feed lists recent received frames by type (text, advert, ack, route-trace…) with <strong>RSSI, SNR and hop count</strong>, colour-coded by type.</li>\n<li>A <strong>link-margin</strong> readout grades how much headroom your last packet had (green / amber / red), alongside a live <strong>packet rate</strong> and a <strong>noise-floor + peak-hold RSSI scope with an on-screen dBm scale</strong>.</li>\n<li>Lays out cleanly in both <strong>portrait and landscape</strong>, so it's readable on the Heltec V4 and the T-Deck.</li>\n</ul>\n<h3>Chat &amp; contacts</h3>\n<ul>\n<li>Direct-message chats now show a <strong>person icon</strong> and channels a <strong>group icon</strong> (instead of the old loop / envelope).</li>\n<li><strong>Block a non-contact sender by name</strong> — handy for silencing an automated room or repeater bot you couldn't block before.</li>\n<li>Opening a chat or channel <strong>no longer jumps to the newest message</strong> — it keeps your scroll position.</li>\n<li>The contacts <strong>Sort &amp; Filter</strong> popup now closes after you pick a sort option.</li>\n<li>Fixed the chat/channel <strong>long-press popup</strong>: the close ✕ no longer overlaps the buttons while you scroll it.</li>\n</ul>\n<h3>Time &amp; timezone</h3>\n<ul>\n<li>New <strong>time-zone picker</strong> with named zones (no longer CET-only) — set yours in <strong>Settings → System</strong>.</li>\n<li>Fixed the clock getting <strong>stuck at 1902</strong> and channels showing 1969–1970 dates: GPS no longer clobbers the clock with an invalid date, and the time now <strong>survives a reboot</strong>.</li>\n</ul>\n<h3>Launcher &amp; Wi-Fi</h3>\n<ul>\n<li><strong>Map tiles now download under Launcher</strong> (the tile cache was wrongly reported as full).</li>\n<li><strong>GPS now gets a fix under Launcher.</strong></li>\n<li>The setup-wizard <strong>Wi-Fi scan no longer comes up empty</strong> — modem sleep is deferred until after you're connected.</li>\n</ul>\n<h3>Bluetooth</h3>\n<ul>\n<li>Bluetooth now <strong>advertises under your node / profile name</strong> instead of \"NimBLE\".</li>\n<li>The <strong>Bluetooth PIN no longer resets</strong> on its own — it's saved and reused across reboots.</li>\n</ul>\n<h3>Power &amp; performance</h3>\n<ul>\n<li>Turning the screen off now <strong>downclocks the CPU</strong> and enables Wi-Fi modem sleep to save power.</li>\n<li>On the map, your <strong>position dot is drawn before the tiles</strong> so it no longer lags behind when panning.</li>\n</ul>\n<h3>Community</h3>\n<ul>\n<li>Merged map-server and SD-tile rendering fixes contributed by <strong>Vybo</strong> (#11). Thanks!</li>\n</ul>\n"
        },
        {
          "version": "beta_5",
          "name": "wadamesh beta_5",
          "datetime": "2026-06-15T21:19:46Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_5",
          "prerelease": false,
          "notes": "Touch firmware **beta_5** for the **LilyGo T-Deck** and **Heltec V4 + TFT**.\n\nInstall or update via the web flasher → **https://flasher.wadamesh.com** (or flash the `*-merged.bin` at `0x0` with esptool). Devices on beta_4 will see beta_5 on their next update check.\n\n---\n\n### Contacts\n- Person icon for people and an antenna for repeaters, instead of a generic envelope / lightning bolt.\n- **Block / unblock** anyone straight from their popup — blocked contacts get a red person icon and their messages are hidden.\n- The list is now a proper table: dedicated **last-heard** and **distance** columns, a **Sort & Filter** button, and **multi-select delete** with an are-you-sure prompt and a progress bar (favourites are protected — unfavourite them first).\n- Time and distance are smaller and pushed right so names get more room; a name too long for two lines scrolls instead of spilling onto a third.\n- Un-favouriting a contact removes its star right away.\n\n### Discovered nodes\n- The Discovered list now **survives reboots** (it used to empty every boot) and holds up to **48** nodes.\n- New **Discovered settings** (cogwheel): auto-delete the oldest node when full, and **auto-delete anything heard via more than N hops** — keeps the list fresh and nearby.\n- The count badge shows **\"48!\"** when the list is full.\n- Adding a node from Discovered appears in Contacts immediately; a purge-all button sits next to Close.\n\n### Region & radio\n- **Setting the region / default scope from the official MeshCore app now works** — it used to time out (`no_event_received`); public-channel floods are now region-tagged. (`companion-v1.16.0.3`, issue #31)\n- **US/Canada** radio preset corrected to the proper **910.525 MHz · 62.5 kHz · SF7** (was 915 MHz / 250 kHz / SF11).\n- **T-Deck transmit power** restored to the full **+22 dBm** — the SX1262 antenna switch was mis-driven, leaking most of the power (~4 mW). (issue #6)\n- Auto-add settings moved to their own dedicated page (out of Radio), reachable from the Contacts menu too.\n\n### Chats & sound\n- Each chat / channel row now shows the **time of its most recent message** on the right.\n- **Mute messages and/or @-mentions per channel**, from that channel's settings.\n- The **@-mentions screen** has taller rows (fits two lines); tapping a mention **jumps to that exact message**.\n- **Volume is now +/- buttons** instead of a hard-to-drag slider; a master **Sound** switch silences everything, with independent **Messages** and **@-mention** switches (the @-mention chime is distinct, with its own on/off + volume).\n\n### Map\n- The map **remembers your zoom and pan** when you leave and come back, instead of snapping back to your location every time.\n- Tapping a contact on the map opens a **compact popup** (no Block button there).\n\n### Keyboard & input\n- **T-Deck keyboard: backspace deletes at the cursor** instead of always chopping the last character, and editing respects where you place the caret.\n- The **Quick replies** page now scrolls so you can reach and edit every slot.\n\n### UI polish\n- Refined bottom tab bar — flat icons that take your theme colour with a soft glow under the active tab — plus an **unread-count badge** on the Chats icon.\n- App drawer: colourful app icons, the command tile relabelled **\"Cmdr\"**, the Apps button in a contrasting accent, and **three-per-row on the Heltec V4**.\n- Full-screen settings pages with a clear X to close, a subtle new-message chip, and a **full-page Signal view** with a live readout and manual refresh.",
          "notesHtml": "<p>Touch firmware <strong>beta_5</strong> for the <strong>LilyGo T-Deck</strong> and <strong>Heltec V4 + TFT</strong>.</p>\n<p>Install or update via the web flasher → <strong><a href=\"https://flasher.wadamesh.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://flasher.wadamesh.com</a></strong> (or flash the <code>*-merged.bin</code> at <code>0x0</code> with esptool). Devices on beta_4 will see beta_5 on their next update check.</p>\n<hr />\n<h3>Contacts</h3>\n<ul>\n<li>Person icon for people and an antenna for repeaters, instead of a generic envelope / lightning bolt.</li>\n<li><strong>Block / unblock</strong> anyone straight from their popup — blocked contacts get a red person icon and their messages are hidden.</li>\n<li>The list is now a proper table: dedicated <strong>last-heard</strong> and <strong>distance</strong> columns, a <strong>Sort &amp; Filter</strong> button, and <strong>multi-select delete</strong> with an are-you-sure prompt and a progress bar (favourites are protected — unfavourite them first).</li>\n<li>Time and distance are smaller and pushed right so names get more room; a name too long for two lines scrolls instead of spilling onto a third.</li>\n<li>Un-favouriting a contact removes its star right away.</li>\n</ul>\n<h3>Discovered nodes</h3>\n<ul>\n<li>The Discovered list now <strong>survives reboots</strong> (it used to empty every boot) and holds up to <strong>48</strong> nodes.</li>\n<li>New <strong>Discovered settings</strong> (cogwheel): auto-delete the oldest node when full, and <strong>auto-delete anything heard via more than N hops</strong> — keeps the list fresh and nearby.</li>\n<li>The count badge shows <strong>\"48!\"</strong> when the list is full.</li>\n<li>Adding a node from Discovered appears in Contacts immediately; a purge-all button sits next to Close.</li>\n</ul>\n<h3>Region &amp; radio</h3>\n<ul>\n<li><strong>Setting the region / default scope from the official MeshCore app now works</strong> — it used to time out (<code>no_event_received</code>); public-channel floods are now region-tagged. (<code>companion-v1.16.0.3</code>, issue #31)</li>\n<li><strong>US/Canada</strong> radio preset corrected to the proper <strong>910.525 MHz · 62.5 kHz · SF7</strong> (was 915 MHz / 250 kHz / SF11).</li>\n<li><strong>T-Deck transmit power</strong> restored to the full <strong>+22 dBm</strong> — the SX1262 antenna switch was mis-driven, leaking most of the power (~4 mW). (issue #6)</li>\n<li>Auto-add settings moved to their own dedicated page (out of Radio), reachable from the Contacts menu too.</li>\n</ul>\n<h3>Chats &amp; sound</h3>\n<ul>\n<li>Each chat / channel row now shows the <strong>time of its most recent message</strong> on the right.</li>\n<li><strong>Mute messages and/or @-mentions per channel</strong>, from that channel's settings.</li>\n<li>The <strong>@-mentions screen</strong> has taller rows (fits two lines); tapping a mention <strong>jumps to that exact message</strong>.</li>\n<li><strong>Volume is now +/- buttons</strong> instead of a hard-to-drag slider; a master <strong>Sound</strong> switch silences everything, with independent <strong>Messages</strong> and <strong>@-mention</strong> switches (the @-mention chime is distinct, with its own on/off + volume).</li>\n</ul>\n<h3>Map</h3>\n<ul>\n<li>The map <strong>remembers your zoom and pan</strong> when you leave and come back, instead of snapping back to your location every time.</li>\n<li>Tapping a contact on the map opens a <strong>compact popup</strong> (no Block button there).</li>\n</ul>\n<h3>Keyboard &amp; input</h3>\n<ul>\n<li><strong>T-Deck keyboard: backspace deletes at the cursor</strong> instead of always chopping the last character, and editing respects where you place the caret.</li>\n<li>The <strong>Quick replies</strong> page now scrolls so you can reach and edit every slot.</li>\n</ul>\n<h3>UI polish</h3>\n<ul>\n<li>Refined bottom tab bar — flat icons that take your theme colour with a soft glow under the active tab — plus an <strong>unread-count badge</strong> on the Chats icon.</li>\n<li>App drawer: colourful app icons, the command tile relabelled <strong>\"Cmdr\"</strong>, the Apps button in a contrasting accent, and <strong>three-per-row on the Heltec V4</strong>.</li>\n<li>Full-screen settings pages with a clear X to close, a subtle new-message chip, and a <strong>full-page Signal view</strong> with a live readout and manual refresh.</li>\n</ul>\n"
        },
        {
          "version": "beta_4",
          "name": "wadamesh beta_4",
          "datetime": "2026-06-14T15:29:19Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_4",
          "prerelease": false,
          "notes": "Touch firmware **beta_4** for the LilyGo T-Deck and Heltec V4 + TFT. Built by CI from `7b7ea17031e0d24f2045158bf3744fd9bac1f2b2`.",
          "notesHtml": "<p>Touch firmware <strong>beta_4</strong> for the LilyGo T-Deck and Heltec V4 + TFT. Built by CI from <code>7b7ea17031e0d24f2045158bf3744fd9bac1f2b2</code>.</p>\n"
        },
        {
          "version": "beta_3",
          "name": "wadamesh beta_3",
          "datetime": "2026-06-13T21:17:35Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_3",
          "prerelease": false,
          "notes": "Touch firmware **beta_3** for the LilyGo T-Deck and Heltec V4 + TFT. Built by CI from `058721fdbc572b4332ad55df12c750331d38aa9a`.",
          "notesHtml": "<p>Touch firmware <strong>beta_3</strong> for the LilyGo T-Deck and Heltec V4 + TFT. Built by CI from <code>058721fdbc572b4332ad55df12c750331d38aa9a</code>.</p>\n"
        },
        {
          "version": "beta_2",
          "name": "wadamesh beta_2",
          "datetime": "2026-06-13T13:52:48Z",
          "url": "https://github.com/ALLFATHER-BV/wadamesh/releases/tag/beta_2",
          "prerelease": false,
          "notes": "Touch firmware for the **LilyGo T-Deck / T-Deck Plus** and **Heltec V4 + TFT**.\n\n### What's new since beta_1\n- **WADAMESH boot logo** — the old MESHCOMOD wordmark is replaced by the brand logo: an anti-aliased mesh mark with the teal dots, on screen from power-on and carried seamlessly into the colour LVGL splash. Brand teal (`#15B6A6`) is now the default UI accent and is in the Theme-colour picker.\n- **Wi-Fi scan no longer crashes** — \"Wi-Fi on but no network connected\" could trip the 5 s task watchdog and reboot. The scan is now a single bounded, yielding async pass.\n- **Wi-Fi settings apply live** — saving credentials or scanning no longer prompts for / forces a reboot (Wi-Fi and BLE coexist via NimBLE).\n- **Factory reset actually wipes** — on SD-card storage it crashed mid-erase and left everything intact; it now wipes SD + NVS cleanly and reboots into a fresh device. (Also fixes the file-manager recursive folder delete.)\n\n### Install\nFlash the `*-merged.bin` for your board at `0x0` with erase (or use the web flasher at flasher.wadamesh.com). The `*.bin` (no `-merged`) is the app-only image for OTA / Launcher.",
          "notesHtml": "<p>Touch firmware for the <strong>LilyGo T-Deck / T-Deck Plus</strong> and <strong>Heltec V4 + TFT</strong>.</p>\n<h3>What's new since beta_1</h3>\n<ul>\n<li><strong>WADAMESH boot logo</strong> — the old MESHCOMOD wordmark is replaced by the brand logo: an anti-aliased mesh mark with the teal dots, on screen from power-on and carried seamlessly into the colour LVGL splash. Brand teal (<code>#15B6A6</code>) is now the default UI accent and is in the Theme-colour picker.</li>\n<li><strong>Wi-Fi scan no longer crashes</strong> — \"Wi-Fi on but no network connected\" could trip the 5 s task watchdog and reboot. The scan is now a single bounded, yielding async pass.</li>\n<li><strong>Wi-Fi settings apply live</strong> — saving credentials or scanning no longer prompts for / forces a reboot (Wi-Fi and BLE coexist via NimBLE).</li>\n<li><strong>Factory reset actually wipes</strong> — on SD-card storage it crashed mid-erase and left everything intact; it now wipes SD + NVS cleanly and reboots into a fresh device. (Also fixes the file-manager recursive folder delete.)</li>\n</ul>\n<h3>Install</h3>\n<p>Flash the <code>*-merged.bin</code> for your board at <code>0x0</code> with erase (or use the web flasher at flasher.wadamesh.com). The <code>*.bin</code> (no <code>-merged</code>) is the app-only image for OTA / Launcher.</p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:40.738Z"
    },
    {
      "id": "zephcore",
      "name": "ZephCore",
      "type": "custom",
      "maintainer": "liquidraver",
      "description": "A ground-up port of MeshCore from Arduino to the Zephyr RTOS. Replaces the Arduino loop with Zephyr's event-driven primitives so the CPU sleeps between events, while aiming for full protocol compatibility with stock MeshCore firmware and the MeshCore mobile apps.\n",
      "repository": "https://github.com/liquidraver/ZephCore",
      "website": "",
      "license": "MIT",
      "status": "active",
      "lifecycle": "active",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "reimplementation",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "zephyr",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "observer"
      ],
      "features": [
        "Zephyr RTOS event-driven architecture",
        "CAD-based RX power saving",
        "Adaptive contention window",
        "Adaptive Power Control",
        "DFU / OTA update support",
        "Listen-only observer (WiFi + MQTT)",
        "Protocol-compatible with MeshCore apps"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true,
          "rawPacketSend": true,
          "rawPacketObserve": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "bleDfu": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": true,
          "mqtt": true,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": true,
          "lowPowerRx": true
        }
      },
      "devices": [
        {
          "id": "rak-4631",
          "status": "supported"
        },
        {
          "id": "uart-solar-node-station",
          "status": "supported"
        },
        {
          "id": "lilygo-techo",
          "status": "supported"
        },
        {
          "id": "wio-tracker-l1",
          "status": "supported"
        },
        {
          "id": "wio-tracker-l1-pro",
          "status": "supported"
        },
        {
          "id": "heltec-v3",
          "status": "supported"
        },
        {
          "id": "heltec-wsl3",
          "status": "supported"
        },
        {
          "id": "heltec-v4",
          "status": "supported"
        },
        {
          "id": "heltec-v4-exp",
          "status": "supported"
        },
        {
          "id": "heltec-t114",
          "status": "supported"
        },
        {
          "id": "heltec-wt3",
          "status": "supported"
        },
        {
          "id": "lilygo-t-beam-sx1262",
          "status": "supported"
        },
        {
          "id": "lilygo-tlora-c6",
          "status": "supported"
        },
        {
          "id": "rak-13302",
          "status": "supported"
        },
        {
          "id": "rak-wismesh-tag",
          "status": "supported"
        },
        {
          "id": "sensecap-solar-p1",
          "status": "supported"
        },
        {
          "id": "sensecap-solar-p1-pro",
          "status": "supported"
        },
        {
          "id": "sensecap-t1000e",
          "status": "supported"
        },
        {
          "id": "station-g2",
          "status": "supported"
        },
        {
          "id": "thinknode-m1",
          "status": "supported"
        },
        {
          "id": "thinknode-m3",
          "status": "supported"
        },
        {
          "id": "thinknode-m6",
          "status": "supported"
        },
        {
          "id": "faketec",
          "status": "supported"
        },
        {
          "id": "gatiot-gat562-30s",
          "status": "supported"
        },
        {
          "id": "xiao-esp32c3",
          "status": "supported"
        },
        {
          "id": "xiao-esp32c6",
          "status": "supported"
        },
        {
          "id": "xiao-esp32s3",
          "status": "supported"
        },
        {
          "id": "xiao-esp32s3-plain",
          "status": "supported"
        },
        {
          "id": "xiao-nrf52",
          "status": "supported"
        },
        {
          "id": "nrf54l15",
          "status": "partial",
          "notes": "Early bring-up; not all peripherals wired."
        }
      ],
      "latest_version": "20260619.094253",
      "released": "2026-06-19",
      "releases": [
        {
          "version": "v20260619.094253",
          "name": "Firmware v20260619.094253",
          "datetime": "2026-06-19T09:43:10Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260619.094253",
          "prerelease": false,
          "notes": "# ZephCore v1.16.3-zephyr\r\n\r\n> (re-re-re-release(last time I swear) with the \"smearing fix on eink after the full update\" and \"automount error on a freshly formatted node\")\r\n\r\n> [!IMPORTANT]\r\n> ## Before you upgrade\r\n>\r\n> **Updating from v1.16.2** — clean flash, no re-bond required, bonds survive.\r\n>\r\n> **Updating from v1.16.1 or older** — flash the firmware; the firmware detects the old installation on first boot and clears the BLE bond storage automatically. Your identity, contacts, channels, and prefs are preserved. You will need to **re-bond** your phone/desktop once (old pairings were stored in a different location that v1.16.2 moved away from). No formatter tool required.\r\n>\r\n> **Coming from Arduino MeshCore** — flash the firmware; it detects the incompatible filesystem on first boot and formats automatically. Everything starts fresh (new identity, clean storage). No formatter tool required.\r\n>\r\n> Take this with a grain of salt tho… try the formatters if anything anomalous happens with your node.\r\n\r\n---\r\n\r\nThis is a GPS-focused release: it stops a battery-killing bug on GPS trackers, puts the GPS duty cycle under your control, and follows up the v1.16.2 ESP32 pairing work with a fix for recent Android phones.\r\n\r\n## Highlights\r\n\r\n### Fixed: ThinkNode M1 draining its battery in a day\r\nOn the ThinkNode M1, the GPS module was never actually powered down between fixes — the reset line was mislabeled in the board definition and held permanently released, so the receiver kept drawing current even when the firmware thought it was asleep. A full battery could disappear in roughly a day with GPS enabled.\r\n\r\nThe M1 now asserts the GPS hardware reset on standby, so the GPS genuinely stops between fixes. If you run an M1 with GPS on, this is the fix you want.\r\n\r\n### New: configurable GPS duty cycle — `set gps duty <seconds>`\r\nYou can now decide how your node handles GPS, instead of it being baked in:\r\n\r\n- **`set gps duty <seconds>`** — how long the GPS sleeps between fixes. Persists to flash and applies immediately.\r\n- **`set gps duty 0`** — **always-on**: the GPS never sleeps. It streams fresh fixes (so telemetry is always current) and stays on long enough to download a full almanac.\r\n- **`set gps duty default`** — reset to the role default.\r\n- **`get gps duty`** — show the now-effective interval.\r\n\r\nThis unifies repeaters and companions behind one knob. **Repeaters default to 48 h** (GPS wakes only for periodic time-sync) and **companions to 5 minutes** — both now adjustable. Existing repeaters are migrated automatically; nothing to do.\r\n\r\n> Bad input is rejected with a usage hint, and the value is clamped to a sane range (10 s … 1 week, or 0 for always-on).\r\n\r\n### Fixed: GPS no longer pins itself on waiting for a first fix\r\nPreviously, after enabling GPS a companion would keep the receiver powered **indefinitely** until it got its first fix — so a node left somewhere without sky view (indoors, in a bag) could quietly drain its battery forever. The first cold-start acquisition is now bounded (5 minutes by default, enough for a genuine cold start), after which the node drops into its normal duty cycle whether or not it got a fix.\r\n\r\n### Fixed: ESP32 Secure Connections pairing (Pixel 7 / recent Android)\r\nFollowing the v1.16.2 ESP32 pairing fix, SC-capable centrals — notably recent Android phones like the Pixel 7 — still failed to bond: the controller's encryption table was left uninitialized because the relevant code was guarded on an ESP-IDF symbol that never exists in a Zephyr build, so the link dropped with a MIC failure at encryption start. The guard is corrected (carried as a managed `hal_espressif` patch), and SC pairing now completes. Legacy-pairing devices were unaffected and continue to work. Thanks @seagull9000.\r\n\r\n## Other fixes and improvements\r\n\r\n- **Fixed: GPS always-on on a freshly flashed companion** — a new install would default `gps_interval` to 0 (always-on) instead of the intended 5-minute duty cycle, causing the \n…",
          "notesHtml": "<h1>ZephCore v1.16.3-zephyr</h1>\n<blockquote>\n<p>(re-re-re-release(last time I swear) with the \"smearing fix on eink after the full update\" and \"automount error on a freshly formatted node\")</p>\n</blockquote>\n<blockquote>\n<p>[!IMPORTANT]</p>\n<h2>Before you upgrade</h2>\n<p><strong>Updating from v1.16.2</strong> — clean flash, no re-bond required, bonds survive.</p>\n<p><strong>Updating from v1.16.1 or older</strong> — flash the firmware; the firmware detects the old installation on first boot and clears the BLE bond storage automatically. Your identity, contacts, channels, and prefs are preserved. You will need to <strong>re-bond</strong> your phone/desktop once (old pairings were stored in a different location that v1.16.2 moved away from). No formatter tool required.</p>\n<p><strong>Coming from Arduino MeshCore</strong> — flash the firmware; it detects the incompatible filesystem on first boot and formats automatically. Everything starts fresh (new identity, clean storage). No formatter tool required.</p>\n<p>Take this with a grain of salt tho… try the formatters if anything anomalous happens with your node.</p>\n</blockquote>\n<hr />\n<p>This is a GPS-focused release: it stops a battery-killing bug on GPS trackers, puts the GPS duty cycle under your control, and follows up the v1.16.2 ESP32 pairing work with a fix for recent Android phones.</p>\n<h2>Highlights</h2>\n<h3>Fixed: ThinkNode M1 draining its battery in a day</h3>\n<p>On the ThinkNode M1, the GPS module was never actually powered down between fixes — the reset line was mislabeled in the board definition and held permanently released, so the receiver kept drawing current even when the firmware thought it was asleep. A full battery could disappear in roughly a day with GPS enabled.</p>\n<p>The M1 now asserts the GPS hardware reset on standby, so the GPS genuinely stops between fixes. If you run an M1 with GPS on, this is the fix you want.</p>\n<h3>New: configurable GPS duty cycle — <code>set gps duty &lt;seconds&gt;</code></h3>\n<p>You can now decide how your node handles GPS, instead of it being baked in:</p>\n<ul>\n<li><strong><code>set gps duty &lt;seconds&gt;</code></strong> — how long the GPS sleeps between fixes. Persists to flash and applies immediately.</li>\n<li><strong><code>set gps duty 0</code></strong> — <strong>always-on</strong>: the GPS never sleeps. It streams fresh fixes (so telemetry is always current) and stays on long enough to download a full almanac.</li>\n<li><strong><code>set gps duty default</code></strong> — reset to the role default.</li>\n<li><strong><code>get gps duty</code></strong> — show the now-effective interval.</li>\n</ul>\n<p>This unifies repeaters and companions behind one knob. <strong>Repeaters default to 48 h</strong> (GPS wakes only for periodic time-sync) and <strong>companions to 5 minutes</strong> — both now adjustable. Existing repeaters are migrated automatically; nothing to do.</p>\n<blockquote>\n<p>Bad input is rejected with a usage hint, and the value is clamped to a sane range (10 s … 1 week, or 0 for always-on).</p>\n</blockquote>\n<h3>Fixed: GPS no longer pins itself on waiting for a first fix</h3>\n<p>Previously, after enabling GPS a companion would keep the receiver powered <strong>indefinitely</strong> until it got its first fix — so a node left somewhere without sky view (indoors, in a bag) could quietly drain its battery forever. The first cold-start acquisition is now bounded (5 minutes by default, enough for a genuine cold start), after which the node drops into its normal duty cycle whether or not it got a fix.</p>\n<h3>Fixed: ESP32 Secure Connections pairing (Pixel 7 / recent Android)</h3>\n<p>Following the v1.16.2 ESP32 pairing fix, SC-capable centrals — notably recent Android phones like the Pixel 7 — still failed to bond: the controller's encryption table was left uninitialized because the relevant code was guarded on an ESP-IDF symbol that never exists in a Zephyr build, so the link dropped with a MIC failure at encryption start. The guard is corrected (carried as a managed <code>hal_espressif</code> patch), and SC pairing now completes. Legacy-pairing devices were unaffected and continue to work. Thanks @seagull9000.</p>\n<h2>Other fixes and improvements</h2>\n<ul>\n<li><strong>Fixed: GPS always-on on a freshly flashed companion</strong> — a new install would default <code>gps_interval</code> to 0 (always-on) instead of the intended 5-minute duty cycle, causing the \n…</li>\n</ul>\n"
        },
        {
          "version": "v20260616.202853",
          "name": "Firmware v20260616.202853",
          "datetime": "2026-06-16T20:29:09Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260616.202853",
          "prerelease": false,
          "notes": "# ZephCore v1.16.2-zephyr\r\n\r\n> [!IMPORTANT]\r\n> ## Before you upgrade — please read\r\n>\r\n> This release changes where devices store their BLE pairing data. The change affects **all platforms**, but the upgrade steps differ:\r\n>\r\n> **All boards (nRF52 *and* ESP32): you must re-bond.** Existing phone/desktop pairings will not carry over. After flashing, remove the old pairing from your device's Bluetooth settings (and from the ZephCore app), then pair again from scratch.\r\n>\r\n> nRF **should** update cleanly, but I recommend doing a flash erase + flash fw + import backup to be absolutely sure. Formatters can be found in the repo's [formatter folder](https://github.com/liquidraver/ZephCore/tree/master/formatter). Check your softdevice version before using one.\r\n\r\n---\r\n\r\n## Highlights\r\n\r\n### Critical fix: ESP32 Bluetooth pairing restored\r\nOn the updated Zephyr 4.4.1 base, ESP32 boards could advertise but **never completed pairing** — the Espressif Bluetooth controller would assert the moment a phone began to pair. This release restores the controller's link-layer encryption so pairing works again. If you have an ESP32-based node (Heltec, XIAO, Station G2, T-Beam, etc.), this is the fix you've been waiting for.\r\n\r\nAdditionally, **Android \"connect from app\" now works on ESP32.** Advertising now always exposes the stable identity address, so the Android companion app's in-app connect flow succeeds while iOS pairing continues to work.\r\n\r\n### BLE pairing data moved to its own storage area\r\nBluetooth bonds previously shared the same filesystem as your identity, preferences, and contacts. They now live in a dedicated, isolated storage partition (NVS) on **both nRF52 and ESP32**. This means a busy pairing store can no longer corrupt your contacts or settings, and pairing writes never touch your user data.\r\n\r\nA factory reset (`erase`) now also clears stored BLE bonds, then reboots automatically so everything comes back up clean — previously bonds could survive an erase.\r\n\r\n### New board: Heltec Wireless Tracker V1.1 (ESP32-S3 + SX1262), thanks to @seagull9000\r\nFull support for the Heltec Wireless Tracker V1.1 companion (ESP32-S3 + SX1262 radio + ST7735R TFT + UC6580 GPS), including:\r\n- Correct battery ADC routing (avoids a wiring conflict in the upstream board definition that otherwise broke all LoRa SPI reads)\r\n- Battery voltage/percentage readings\r\n- Onboard GNSS\r\n- Status-LED heartbeat\r\n- OLED/TFT display and BLE companion transport\r\n\r\n\r\n### New board: LilyGo T-Beam v1.2 (SX1262)\r\nFull support for the classic-ESP32 LilyGo T-Beam v1.2 with the SX1262 radio, including:\r\n- AXP2101 power management (LoRa + GPS rails brought up automatically at boot)\r\n- **Battery fuel-gauge readings** over I2C — accurate battery voltage and percentage, even though this board has no battery ADC\r\n- Onboard GNSS (NEO-6M / NEO-M8N)\r\n- The user button wired up (short press = page/select, long press = action)\r\n- OLED display, BLE companion transport, and CLI-based repeater mode\r\n\r\n> Note: classic-ESP32 repeaters (e.g. T-Beam) run CLI-only and do not include WiFi-AP OTA — the WiFi driver buffers plus OTA heap don't fit the classic ESP32's RAM. ESP32-S3 / C-series repeaters keep WiFi OTA.\r\n\r\n### E-paper anti-ghosting\r\nE-paper displays now perform a periodic full refresh (every 8 partial updates by default) to clear the faint \"ghost\" images that build up where text changes most often, like the status bar. The interval is configurable build-time, and the feature is automatically ignored on OLED/TFT screens that don't ghost.\r\n\r\n### More reliable companion connection (Linux / native transport)\r\nThe native TCP transport now applies the same congestion control already used over Bluetooth. Instead of silently dropping data when the connection is briefly saturated (for example, an incoming message arriving during a large contact/channel import), it now back-pressures and retries, and important protocol responses are never dropped. A stalled peer that stops reading is cleanly dis\n…",
          "notesHtml": "<h1>ZephCore v1.16.2-zephyr</h1>\n<blockquote>\n<p>[!IMPORTANT]</p>\n<h2>Before you upgrade — please read</h2>\n<p>This release changes where devices store their BLE pairing data. The change affects <strong>all platforms</strong>, but the upgrade steps differ:</p>\n<p><strong>All boards (nRF52 <em>and</em> ESP32): you must re-bond.</strong> Existing phone/desktop pairings will not carry over. After flashing, remove the old pairing from your device's Bluetooth settings (and from the ZephCore app), then pair again from scratch.</p>\n<p>nRF <strong>should</strong> update cleanly, but I recommend doing a flash erase + flash fw + import backup to be absolutely sure. Formatters can be found in the repo's <a href=\"https://github.com/liquidraver/ZephCore/tree/master/formatter\" target=\"_blank\" rel=\"noopener noreferrer\">formatter folder</a>. Check your softdevice version before using one.</p>\n</blockquote>\n<hr />\n<h2>Highlights</h2>\n<h3>Critical fix: ESP32 Bluetooth pairing restored</h3>\n<p>On the updated Zephyr 4.4.1 base, ESP32 boards could advertise but <strong>never completed pairing</strong> — the Espressif Bluetooth controller would assert the moment a phone began to pair. This release restores the controller's link-layer encryption so pairing works again. If you have an ESP32-based node (Heltec, XIAO, Station G2, T-Beam, etc.), this is the fix you've been waiting for.</p>\n<p>Additionally, <strong>Android \"connect from app\" now works on ESP32.</strong> Advertising now always exposes the stable identity address, so the Android companion app's in-app connect flow succeeds while iOS pairing continues to work.</p>\n<h3>BLE pairing data moved to its own storage area</h3>\n<p>Bluetooth bonds previously shared the same filesystem as your identity, preferences, and contacts. They now live in a dedicated, isolated storage partition (NVS) on <strong>both nRF52 and ESP32</strong>. This means a busy pairing store can no longer corrupt your contacts or settings, and pairing writes never touch your user data.</p>\n<p>A factory reset (<code>erase</code>) now also clears stored BLE bonds, then reboots automatically so everything comes back up clean — previously bonds could survive an erase.</p>\n<h3>New board: Heltec Wireless Tracker V1.1 (ESP32-S3 + SX1262), thanks to @seagull9000</h3>\n<p>Full support for the Heltec Wireless Tracker V1.1 companion (ESP32-S3 + SX1262 radio + ST7735R TFT + UC6580 GPS), including:</p>\n<ul>\n<li>Correct battery ADC routing (avoids a wiring conflict in the upstream board definition that otherwise broke all LoRa SPI reads)</li>\n<li>Battery voltage/percentage readings</li>\n<li>Onboard GNSS</li>\n<li>Status-LED heartbeat</li>\n<li>OLED/TFT display and BLE companion transport</li>\n</ul>\n<h3>New board: LilyGo T-Beam v1.2 (SX1262)</h3>\n<p>Full support for the classic-ESP32 LilyGo T-Beam v1.2 with the SX1262 radio, including:</p>\n<ul>\n<li>AXP2101 power management (LoRa + GPS rails brought up automatically at boot)</li>\n<li><strong>Battery fuel-gauge readings</strong> over I2C — accurate battery voltage and percentage, even though this board has no battery ADC</li>\n<li>Onboard GNSS (NEO-6M / NEO-M8N)</li>\n<li>The user button wired up (short press = page/select, long press = action)</li>\n<li>OLED display, BLE companion transport, and CLI-based repeater mode</li>\n</ul>\n<blockquote>\n<p>Note: classic-ESP32 repeaters (e.g. T-Beam) run CLI-only and do not include WiFi-AP OTA — the WiFi driver buffers plus OTA heap don't fit the classic ESP32's RAM. ESP32-S3 / C-series repeaters keep WiFi OTA.</p>\n</blockquote>\n<h3>E-paper anti-ghosting</h3>\n<p>E-paper displays now perform a periodic full refresh (every 8 partial updates by default) to clear the faint \"ghost\" images that build up where text changes most often, like the status bar. The interval is configurable build-time, and the feature is automatically ignored on OLED/TFT screens that don't ghost.</p>\n<h3>More reliable companion connection (Linux / native transport)</h3>\n<p>The native TCP transport now applies the same congestion control already used over Bluetooth. Instead of silently dropping data when the connection is briefly saturated (for example, an incoming message arriving during a large contact/channel import), it now back-pressures and retries, and important protocol responses are never dropped. A stalled peer that stops reading is cleanly dis\n…</p>\n"
        },
        {
          "version": "v20260613.205222",
          "name": "Firmware v20260613.205222",
          "datetime": "2026-06-13T20:52:38Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260613.205222",
          "prerelease": false,
          "notes": "DO NOT DOWNLOAD THIS RELEASE JUST TO UPDATE, YOU NEED A FLASH ERASE FOR IT TO WORK PROPERLY.\r\nI'LL RE-RELEASE IT SOON AS I CATCH THE BUG!\r\n(it seems devices with multiple bondings are affected only)\r\n\r\nSo if something is broken: delete bond, erase flash and try again.\r\n\r\n\r\n\r\n\r\n\r\n## What's New\r\n\r\n- **RX duty cycle (power saving) reworked** — now properly tested against the datasheet, gives ~40-55% radio-off time with no packet loss on up-to-date nodes. Toggle with `set rxduty on/off`. (Mixed old/new meshes: keep it off on infra nodes for now. Needs preamble 32 on adjacent nodes)\r\n- **Joystick UI now shows accented characters** (Hungarian/Slovak/Czech/Polish/etc. names display correctly), emojis are stripped instead of showing garbage. Unlock gesture changed to Left -> OK -> Right (easier/faster than the old Back-OK-Back).\r\n- `set rxduty` / `set radio.rxgain` now also accept `on` / `off`, not just `1`/`0`.\r\n\r\n## Fixes\r\n\r\n- WisMesh Tag battery percentage was reading high — calibration corrected.\r\n- RTC clock could get permanently stuck blank after battery loss — now recovers and re-syncs.\r\n- Clock source indicator (GPS/App/Local) and display now update correctly/immediately.\r\n- Auto-shutdown no longer triggers on a brief voltage dip during transmit (needs 3 low readings in a row now).\r\n- Fixed a race in MQTT \"online\" status reporting on repeaters/observers.\r\n- Several small crash/overflow hardening fixes from ongoing code audit (no user-visible behavior change).",
          "notesHtml": "<p>DO NOT DOWNLOAD THIS RELEASE JUST TO UPDATE, YOU NEED A FLASH ERASE FOR IT TO WORK PROPERLY.\nI'LL RE-RELEASE IT SOON AS I CATCH THE BUG!\n(it seems devices with multiple bondings are affected only)</p>\n<p>So if something is broken: delete bond, erase flash and try again.</p>\n<h2>What's New</h2>\n<ul>\n<li><strong>RX duty cycle (power saving) reworked</strong> — now properly tested against the datasheet, gives ~40-55% radio-off time with no packet loss on up-to-date nodes. Toggle with <code>set rxduty on/off</code>. (Mixed old/new meshes: keep it off on infra nodes for now. Needs preamble 32 on adjacent nodes)</li>\n<li><strong>Joystick UI now shows accented characters</strong> (Hungarian/Slovak/Czech/Polish/etc. names display correctly), emojis are stripped instead of showing garbage. Unlock gesture changed to Left -&gt; OK -&gt; Right (easier/faster than the old Back-OK-Back).</li>\n<li><code>set rxduty</code> / <code>set radio.rxgain</code> now also accept <code>on</code> / <code>off</code>, not just <code>1</code>/<code>0</code>.</li>\n</ul>\n<h2>Fixes</h2>\n<ul>\n<li>WisMesh Tag battery percentage was reading high — calibration corrected.</li>\n<li>RTC clock could get permanently stuck blank after battery loss — now recovers and re-syncs.</li>\n<li>Clock source indicator (GPS/App/Local) and display now update correctly/immediately.</li>\n<li>Auto-shutdown no longer triggers on a brief voltage dip during transmit (needs 3 low readings in a row now).</li>\n<li>Fixed a race in MQTT \"online\" status reporting on repeaters/observers.</li>\n<li>Several small crash/overflow hardening fixes from ongoing code audit (no user-visible behavior change).</li>\n</ul>\n"
        },
        {
          "version": "v20260608.105434",
          "name": "Firmware v20260608.105434",
          "datetime": "2026-06-08T10:54:48Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260608.105434",
          "prerelease": false,
          "notes": "## New\r\n\r\n### Hardware RTC auto-discovery\r\nOut-of-the-box nodes with a battery/cap-backed I2C RTC (**DS3231, PCF8563,\r\nRV3028, RX8130CE**) now restore the clock at boot — shown tagged **`L`** until\r\nthe next GPS / app / CLI sync — and write the time back on every sync so it\r\nsurvives power-off. Boards opt in via `boards/common/rtc-i2c.dtsi`; on boards\r\nwithout it, this compiles to nothing.\r\n\r\n> First wired up on **LilyGo T-Echo** and **ThinkNode M1**.\r\n\r\n### Buttonless BLE DFU (legacy Nordic/Adafruit OTA jump)\r\nA paired phone can now trigger the jump into the bootloader's BLE OTA mode\r\ndirectly from the DFU Firmware Upgrade app — no button press needed (**nRF52 only**). The\r\nservice exposes the full legacy DFU characteristic set (Control Point, Packet,\r\nRevision) so iOS's DFU library can discover and identify the device correctly.\r\n\r\nCompanion needs disconnecting from MeshCore app first!\r\n\r\nThis was only tested with a handful of nodes and an iOS! This change can introduce errors in other phones I'm not aware of. A BLE bond delete + re-pair should solve it.\r\n\r\n### BLE TX power bumped to +8 dBm\r\nRaised from **+4 dBm → +8 dBm**, the max output the nRF52840 / nRF54L\r\nhigh-power radio front-end supports — better range and link margin for the\r\ncompanion connection.\r\nThis is still under test, but should not cause excessive/noticeable battery drain.\r\n\r\n### MIT license formalized\r\nAdded `zephcore/LICENSE` (MIT, same as upstream MeshCore) and flipped the\r\n`SPDX-License-Identifier` header across the source tree from `Apache-2.0` to\r\n`MIT`. Vendored dependencies that carry their own compatible licenses\r\n(Monocypher, Zephyr patches) are noted at the bottom of the license file.\r\n\r\n## Fixed\r\n\r\n- **Companion startup races** — initial-advert handling and contact-table\r\n  iteration were running on `sysworkq` while the main thread mutated the same\r\n  mesh/contact state, a race that could corrupt state or wedge the contact\r\n  dump. Both now run on the main thread, driven through the event loop\r\n  (`MESH_EVENT_CONTACT_ITER`), same as the rest of the mesh state machine.\r\n\r\n- **Hardware-RTC writes no longer race the main loop** — `zephcore_rtc_save()`\r\n  is now routed through the same deferred-to-main-thread mechanism as prefs\r\n  flushes (`MESH_EVENT_RTC_SAVE`). GPS fixes land on the GNSS modem-chat thread\r\n  and just stash the latest epoch; the actual blocking I2C write happens on the\r\n  main thread, coalescing multiple pending fixes into one save.\r\n\r\n- **`MAX_ANON_CONTACTS` cap fixed** — transient/anon contact slots (e.g.\r\n  created for BLE direct-message lookups to non-contact pubkeys) were being\r\n  capped by `MAX_CONTACTS` instead of their own larger allotment, causing\r\n  premature slot exhaustion/eviction.\r\n\r\n- **XIAO nRF54L15 build fixed.**\r\n\r\n## Internals\r\n\r\n- **ZephyrCompanionUSB** — assembled V3 frames now wake the main thread via\r\n  `k_event` instead of `k_work_submit` on `sysworkq`, matching the BLE RX path\r\n  and removing a parse-vs-`loop()` race.\r\n\r\n- **Buttonless DFU** now hard-depends on `SOC_SERIES_NRF52` (was a soft\r\n  `default y`). Other nRF52-only paths (bootloader-version scan, VBUS detect,\r\n  formatter/updater tools) were cleaned up to drop the redundant\r\n  `SOC_SERIES_NRF52X` checks.\r\n\r\n- **West Update** — Zephyr updated to 4.4.1-rc1",
          "notesHtml": "<h2>New</h2>\n<h3>Hardware RTC auto-discovery</h3>\n<p>Out-of-the-box nodes with a battery/cap-backed I2C RTC (<strong>DS3231, PCF8563,\nRV3028, RX8130CE</strong>) now restore the clock at boot — shown tagged <strong><code>L</code></strong> until\nthe next GPS / app / CLI sync — and write the time back on every sync so it\nsurvives power-off. Boards opt in via <code>boards/common/rtc-i2c.dtsi</code>; on boards\nwithout it, this compiles to nothing.</p>\n<blockquote>\n<p>First wired up on <strong>LilyGo T-Echo</strong> and <strong>ThinkNode M1</strong>.</p>\n</blockquote>\n<h3>Buttonless BLE DFU (legacy Nordic/Adafruit OTA jump)</h3>\n<p>A paired phone can now trigger the jump into the bootloader's BLE OTA mode\ndirectly from the DFU Firmware Upgrade app — no button press needed (<strong>nRF52 only</strong>). The\nservice exposes the full legacy DFU characteristic set (Control Point, Packet,\nRevision) so iOS's DFU library can discover and identify the device correctly.</p>\n<p>Companion needs disconnecting from MeshCore app first!</p>\n<p>This was only tested with a handful of nodes and an iOS! This change can introduce errors in other phones I'm not aware of. A BLE bond delete + re-pair should solve it.</p>\n<h3>BLE TX power bumped to +8 dBm</h3>\n<p>Raised from <strong>+4 dBm → +8 dBm</strong>, the max output the nRF52840 / nRF54L\nhigh-power radio front-end supports — better range and link margin for the\ncompanion connection.\nThis is still under test, but should not cause excessive/noticeable battery drain.</p>\n<h3>MIT license formalized</h3>\n<p>Added <code>zephcore/LICENSE</code> (MIT, same as upstream MeshCore) and flipped the\n<code>SPDX-License-Identifier</code> header across the source tree from <code>Apache-2.0</code> to\n<code>MIT</code>. Vendored dependencies that carry their own compatible licenses\n(Monocypher, Zephyr patches) are noted at the bottom of the license file.</p>\n<h2>Fixed</h2>\n<ul>\n<li><p><strong>Companion startup races</strong> — initial-advert handling and contact-table\niteration were running on <code>sysworkq</code> while the main thread mutated the same\nmesh/contact state, a race that could corrupt state or wedge the contact\ndump. Both now run on the main thread, driven through the event loop\n(<code>MESH_EVENT_CONTACT_ITER</code>), same as the rest of the mesh state machine.</p>\n</li>\n<li><p><strong>Hardware-RTC writes no longer race the main loop</strong> — <code>zephcore_rtc_save()</code>\nis now routed through the same deferred-to-main-thread mechanism as prefs\nflushes (<code>MESH_EVENT_RTC_SAVE</code>). GPS fixes land on the GNSS modem-chat thread\nand just stash the latest epoch; the actual blocking I2C write happens on the\nmain thread, coalescing multiple pending fixes into one save.</p>\n</li>\n<li><p><strong><code>MAX_ANON_CONTACTS</code> cap fixed</strong> — transient/anon contact slots (e.g.\ncreated for BLE direct-message lookups to non-contact pubkeys) were being\ncapped by <code>MAX_CONTACTS</code> instead of their own larger allotment, causing\npremature slot exhaustion/eviction.</p>\n</li>\n<li><p><strong>XIAO nRF54L15 build fixed.</strong></p>\n</li>\n</ul>\n<h2>Internals</h2>\n<ul>\n<li><p><strong>ZephyrCompanionUSB</strong> — assembled V3 frames now wake the main thread via\n<code>k_event</code> instead of <code>k_work_submit</code> on <code>sysworkq</code>, matching the BLE RX path\nand removing a parse-vs-<code>loop()</code> race.</p>\n</li>\n<li><p><strong>Buttonless DFU</strong> now hard-depends on <code>SOC_SERIES_NRF52</code> (was a soft\n<code>default y</code>). Other nRF52-only paths (bootloader-version scan, VBUS detect,\nformatter/updater tools) were cleaned up to drop the redundant\n<code>SOC_SERIES_NRF52X</code> checks.</p>\n</li>\n<li><p><strong>West Update</strong> — Zephyr updated to 4.4.1-rc1</p>\n</li>\n</ul>\n"
        },
        {
          "version": "v20260606.150211",
          "name": "Firmware v20260606.150211",
          "datetime": "2026-06-06T15:02:26Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260606.150211",
          "prerelease": false,
          "notes": "Synced with upstream vanilla MeshCore v1.16.0",
          "notesHtml": "<p>Synced with upstream vanilla MeshCore v1.16.0</p>\n"
        },
        {
          "version": "v20260605.132226",
          "name": "Firmware v20260605.132226",
          "datetime": "2026-06-05T13:22:43Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260605.132226",
          "prerelease": false,
          "notes": "## New\r\n\r\n**USB serial console for companions**\r\nConfigure companion devices (e.g. Wio Tracker L1) by typing commands over USB, no phone app needed.\r\nWorks in the flasher.meshcore.io serial console (or any terminal), just like the repeater CLI. Stays out of the way of the Bluetooth/USB app — only one connection is active at a time.\r\n\r\n**Battery gauge calibration (`adc.multiplier`)**\r\nCorrect the battery voltage reading so the % is accurate for your device:\r\n- `set adc.multiplier full` — calibrate at full charge (easiest)\r\n- `set adc.multiplier target <mV>` — calibrate to a multimeter reading (most accurate)\r\n- `set adc.multiplier 0` — reset to default\r\n- `get adc.multiplier` — show current\r\n\r\n**Per-device battery curves**\r\nBattery % now uses a real, device-specific voltage curve instead of a rough estimate, so readings are far more accurate.\r\nIncluded for Wio Tracker L1, T1000-E, SenseCAP Solar, ThinkNode M6, and RAK WisMesh Tag (others use a sensible default).\r\n\r\n**Low-battery auto-shutdown**\r\nBattery-powered companions now power down automatically when the cell runs low (default 3.3 V, ~10% on the new curves) to protect it from over-discharge.\r\nShows a brief \"Low Battery — Shutting Down\" notice first (3 s on OLED; e-paper just leaves it on screen), and is skipped while charging or on USB power so it never cuts out a plugged-in device.\r\nOn by default for nRF52 companions.\r\nTune it over the USB console:\r\n- `set autoshutdown <mV>` — set the cutoff (1–5000 mV)\r\n- `set autoshutdown 0` — turn it off\r\n- `get autoshutdown` — show current\r\n\r\n**Clock source indicator**\r\nThe time in the top bar now shows a tiny letter telling you where it was last synced from: **G** (GPS), **A** (phone app), **N** (network), or **L** (local).\r\nIf the device hasn't heard from GPS or the app in the last 12 hours, it falls back to **L** — the clock is just free-running on the device's own crystal at that point (drift is only a few seconds a day, so it stays accurate, but you know it isn't being checked against an outside source).\r\nAfter a restart it shows **L** until the first sync.\r\n\r\n## Fixed\r\n\r\n**Device name no longer overlaps the clock**\r\nOn the home screen, a long device name used to run underneath the time and battery in the top bar, making both unreadable.\r\nThe name is now trimmed to fit the space before the clock, on any screen size.",
          "notesHtml": "<h2>New</h2>\n<p><strong>USB serial console for companions</strong>\nConfigure companion devices (e.g. Wio Tracker L1) by typing commands over USB, no phone app needed.\nWorks in the flasher.meshcore.io serial console (or any terminal), just like the repeater CLI. Stays out of the way of the Bluetooth/USB app — only one connection is active at a time.</p>\n<p><strong>Battery gauge calibration (<code>adc.multiplier</code>)</strong>\nCorrect the battery voltage reading so the % is accurate for your device:</p>\n<ul>\n<li><code>set adc.multiplier full</code> — calibrate at full charge (easiest)</li>\n<li><code>set adc.multiplier target &lt;mV&gt;</code> — calibrate to a multimeter reading (most accurate)</li>\n<li><code>set adc.multiplier 0</code> — reset to default</li>\n<li><code>get adc.multiplier</code> — show current</li>\n</ul>\n<p><strong>Per-device battery curves</strong>\nBattery % now uses a real, device-specific voltage curve instead of a rough estimate, so readings are far more accurate.\nIncluded for Wio Tracker L1, T1000-E, SenseCAP Solar, ThinkNode M6, and RAK WisMesh Tag (others use a sensible default).</p>\n<p><strong>Low-battery auto-shutdown</strong>\nBattery-powered companions now power down automatically when the cell runs low (default 3.3 V, ~10% on the new curves) to protect it from over-discharge.\nShows a brief \"Low Battery — Shutting Down\" notice first (3 s on OLED; e-paper just leaves it on screen), and is skipped while charging or on USB power so it never cuts out a plugged-in device.\nOn by default for nRF52 companions.\nTune it over the USB console:</p>\n<ul>\n<li><code>set autoshutdown &lt;mV&gt;</code> — set the cutoff (1–5000 mV)</li>\n<li><code>set autoshutdown 0</code> — turn it off</li>\n<li><code>get autoshutdown</code> — show current</li>\n</ul>\n<p><strong>Clock source indicator</strong>\nThe time in the top bar now shows a tiny letter telling you where it was last synced from: <strong>G</strong> (GPS), <strong>A</strong> (phone app), <strong>N</strong> (network), or <strong>L</strong> (local).\nIf the device hasn't heard from GPS or the app in the last 12 hours, it falls back to <strong>L</strong> — the clock is just free-running on the device's own crystal at that point (drift is only a few seconds a day, so it stays accurate, but you know it isn't being checked against an outside source).\nAfter a restart it shows <strong>L</strong> until the first sync.</p>\n<h2>Fixed</h2>\n<p><strong>Device name no longer overlaps the clock</strong>\nOn the home screen, a long device name used to run underneath the time and battery in the top bar, making both unreadable.\nThe name is now trimmed to fit the space before the clock, on any screen size.</p>\n"
        },
        {
          "version": "v20260603.123327",
          "name": "Firmware v20260603.123327",
          "datetime": "2026-06-03T12:33:43Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260603.123327",
          "prerelease": false,
          "notes": "(Re-Released because of native linux bugfixes)\r\n\r\nNew\r\n\r\n- Room Server (BBS) role (no auto-build, no repeater function)\r\n- GAT562 30S Mesh Kit board support (nRF52840 + SX1262, RAK4631 core, 30 dBm PA) — one image for both the full kit and the screenless solar repeater.\r\n- Production is now the default build — no more prod.conf; debug.conf is the opt-in for logging.\r\n- USB companion decoupled from logging — CDC ACM transport now compiles independently of CONFIG_LOG. (companions are USB+BLE hybrid from now, only one type can be connected at a time)\r\n- Linux native target — built and shipped as executables (companion + repeater).\r\n- Battery reading should be more precise with board specific curve support and a standard lipo curve for devices that does not have any data on the internet about it's curve\r\n\r\nBug Fixes\r\n\r\n- USB cable-yank no longer strands the companion on USB and blocks BLE until reboot.\r\n- BLE/USB transport handoff reworked to first-come-first-served, made thread-safe.\r\n- Zero-delay direct/zero-hop sends over BLE/USB no longer stall.\r\n- Channel reply from the Unread screen now sends instead of silently failing.\r\n- Repeater anon reply with a malformed return path now floods (safe fallback) instead of emitting a corrupt direct packet.\r\n- Header-error frames now counted as receive errors (and no more zombie packet receptions triggered)\r\n- Airtime/LDRO estimate fixed to track the driver across every SF/BW.\r\n- RNG seed derivation hardened against hash failure.\r\n\r\nInternals\r\n\r\n- Crypto: orlp/ed25519 → Monocypher 4.0.2 — audited, single-file. Existing identities load/sign/verify unchanged — no re-key, no migration, full wire compatibility.\r\n- Bumped west / pinned Zephyr tree.\r\n- Synced with vanilla MeshCore dev.\r\n- Split RepeaterMesh into Uplink + RegionCLI; deduped app-layer response/telemetry/JSON builders.\r\n- Simplified the packet manager, dispatcher, and radio config paths.",
          "notesHtml": "<p>(Re-Released because of native linux bugfixes)</p>\n<p>New</p>\n<ul>\n<li>Room Server (BBS) role (no auto-build, no repeater function)</li>\n<li>GAT562 30S Mesh Kit board support (nRF52840 + SX1262, RAK4631 core, 30 dBm PA) — one image for both the full kit and the screenless solar repeater.</li>\n<li>Production is now the default build — no more prod.conf; debug.conf is the opt-in for logging.</li>\n<li>USB companion decoupled from logging — CDC ACM transport now compiles independently of CONFIG_LOG. (companions are USB+BLE hybrid from now, only one type can be connected at a time)</li>\n<li>Linux native target — built and shipped as executables (companion + repeater).</li>\n<li>Battery reading should be more precise with board specific curve support and a standard lipo curve for devices that does not have any data on the internet about it's curve</li>\n</ul>\n<p>Bug Fixes</p>\n<ul>\n<li>USB cable-yank no longer strands the companion on USB and blocks BLE until reboot.</li>\n<li>BLE/USB transport handoff reworked to first-come-first-served, made thread-safe.</li>\n<li>Zero-delay direct/zero-hop sends over BLE/USB no longer stall.</li>\n<li>Channel reply from the Unread screen now sends instead of silently failing.</li>\n<li>Repeater anon reply with a malformed return path now floods (safe fallback) instead of emitting a corrupt direct packet.</li>\n<li>Header-error frames now counted as receive errors (and no more zombie packet receptions triggered)</li>\n<li>Airtime/LDRO estimate fixed to track the driver across every SF/BW.</li>\n<li>RNG seed derivation hardened against hash failure.</li>\n</ul>\n<p>Internals</p>\n<ul>\n<li>Crypto: orlp/ed25519 → Monocypher 4.0.2 — audited, single-file. Existing identities load/sign/verify unchanged — no re-key, no migration, full wire compatibility.</li>\n<li>Bumped west / pinned Zephyr tree.</li>\n<li>Synced with vanilla MeshCore dev.</li>\n<li>Split RepeaterMesh into Uplink + RegionCLI; deduped app-layer response/telemetry/JSON builders.</li>\n<li>Simplified the packet manager, dispatcher, and radio config paths.</li>\n</ul>\n"
        },
        {
          "version": "v20260528.133858",
          "name": "Firmware v20260528.133858",
          "datetime": "2026-05-28T13:39:14Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260528.133858",
          "prerelease": false,
          "notes": "Security\r\n- Hardened login password comparison against timing side-channel attacks\r\n- Fixed weak entropy at first boot — initial device identity is now properly random\r\n- Fixed 3 RNG edge cases that could produce predictable output under certain startup conditions\r\n\r\nBug Fixes\r\n- Fixed repeater + observer mode combo not working together\r\n- USB: unified CDC ACM init across companion and repeater, removed unnecessary boot delays\r\n\r\nNew\r\n- Native Linux target — initial port for desktop testing",
          "notesHtml": "<p>Security</p>\n<ul>\n<li>Hardened login password comparison against timing side-channel attacks</li>\n<li>Fixed weak entropy at first boot — initial device identity is now properly random</li>\n<li>Fixed 3 RNG edge cases that could produce predictable output under certain startup conditions</li>\n</ul>\n<p>Bug Fixes</p>\n<ul>\n<li>Fixed repeater + observer mode combo not working together</li>\n<li>USB: unified CDC ACM init across companion and repeater, removed unnecessary boot delays</li>\n</ul>\n<p>New</p>\n<ul>\n<li>Native Linux target — initial port for desktop testing</li>\n</ul>\n"
        },
        {
          "version": "v20260522.140428",
          "name": "Firmware v20260522.140428",
          "datetime": "2026-05-22T14:04:43Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260522.140428",
          "prerelease": false,
          "notes": "Wio Tracker — completely new joystick UI (thanks [@Calvario](https://github.com/Calvario)) — new screen lifecycle, DM retry, channel send with feedback, GPS screen with altitude, lock screen, time sync, path hash bytes setting, and more.\r\n\r\nHeltec T114 board support (thanks [@Calvario](https://github.com/Calvario)) — with and without screen.\r\n\r\nPSRAM activation on capable devices — enables OTA on boards that support it.\r\n\r\nSync with vanilla MeshCore dev\r\n\r\nBug Fixes\r\nBLE disabled state now correctly honoured — watchdog was silently re-enabling BLE on every housekeeping tick\r\nFixed out-of-bounds read in path-decoding (BLE + LoRa-anon paths)\r\nNull-termination fix in Add/Update Contact command\r\nFixed overflow frame being clobbered under BLE congestion\r\nFixed T114 long press\r\nSeveral BLE audit hardening fixes (error codes, length checks, buffer sizing)",
          "notesHtml": "<p>Wio Tracker — completely new joystick UI (thanks <a href=\"https://github.com/Calvario\" target=\"_blank\" rel=\"noopener noreferrer\">@Calvario</a>) — new screen lifecycle, DM retry, channel send with feedback, GPS screen with altitude, lock screen, time sync, path hash bytes setting, and more.</p>\n<p>Heltec T114 board support (thanks <a href=\"https://github.com/Calvario\" target=\"_blank\" rel=\"noopener noreferrer\">@Calvario</a>) — with and without screen.</p>\n<p>PSRAM activation on capable devices — enables OTA on boards that support it.</p>\n<p>Sync with vanilla MeshCore dev</p>\n<p>Bug Fixes\nBLE disabled state now correctly honoured — watchdog was silently re-enabling BLE on every housekeeping tick\nFixed out-of-bounds read in path-decoding (BLE + LoRa-anon paths)\nNull-termination fix in Add/Update Contact command\nFixed overflow frame being clobbered under BLE congestion\nFixed T114 long press\nSeveral BLE audit hardening fixes (error codes, length checks, buffer sizing)</p>\n"
        },
        {
          "version": "v20260514.205836",
          "name": "Firmware v20260514.205836",
          "datetime": "2026-05-14T20:58:46Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260514.205836",
          "prerelease": false,
          "notes": "- New experimental RX-busy latch: ZephCore now tracks an in-progress reception across the full packet, so the transmitter won't step on a packet that's already being decoded.\r\n- Improved CAD (Listen-Before-Talk) behavior: the radio re-enters listening mode faster between TX retries on busy channels, and a stuck channel-busy state recovers automatically instead of requiring a reset.\r\n- updated default prefs to advert less and loop detect moderate",
          "notesHtml": "<ul>\n<li>New experimental RX-busy latch: ZephCore now tracks an in-progress reception across the full packet, so the transmitter won't step on a packet that's already being decoded.</li>\n<li>Improved CAD (Listen-Before-Talk) behavior: the radio re-enters listening mode faster between TX retries on busy channels, and a stuck channel-busy state recovers automatically instead of requiring a reset.</li>\n<li>updated default prefs to advert less and loop detect moderate</li>\n</ul>\n"
        },
        {
          "version": "v20260511.125830",
          "name": "Firmware v20260511.125830",
          "datetime": "2026-05-11T12:58:40Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260511.125830",
          "prerelease": false,
          "notes": "- Channel deletion safety: fixed bug where deleting the public channel could wipe other channels after reboot.\r\n- LBT retry priority: preserved flood packet priority during LBT-based retransmissions.\r\n- CAD/LBT mode switching: fixed radio reconfiguration so mode changes are fully applied.\r\n- rx_boost init: set deterministic startup state to avoid undefined boot behavior.\r\n- Atomic contact saves (QSPI): contacts now use temp+sync+rename on external flash devices.\r\n- Atomic write refactor: unified temp-file atomic write flow used by datastore save paths.\r\n- promicro_sx1262 build support: fixed/added board build wiring and related project metadata.\r\n- Vanilla sync (CompanionMesh): aligned local logic with upstream baseline changes.\r\n- SX1262 patch updates: refined Zephyr SX126x native patch and related ignore rules.",
          "notesHtml": "<ul>\n<li>Channel deletion safety: fixed bug where deleting the public channel could wipe other channels after reboot.</li>\n<li>LBT retry priority: preserved flood packet priority during LBT-based retransmissions.</li>\n<li>CAD/LBT mode switching: fixed radio reconfiguration so mode changes are fully applied.</li>\n<li>rx_boost init: set deterministic startup state to avoid undefined boot behavior.</li>\n<li>Atomic contact saves (QSPI): contacts now use temp+sync+rename on external flash devices.</li>\n<li>Atomic write refactor: unified temp-file atomic write flow used by datastore save paths.</li>\n<li>promicro_sx1262 build support: fixed/added board build wiring and related project metadata.</li>\n<li>Vanilla sync (CompanionMesh): aligned local logic with upstream baseline changes.</li>\n<li>SX1262 patch updates: refined Zephyr SX126x native patch and related ignore rules.</li>\n</ul>\n"
        },
        {
          "version": "v20260507.103840",
          "name": "Firmware v20260507.103840",
          "datetime": "2026-05-07T10:38:49Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260507.103840",
          "prerelease": false,
          "notes": "In one of my ravings trying to shorten rx-rx and tx-rx path I accidentally disabled hardware CAD.\r\nThis release just does that: re-enables it.\r\n\r\nAlso added formatters for nRF here: https://github.com/liquidraver/ZephCore/tree/master/formatter\r\n\r\n\r\nHardware CAD test:\r\n\r\nNothing catched in that 2 symbol CAD check:\r\n\r\nsx126x_irq_work_handler: IRQ status: 0x0080\r\nsx126x_irq_work_handler: CAD done: free\r\nsx126x_irq_work_handler: IRQ status: 0x0001\r\nsx126x_handle_irq_tx_done: TX done\r\nlora_radio_base: TX complete, RX restarted\r\n\r\nSomething was in our channel during CAD check:\r\n\r\nsx126x_irq_work_handler: IRQ status: 0x0180←[0m\r\nsx126x_irq_work_handler: CAD done: activity←[0m\r\nsx126x_lora_send_async: LBT: channel busy←[0m\r\nlora_radio_base: hwSendAsync failed: -16←[0m\r\nzephcore_dispatcher: checkSend: startSendRaw failed! re-queuing delay=240\r\n....same goes on for 3-4 times\r\nthen:\r\nsx126x_irq_work_handler: IRQ status: 0x0080\r\nsx126x_irq_work_handler: CAD done: free\r\nsx126x_irq_work_handler: IRQ status: 0x0001\r\nsx126x_handle_irq_tx_done: TX done\r\nlora_radio_base: TX complete, RX restarted",
          "notesHtml": "<p>In one of my ravings trying to shorten rx-rx and tx-rx path I accidentally disabled hardware CAD.\nThis release just does that: re-enables it.</p>\n<p>Also added formatters for nRF here: <a href=\"https://github.com/liquidraver/ZephCore/tree/master/formatter\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/liquidraver/ZephCore/tree/master/formatter</a></p>\n<p>Hardware CAD test:</p>\n<p>Nothing catched in that 2 symbol CAD check:</p>\n<p>sx126x_irq_work_handler: IRQ status: 0x0080\nsx126x_irq_work_handler: CAD done: free\nsx126x_irq_work_handler: IRQ status: 0x0001\nsx126x_handle_irq_tx_done: TX done\nlora_radio_base: TX complete, RX restarted</p>\n<p>Something was in our channel during CAD check:</p>\n<p>sx126x_irq_work_handler: IRQ status: 0x0180←[0m\nsx126x_irq_work_handler: CAD done: activity←[0m\nsx126x_lora_send_async: LBT: channel busy←[0m\nlora_radio_base: hwSendAsync failed: -16←[0m\nzephcore_dispatcher: checkSend: startSendRaw failed! re-queuing delay=240\n....same goes on for 3-4 times\nthen:\nsx126x_irq_work_handler: IRQ status: 0x0080\nsx126x_irq_work_handler: CAD done: free\nsx126x_irq_work_handler: IRQ status: 0x0001\nsx126x_handle_irq_tx_done: TX done\nlora_radio_base: TX complete, RX restarted</p>\n"
        },
        {
          "version": "v20260506.102120",
          "name": "Firmware v20260506.102120",
          "datetime": "2026-05-06T10:21:30Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260506.102120",
          "prerelease": false,
          "notes": "- Duty cycling is now disabled by default. \r\n  Further research showed that preamble 16 is NOT enough for a reliable duty cycle in noisy environments, so we'll wait for most of the mesh switching to preamble 32 to test it further\r\n\r\n- SX driver had some serious issues with CAD so it is recommended to update to this version as soon as possible\r\n\r\n- GPS will not be disabled if no GNSS message comes in (on repeaters), that was a test-code that stuck",
          "notesHtml": "<ul>\n<li><p>Duty cycling is now disabled by default. \nFurther research showed that preamble 16 is NOT enough for a reliable duty cycle in noisy environments, so we'll wait for most of the mesh switching to preamble 32 to test it further</p>\n</li>\n<li><p>SX driver had some serious issues with CAD so it is recommended to update to this version as soon as possible</p>\n</li>\n<li><p>GPS will not be disabled if no GNSS message comes in (on repeaters), that was a test-code that stuck</p>\n</li>\n</ul>\n"
        },
        {
          "version": "v20260505.131914",
          "name": "Firmware v20260505.131914",
          "datetime": "2026-05-05T13:19:23Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260505.131914",
          "prerelease": false,
          "notes": "Kistarcsa-edition\r\n\r\nTested in the depths of the tarcsa-cauldron with weak/noisy/who-knows-whats-the-problem-of-that-heltecv3 repeater, optimized for the aforementioned use-case.\r\n\r\n- Duty cycle is 13/3 now. Slightly more battery consumption, but better RX error margin. No use for extra battery time if packets are lost in noisy/weak link environments.\r\n- hwconfig now has a fail-safe so no more edge-case unsaved radio settings\r\n- SX TX Ramp time increased to 800µs from 200µs. expect very heavy latency increase if you can sense time in a different way normal humans do! \r\n  (also expect cleaner spectral mask at 22 dBm. nobody cares about it, doesn't change anything in a meaningful way, but it's a playground, we optimize even things that doesn't really need optimizing)\r\n  (ask your favourite AI what are the benefits of 800µs vs 200µs if interested)\r\n- Companions had too much initial jitter with zero benefit, so it was tuned down to RNG20-150msec\r\n- Claude noticed some line ending stuff by itself, without asking, so I gave him credit (heh)",
          "notesHtml": "<p>Kistarcsa-edition</p>\n<p>Tested in the depths of the tarcsa-cauldron with weak/noisy/who-knows-whats-the-problem-of-that-heltecv3 repeater, optimized for the aforementioned use-case.</p>\n<ul>\n<li>Duty cycle is 13/3 now. Slightly more battery consumption, but better RX error margin. No use for extra battery time if packets are lost in noisy/weak link environments.</li>\n<li>hwconfig now has a fail-safe so no more edge-case unsaved radio settings</li>\n<li>SX TX Ramp time increased to 800µs from 200µs. expect very heavy latency increase if you can sense time in a different way normal humans do! \n(also expect cleaner spectral mask at 22 dBm. nobody cares about it, doesn't change anything in a meaningful way, but it's a playground, we optimize even things that doesn't really need optimizing)\n(ask your favourite AI what are the benefits of 800µs vs 200µs if interested)</li>\n<li>Companions had too much initial jitter with zero benefit, so it was tuned down to RNG20-150msec</li>\n<li>Claude noticed some line ending stuff by itself, without asking, so I gave him credit (heh)</li>\n</ul>\n"
        },
        {
          "version": "v20260502.112307",
          "name": "Firmware v20260502.112307",
          "datetime": "2026-05-02T11:23:18Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260502.112307",
          "prerelease": false,
          "notes": "This release only removes the \"hot path\" after finishing TX.\r\nIt was an attempt to eliminate \"Sent\" but not \"Heard X repeats\" messages.\r\nI re-did the math, we don't need to stay in full RX after TX for any reason, immediately back to duty cycling is fine until someone starts to use SF7/BW500.\r\nGetting back to duty cycling is in the ms range, no preamble can be missed, so \"Sent\" but not \"Heard\" packets are seems to be truly RF collision/repeater listening to other packets etc.",
          "notesHtml": "<p>This release only removes the \"hot path\" after finishing TX.\nIt was an attempt to eliminate \"Sent\" but not \"Heard X repeats\" messages.\nI re-did the math, we don't need to stay in full RX after TX for any reason, immediately back to duty cycling is fine until someone starts to use SF7/BW500.\nGetting back to duty cycling is in the ms range, no preamble can be missed, so \"Sent\" but not \"Heard\" packets are seems to be truly RF collision/repeater listening to other packets etc.</p>\n"
        },
        {
          "version": "v20260501.191026",
          "name": "Firmware v20260501.191026",
          "datetime": "2026-05-01T19:10:34Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260501.191026",
          "prerelease": false,
          "notes": "- Fixed a freeze that could happen on startup or when changing channels\r\n- Fixed receive sensitivity boost not being applied (it was always off regardless of settings)\r\n- Fixed interference filtering not being recalibrated correctly on 868/433/779 MHz — improves range and reliability\r\n- Fixed a rare bug where packets could be missed or processed twice\r\n- After sending a message, the radio now stays in receive mode for 3 seconds before going back to sleep — reduces chance of missing a reply\r\n- Various tuning improvements to how the radio sleeps and wakes while listening",
          "notesHtml": "<ul>\n<li>Fixed a freeze that could happen on startup or when changing channels</li>\n<li>Fixed receive sensitivity boost not being applied (it was always off regardless of settings)</li>\n<li>Fixed interference filtering not being recalibrated correctly on 868/433/779 MHz — improves range and reliability</li>\n<li>Fixed a rare bug where packets could be missed or processed twice</li>\n<li>After sending a message, the radio now stays in receive mode for 3 seconds before going back to sleep — reduces chance of missing a reply</li>\n<li>Various tuning improvements to how the radio sleeps and wakes while listening</li>\n</ul>\n"
        },
        {
          "version": "v20260430.112448",
          "name": "Firmware v20260430.112448",
          "datetime": "2026-04-30T11:25:02Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260430.112448",
          "prerelease": false,
          "notes": "- Added explicit \"none\" scope handling so companion sends stay unscoped even when a default scope exists.\r\n- Hardened packet and mesh security paths with multiple small fixes, including validation/handling updates in Packet.cpp and Mesh.cpp.\r\n- Fixed small BLE behavior issues in companion message handling.\r\n- Fixed an SX126x native driver race condition (via Zephyr patch update) to improve radio stability under concurrent events.\r\n- Increased LoRa preamble settings to align behavior with vanilla baseline. (increased to 32)",
          "notesHtml": "<ul>\n<li>Added explicit \"none\" scope handling so companion sends stay unscoped even when a default scope exists.</li>\n<li>Hardened packet and mesh security paths with multiple small fixes, including validation/handling updates in Packet.cpp and Mesh.cpp.</li>\n<li>Fixed small BLE behavior issues in companion message handling.</li>\n<li>Fixed an SX126x native driver race condition (via Zephyr patch update) to improve radio stability under concurrent events.</li>\n<li>Increased LoRa preamble settings to align behavior with vanilla baseline. (increased to 32)</li>\n</ul>\n"
        },
        {
          "version": "v20260429.104549",
          "name": "Firmware v20260429.104549",
          "datetime": "2026-04-29T10:46:03Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260429.104549",
          "prerelease": false,
          "notes": "BLE\r\n- Major BLE improvements for companion connectivity, behavior, and reliability. (you can switch on Experimental Settings > Faster Channel Syncing in official app now)\r\n- Internal BLE stack refinements and protocol handling cleanups.\r\n\r\nRadio / LoRa (SX126x)\r\n- Fixed SX126x duty-cycle RX recovery to properly re-arm after BUSY timeout conditions.\r\n- Fixed SX126x TX-enable GPIO handling when dio2-tx-enable is active. (Heltecs were behaving badly because of this!)\r\n\r\nBoard / Hardware Fixes\r\n- Fixed rak4631 handling to avoid toggling SX1262 power-enable pin unexpectedly. (#18)\r\n- Added full display reset after splash screen to improve display bring-up stability. + stole vanilla's refresh algo",
          "notesHtml": "<p>BLE</p>\n<ul>\n<li>Major BLE improvements for companion connectivity, behavior, and reliability. (you can switch on Experimental Settings &gt; Faster Channel Syncing in official app now)</li>\n<li>Internal BLE stack refinements and protocol handling cleanups.</li>\n</ul>\n<p>Radio / LoRa (SX126x)</p>\n<ul>\n<li>Fixed SX126x duty-cycle RX recovery to properly re-arm after BUSY timeout conditions.</li>\n<li>Fixed SX126x TX-enable GPIO handling when dio2-tx-enable is active. (Heltecs were behaving badly because of this!)</li>\n</ul>\n<p>Board / Hardware Fixes</p>\n<ul>\n<li>Fixed rak4631 handling to avoid toggling SX1262 power-enable pin unexpectedly. (#18)</li>\n<li>Added full display reset after splash screen to improve display bring-up stability. + stole vanilla's refresh algo</li>\n</ul>\n"
        },
        {
          "version": "v20260428.134456",
          "name": "Firmware v20260428.134456",
          "datetime": "2026-04-28T13:45:05Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260428.134456",
          "prerelease": false,
          "notes": "-disable GPS cycle until reboot if no GNSS messages present\r\n-make our sx driver more aligned with radiolib's logics (BUSY-line timeout protection, Wake-from-sleep robustness)\r\n-runtime guard agc reset if rx duty cycle is enabled\r\n-tune delay knobs (move closer to vanilla values)\r\n-refactor repeater prefs changes (fix prefs not stored / overwritten on a second \"set\" command AND don't apply new radio prefs before reboot)\r\n-micro-tweak: skip APC math when APC is off\r\n-port vanilla duty cycling logic and replace our coarse method\r\n-fix RX duty cycling logic (it was 9symbol rx / 6symbol sleep instead of 10/6)",
          "notesHtml": "<p>-disable GPS cycle until reboot if no GNSS messages present\n-make our sx driver more aligned with radiolib's logics (BUSY-line timeout protection, Wake-from-sleep robustness)\n-runtime guard agc reset if rx duty cycle is enabled\n-tune delay knobs (move closer to vanilla values)\n-refactor repeater prefs changes (fix prefs not stored / overwritten on a second \"set\" command AND don't apply new radio prefs before reboot)\n-micro-tweak: skip APC math when APC is off\n-port vanilla duty cycling logic and replace our coarse method\n-fix RX duty cycling logic (it was 9symbol rx / 6symbol sleep instead of 10/6)</p>\n"
        },
        {
          "version": "v20260427.083554",
          "name": "Firmware v20260427.083554",
          "datetime": "2026-04-27T08:36:02Z",
          "url": "https://github.com/liquidraver/ZephCore/releases/tag/v20260427.083554",
          "prerelease": false,
          "notes": "-Fix repeater prefs not persisting path.hash.mode, loop.detect, radio.rxgain, rxduty, APC settings across reboots\r\n-Fix stack overflow in prefs load (8-byte buffer for 25-byte read) that silently corrupted owner.info on every boot\r\n-Fix get radio.rxgain always returning radio frequency/BW settings instead of RX gain boost value\r\n-Repeater first-boot and firmware-upgrade now correctly default radio.rxgain and rxduty to ON for SX1262 boards\r\n-Fix setting new repeater radio preset/individual settings applying immediately instead only after reboot",
          "notesHtml": "<p>-Fix repeater prefs not persisting path.hash.mode, loop.detect, radio.rxgain, rxduty, APC settings across reboots\n-Fix stack overflow in prefs load (8-byte buffer for 25-byte read) that silently corrupted owner.info on every boot\n-Fix get radio.rxgain always returning radio frequency/BW settings instead of RX gain boost value\n-Repeater first-boot and firmware-upgrade now correctly default radio.rxgain and rxduty to ON for SX1262 boards\n-Fix setting new repeater radio preset/individual settings applying immediately instead only after reboot</p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:42.115Z"
    },
    {
      "id": "meshcore-tbeam-1w",
      "name": "MeshCore T-Beam 1W",
      "type": "fork",
      "maintainer": "mintylinux",
      "description": "Dedicated MeshCore firmware builds for the LilyGo T-Beam 1 Watt, providing prebuilt binaries for easy flashing without compiling from source.\n",
      "repository": "https://github.com/mintylinux/Meshcore-T-beam-1W-Firmware",
      "license": "MIT",
      "status": "maintenance",
      "lifecycle": "maintenance",
      "maturity": "stable",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater"
      ],
      "features": [
        "Prebuilt firmware for T-Beam 1W",
        "Easy flashing without compiling"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": false,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": false,
          "sensors": false,
          "lowPowerRx": false
        }
      },
      "devices": [
        {
          "id": "lilygo-tbeam-1w",
          "status": "supported"
        }
      ],
      "latest_version": "1.15.0",
      "released": "2026-05-07",
      "releases": [
        {
          "version": "1.15.0",
          "name": "Meshcore-T-Beam-1W-Firmware Ver 1.15.0",
          "datetime": "2026-05-07T23:36:55Z",
          "url": "https://github.com/mintylinux/Meshcore-T-beam-1W-Firmware/releases/tag/1.15.0",
          "prerelease": false,
          "notes": "# Changelog - T-Beam 1W Firmware\r\n\r\nAll notable changes to the MeshCore T-Beam 1W firmware will be documented in this file.\r\n## [1.15.0] - 2026-05-07\r\n\r\n### Updated\r\n- Merged upstream MeshCore `v1.15.0` from `meshcore-dev/MeshCore`\r\n- Rebuilt and verified all T-Beam 1W SX1262 target variants:\r\n  - `T_Beam_1W_SX1262_companion_radio_ble`\r\n  - `T_Beam_1W_SX1262_companion_radio_usb`\r\n  - `T_Beam_1W_SX1262_repeater`\r\n  - `T_Beam_1W_SX1262_room_server`\r\n- Generated new merged firmware artifacts:\r\n  - `T-Beam-1W-CompanionBLE-v1.15.0-merged.bin`\r\n  - `T-Beam-1W-CompanionUSB-v1.15.0-merged.bin`\r\n  - `T-Beam-1W-Repeater-v1.15.0-merged.bin`\r\n  - `T-Beam-1W-RoomServer-v1.15.0-merged.bin`\r\n\r\n### Upstream Changes (v1.14.1 → v1.15.0)\r\n- Default Scope support\r\n- New `GROUP_DATA` binary packet support\r\n- Radio `rxgain` now enabled by default\r\n- Radio frequency range extended down to 150 MHz\r\n- New `get|set dutycycle` CLI command\r\n- WiFi companion fixes for Heltec V4 and T-Beam 1W\r\n- nRF companion OTA update support\r\n- Additional sensor, board support, and stability fixes\r\n\r\n### T-Beam 1W Specific Changes\r\n- Added `SX126X_REGISTER_PATCH=1` for a more stable SX1262 noise floor\r\n- Added `USE_SX1262` to the shared T-Beam 1W SX1262 build flags\r\n- Added `T_Beam_1W_SX1262_companion_radio_usb` build target\r\n- Switched from `min_spiffs.csv` to `default_16MB.csv` to use the full 16MB flash\r\n- Fixed `boards/t_beam_1w.json` to use the generic Arduino `esp32s3` variant so all SX1262 targets build correctly\r\n- Preserved and integrated T-Beam 1W fan control support in all three runtime loops:\r\n  - Companion\r\n  - Repeater\r\n  - Room Server\r\n- Updated the fan thermostat to use MCU temperature with hysteresis:\r\n  - Fan turns ON at `45°C`\r\n  - Fan turns OFF below `41°C`\r\n  - Minimum runtime remains `5s`\r\n\r\n### Technical Details (T-Beam 1W Specific)\r\n- Flash Mode: DIO (Dual I/O)\r\n- Flash Size: 16MB\r\n- Flash Frequency: 80MHz\r\n- Chip: ESP32-S3\r\n- Board: LilyGo T-Beam 1W with SX1262 LoRa radio",
          "notesHtml": "<h1>Changelog - T-Beam 1W Firmware</h1>\n<p>All notable changes to the MeshCore T-Beam 1W firmware will be documented in this file.</p>\n<h2>[1.15.0] - 2026-05-07</h2>\n<h3>Updated</h3>\n<ul>\n<li>Merged upstream MeshCore <code>v1.15.0</code> from <code>meshcore-dev/MeshCore</code></li>\n<li>Rebuilt and verified all T-Beam 1W SX1262 target variants:<ul>\n<li><code>T_Beam_1W_SX1262_companion_radio_ble</code></li>\n<li><code>T_Beam_1W_SX1262_companion_radio_usb</code></li>\n<li><code>T_Beam_1W_SX1262_repeater</code></li>\n<li><code>T_Beam_1W_SX1262_room_server</code></li>\n</ul>\n</li>\n<li>Generated new merged firmware artifacts:<ul>\n<li><code>T-Beam-1W-CompanionBLE-v1.15.0-merged.bin</code></li>\n<li><code>T-Beam-1W-CompanionUSB-v1.15.0-merged.bin</code></li>\n<li><code>T-Beam-1W-Repeater-v1.15.0-merged.bin</code></li>\n<li><code>T-Beam-1W-RoomServer-v1.15.0-merged.bin</code></li>\n</ul>\n</li>\n</ul>\n<h3>Upstream Changes (v1.14.1 → v1.15.0)</h3>\n<ul>\n<li>Default Scope support</li>\n<li>New <code>GROUP_DATA</code> binary packet support</li>\n<li>Radio <code>rxgain</code> now enabled by default</li>\n<li>Radio frequency range extended down to 150 MHz</li>\n<li>New <code>get|set dutycycle</code> CLI command</li>\n<li>WiFi companion fixes for Heltec V4 and T-Beam 1W</li>\n<li>nRF companion OTA update support</li>\n<li>Additional sensor, board support, and stability fixes</li>\n</ul>\n<h3>T-Beam 1W Specific Changes</h3>\n<ul>\n<li>Added <code>SX126X_REGISTER_PATCH=1</code> for a more stable SX1262 noise floor</li>\n<li>Added <code>USE_SX1262</code> to the shared T-Beam 1W SX1262 build flags</li>\n<li>Added <code>T_Beam_1W_SX1262_companion_radio_usb</code> build target</li>\n<li>Switched from <code>min_spiffs.csv</code> to <code>default_16MB.csv</code> to use the full 16MB flash</li>\n<li>Fixed <code>boards/t_beam_1w.json</code> to use the generic Arduino <code>esp32s3</code> variant so all SX1262 targets build correctly</li>\n<li>Preserved and integrated T-Beam 1W fan control support in all three runtime loops:<ul>\n<li>Companion</li>\n<li>Repeater</li>\n<li>Room Server</li>\n</ul>\n</li>\n<li>Updated the fan thermostat to use MCU temperature with hysteresis:<ul>\n<li>Fan turns ON at <code>45°C</code></li>\n<li>Fan turns OFF below <code>41°C</code></li>\n<li>Minimum runtime remains <code>5s</code></li>\n</ul>\n</li>\n</ul>\n<h3>Technical Details (T-Beam 1W Specific)</h3>\n<ul>\n<li>Flash Mode: DIO (Dual I/O)</li>\n<li>Flash Size: 16MB</li>\n<li>Flash Frequency: 80MHz</li>\n<li>Chip: ESP32-S3</li>\n<li>Board: LilyGo T-Beam 1W with SX1262 LoRa radio</li>\n</ul>\n"
        },
        {
          "version": "1.14.1",
          "name": "Meshcore-T-Beam-1W-Firmware Ver 1.14.1",
          "datetime": "2026-03-29T21:31:23Z",
          "url": "https://github.com/mintylinux/Meshcore-T-beam-1W-Firmware/releases/tag/1.14.1",
          "prerelease": false,
          "notes": "## [1.14.1] - 2026-03-29\r\n\r\n### Updated\r\n- Merged upstream MeshCore `v1.14.1` from `meshcore-dev/MeshCore`\r\n- Rebuilt all T-Beam 1W target variants:\r\n  - `T-Beam-1W-CompanionBLE-v1.14.1-merged.bin`\r\n  - `T-Beam-1W-Repeater-v1.14.1-merged.bin`\r\n  - `T-Beam-1W-RoomServer-v1.14.1-merged.bin`\r\n\r\n### Upstream Changes (v1.14.0 → v1.14.1)\r\n- Repeater and Room Server: flood advert timer now uses path_hash_mode pref\r\n- MCU temperature added to telemetry responses from room servers\r\n- Remote LNA support\r\n- Various bug fixes and documentation updates\r\n- Updated webflasher references to v1.14.1",
          "notesHtml": "<h2>[1.14.1] - 2026-03-29</h2>\n<h3>Updated</h3>\n<ul>\n<li>Merged upstream MeshCore <code>v1.14.1</code> from <code>meshcore-dev/MeshCore</code></li>\n<li>Rebuilt all T-Beam 1W target variants:<ul>\n<li><code>T-Beam-1W-CompanionBLE-v1.14.1-merged.bin</code></li>\n<li><code>T-Beam-1W-Repeater-v1.14.1-merged.bin</code></li>\n<li><code>T-Beam-1W-RoomServer-v1.14.1-merged.bin</code></li>\n</ul>\n</li>\n</ul>\n<h3>Upstream Changes (v1.14.0 → v1.14.1)</h3>\n<ul>\n<li>Repeater and Room Server: flood advert timer now uses path_hash_mode pref</li>\n<li>MCU temperature added to telemetry responses from room servers</li>\n<li>Remote LNA support</li>\n<li>Various bug fixes and documentation updates</li>\n<li>Updated webflasher references to v1.14.1</li>\n</ul>\n"
        },
        {
          "version": "1.14",
          "name": "Meshcore LilyGo T-Beam 1Watt. Firmware Ver 1.14",
          "datetime": "2026-03-07T18:25:59Z",
          "url": "https://github.com/mintylinux/Meshcore-T-beam-1W-Firmware/releases/tag/1.14",
          "prerelease": false,
          "notes": "# Changelog - T-Beam 1W Firmware\r\n\r\nAll notable changes to the MeshCore T-Beam 1W firmware will be documented in this file.\r\n## [1.14.0] - 2026-03-07\r\n\r\n### Added\r\n- Updated firmware base to MeshCore `v1.14.0` (upstream merge from `meshcore-dev/MeshCore`)\r\n- New v1.14.0 merged firmware artifacts for T-Beam 1W:\r\n  - `T-Beam-1W-CompanionBLE-v1.14.0-merged.bin`\r\n  - `T-Beam-1W-Repeater-v1.14.0-merged.bin`\r\n  - `T-Beam-1W-RoomServer-v1.14.0-merged.bin`\r\n\r\n### Changed\r\n- Updated webflasher packaging/version references from `v1.13.0` to `v1.14.0`:\r\n  - `create_webflasher_bins.sh`\r\n  - `webflasher/manifest.json`\r\n  - `webflasher/flash-windows.bat`\r\n  - `webflasher/flash-windows.ps1`\r\n- Rebuilt all T-Beam 1W target variants on top of MeshCore v1.14.0\r\n\r\n### Fixed\r\n- Resolved upstream merge conflict in `EnvironmentSensorManager.cpp` while preserving expected GPS loop behavior\r\n- Re-generated merged binaries with required components/offsets for direct flashing:\r\n  - bootloader @ `0x0000`\r\n  - partitions @ `0x8000`\r\n  - boot_app0 @ `0xE000`\r\n  - firmware @ `0x10000`\r\n\r\n### Technical Details (T-Beam 1W Specific)\r\n- Flash Mode: DIO (Dual I/O)\r\n- Flash Size: 4MB\r\n- Flash Frequency: 80MHz\r\n- Chip: ESP32-S3\r\n- Board: LilyGo T-Beam 1W with SX1262 LoRa radio\r\n\r\n---",
          "notesHtml": "<h1>Changelog - T-Beam 1W Firmware</h1>\n<p>All notable changes to the MeshCore T-Beam 1W firmware will be documented in this file.</p>\n<h2>[1.14.0] - 2026-03-07</h2>\n<h3>Added</h3>\n<ul>\n<li>Updated firmware base to MeshCore <code>v1.14.0</code> (upstream merge from <code>meshcore-dev/MeshCore</code>)</li>\n<li>New v1.14.0 merged firmware artifacts for T-Beam 1W:<ul>\n<li><code>T-Beam-1W-CompanionBLE-v1.14.0-merged.bin</code></li>\n<li><code>T-Beam-1W-Repeater-v1.14.0-merged.bin</code></li>\n<li><code>T-Beam-1W-RoomServer-v1.14.0-merged.bin</code></li>\n</ul>\n</li>\n</ul>\n<h3>Changed</h3>\n<ul>\n<li>Updated webflasher packaging/version references from <code>v1.13.0</code> to <code>v1.14.0</code>:<ul>\n<li><code>create_webflasher_bins.sh</code></li>\n<li><code>webflasher/manifest.json</code></li>\n<li><code>webflasher/flash-windows.bat</code></li>\n<li><code>webflasher/flash-windows.ps1</code></li>\n</ul>\n</li>\n<li>Rebuilt all T-Beam 1W target variants on top of MeshCore v1.14.0</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>Resolved upstream merge conflict in <code>EnvironmentSensorManager.cpp</code> while preserving expected GPS loop behavior</li>\n<li>Re-generated merged binaries with required components/offsets for direct flashing:<ul>\n<li>bootloader @ <code>0x0000</code></li>\n<li>partitions @ <code>0x8000</code></li>\n<li>boot_app0 @ <code>0xE000</code></li>\n<li>firmware @ <code>0x10000</code></li>\n</ul>\n</li>\n</ul>\n<h3>Technical Details (T-Beam 1W Specific)</h3>\n<ul>\n<li>Flash Mode: DIO (Dual I/O)</li>\n<li>Flash Size: 4MB</li>\n<li>Flash Frequency: 80MHz</li>\n<li>Chip: ESP32-S3</li>\n<li>Board: LilyGo T-Beam 1W with SX1262 LoRa radio</li>\n</ul>\n<hr />\n"
        },
        {
          "version": "1.13.0",
          "name": "Meshcore LilyGo T-Beam 1Watt Firmware v1.13",
          "datetime": "2026-02-17T17:06:32Z",
          "url": "https://github.com/mintylinux/Meshcore-T-beam-1W-Firmware/releases/tag/1.13.0",
          "prerelease": false,
          "notes": "## [1.13.0] - 2026-02-17\r\n\r\n### Added\r\n- **Repeater CLI Commands**: Remote management via CLI\r\n  - `reboot` - Restart the device\r\n  - `advert` - View advertise settings\r\n  - `set af` - Set auto-forward mode\r\n  - `set name` - Set device name\r\n  - `set lat` / `set lon` - Set GPS coordinates\r\n  - `password` - Change admin password\r\n  - `ver` - Display firmware version\r\n- **Room Server Enhancements**\r\n  - Persistent preferences (loads/saves settings)\r\n  - Same CLI commands as repeater for remote management\r\n  - Timeout detection for push posts (evicts clients after 3 timeouts)\r\n  - TXT_TYPE_SIGNED_PLAIN for outbound messages\r\n- **Companion Radio Features**\r\n  - Anonymous request support (CMD_SEND_ANON_REQ)\r\n  - Auto-add configuration commands (CMD_SET_AUTOADD_CONFIG, CMD_GET_AUTOADD_CONFIG)\r\n  - Allowed repeat frequency query (CMD_GET_ALLOWED_REPEAT_FREQ)\r\n  - Granular auto-add contact type filtering\r\n- **ESP32 Features**\r\n  - ESP32RTCClock for repeater (keeps time across reboots)\r\n- **Temperature-Based Fan Control** (T-Beam 1W)\r\n  - Smart fan activation based on NTC thermistor readings (GPIO 14)\r\n  - Fan turns ON when temperature exceeds 37°C\r\n  - Fan turns OFF when temperature drops below 35°C (hysteresis prevents oscillation)\r\n  - Replaces always-on fan behavior with intelligent thermal management\r\n  - Uses Steinhart-Hart equation for accurate temperature calculation\r\n\r\n### Fixed\r\n- CAD (Channel Activity Detection) detection fixed\r\n- Duplicate message IDs in repeater CLI view\r\n- Room server crash fixes\r\n- hasName() method missing return statement\r\n- BaseChatMesh compilation issues for various targets\r\n- RAK terminal chat fixes\r\n\r\n### Changed\r\n- Mesh packet optimization: Don't retransmit packets already handled by this node\r\n- Refactored advertise data methods to AdvertDataHelper.cpp\r\n- TxtDataHelpers.h with standard TXT sub-types\r\n- Repeater debug diagnostics improvements\r\n- Build configuration now supports ADVERT_NAME, ADVERT_LAT, ADVERT_LON defines\r\n\r\n### Technical Details (T-Beam 1W Specific)\r\n- Flash Mode: DIO (Dual I/O)\r\n- Flash Size: 4MB\r\n- Flash Frequency: 80MHz\r\n- Chip: ESP32-S3\r\n- Board: LilyGo T-Beam 1W with SX1262 LoRa radio\r\n\r\n### Webflasher Binaries\r\nAll binaries include:\r\n- Bootloader at 0x0000\r\n- Partition table at 0x8000\r\n- boot_app0.bin at 0xe000 (required for boot)\r\n- Application firmware at 0x10000\r\n\r\n**Note**: Official MeshCore webflasher currently flashes at wrong offset. Use esptool directly:\r\n```bash\r\npython -m esptool --chip esp32s3 --port COM5 --baud 460800 write_flash 0x0 T-Beam-1W-CompanionBLE-v1.13.0.bin\r\n```\r\n\r\nOr use the provided Windows scripts: `flash-windows.bat` or `flash-windows.ps1`\r\n\r\n---",
          "notesHtml": "<h2>[1.13.0] - 2026-02-17</h2>\n<h3>Added</h3>\n<ul>\n<li><strong>Repeater CLI Commands</strong>: Remote management via CLI<ul>\n<li><code>reboot</code> - Restart the device</li>\n<li><code>advert</code> - View advertise settings</li>\n<li><code>set af</code> - Set auto-forward mode</li>\n<li><code>set name</code> - Set device name</li>\n<li><code>set lat</code> / <code>set lon</code> - Set GPS coordinates</li>\n<li><code>password</code> - Change admin password</li>\n<li><code>ver</code> - Display firmware version</li>\n</ul>\n</li>\n<li><strong>Room Server Enhancements</strong><ul>\n<li>Persistent preferences (loads/saves settings)</li>\n<li>Same CLI commands as repeater for remote management</li>\n<li>Timeout detection for push posts (evicts clients after 3 timeouts)</li>\n<li>TXT_TYPE_SIGNED_PLAIN for outbound messages</li>\n</ul>\n</li>\n<li><strong>Companion Radio Features</strong><ul>\n<li>Anonymous request support (CMD_SEND_ANON_REQ)</li>\n<li>Auto-add configuration commands (CMD_SET_AUTOADD_CONFIG, CMD_GET_AUTOADD_CONFIG)</li>\n<li>Allowed repeat frequency query (CMD_GET_ALLOWED_REPEAT_FREQ)</li>\n<li>Granular auto-add contact type filtering</li>\n</ul>\n</li>\n<li><strong>ESP32 Features</strong><ul>\n<li>ESP32RTCClock for repeater (keeps time across reboots)</li>\n</ul>\n</li>\n<li><strong>Temperature-Based Fan Control</strong> (T-Beam 1W)<ul>\n<li>Smart fan activation based on NTC thermistor readings (GPIO 14)</li>\n<li>Fan turns ON when temperature exceeds 37°C</li>\n<li>Fan turns OFF when temperature drops below 35°C (hysteresis prevents oscillation)</li>\n<li>Replaces always-on fan behavior with intelligent thermal management</li>\n<li>Uses Steinhart-Hart equation for accurate temperature calculation</li>\n</ul>\n</li>\n</ul>\n<h3>Fixed</h3>\n<ul>\n<li>CAD (Channel Activity Detection) detection fixed</li>\n<li>Duplicate message IDs in repeater CLI view</li>\n<li>Room server crash fixes</li>\n<li>hasName() method missing return statement</li>\n<li>BaseChatMesh compilation issues for various targets</li>\n<li>RAK terminal chat fixes</li>\n</ul>\n<h3>Changed</h3>\n<ul>\n<li>Mesh packet optimization: Don't retransmit packets already handled by this node</li>\n<li>Refactored advertise data methods to AdvertDataHelper.cpp</li>\n<li>TxtDataHelpers.h with standard TXT sub-types</li>\n<li>Repeater debug diagnostics improvements</li>\n<li>Build configuration now supports ADVERT_NAME, ADVERT_LAT, ADVERT_LON defines</li>\n</ul>\n<h3>Technical Details (T-Beam 1W Specific)</h3>\n<ul>\n<li>Flash Mode: DIO (Dual I/O)</li>\n<li>Flash Size: 4MB</li>\n<li>Flash Frequency: 80MHz</li>\n<li>Chip: ESP32-S3</li>\n<li>Board: LilyGo T-Beam 1W with SX1262 LoRa radio</li>\n</ul>\n<h3>Webflasher Binaries</h3>\n<p>All binaries include:</p>\n<ul>\n<li>Bootloader at 0x0000</li>\n<li>Partition table at 0x8000</li>\n<li>boot_app0.bin at 0xe000 (required for boot)</li>\n<li>Application firmware at 0x10000</li>\n</ul>\n<p><strong>Note</strong>: Official MeshCore webflasher currently flashes at wrong offset. Use esptool directly:</p>\n<pre><code>python -m esptool --chip esp32s3 --port COM5 --baud 460800 write_flash 0x0 T-Beam-1W-CompanionBLE-v1.13.0.bin\n</code></pre>\n<p>Or use the provided Windows scripts: <code>flash-windows.bat</code> or <code>flash-windows.ps1</code></p>\n<hr />\n"
        },
        {
          "version": "1.12.0",
          "name": "Meshcore LilyGo T-Beam 1Watt. Firmware Ver 1.12.0",
          "datetime": "2026-01-31T03:11:31Z",
          "url": "https://github.com/mintylinux/Meshcore-T-beam-1W-Firmware/releases/tag/1.12.0",
          "prerelease": false,
          "notes": "IMAGES NOW FLASH WITH OFFICIAL MESHCORE WEBFLASHER. PRESS RESET ON DEVICE AFTER THE FLASHING PROCESS.\r\n\r\nAll Features Working:\r\n\r\n1. GPS Communication ✅\r\n◦  Fixed TX/RX pin swap (GPIO 5/6)\r\n◦  NMEA sentences received\r\n◦  L76K GPS working (needs outdoor placement for satellite fix)\r\n2. Battery Monitoring ✅\r\n◦  GPIO 4 ADC reading (per Meshtastic config)\r\n◦  ADC multiplier 2.9333\r\n◦  Real-time voltage\r\n◦  Updates dynamically in app\r\n3. Radio & PA ✅\r\n◦  TX power limited to 22 dBm (safe for 1W PA)\r\n◦  PA ramp time 800µs\r\n◦  Fan control (5s after TX)\r\n4. MeshCore v1.12.0 ✅\r\n◦  All virtual methods implemented\r\n◦  USB CDC serial debug enabled\r\n◦  2S Li-ion battery support (6.0-8.4V)",
          "notesHtml": "<p>IMAGES NOW FLASH WITH OFFICIAL MESHCORE WEBFLASHER. PRESS RESET ON DEVICE AFTER THE FLASHING PROCESS.</p>\n<p>All Features Working:</p>\n<ol>\n<li>GPS Communication ✅\n◦  Fixed TX/RX pin swap (GPIO 5/6)\n◦  NMEA sentences received\n◦  L76K GPS working (needs outdoor placement for satellite fix)</li>\n<li>Battery Monitoring ✅\n◦  GPIO 4 ADC reading (per Meshtastic config)\n◦  ADC multiplier 2.9333\n◦  Real-time voltage\n◦  Updates dynamically in app</li>\n<li>Radio &amp; PA ✅\n◦  TX power limited to 22 dBm (safe for 1W PA)\n◦  PA ramp time 800µs\n◦  Fan control (5s after TX)</li>\n<li>MeshCore v1.12.0 ✅\n◦  All virtual methods implemented\n◦  USB CDC serial debug enabled\n◦  2S Li-ion battery support (6.0-8.4V)</li>\n</ol>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:38.467Z"
    },
    {
      "id": "meshcore-evo",
      "name": "MeshCore-Evo",
      "type": "fork",
      "maintainer": "mattzzw",
      "description": "An improved repeater-focused fork of MeshCore that bundled pending upstream PRs and improvements for dense meshes — notably flood-advert traffic mitigation and enhanced `denyf *` handling. Largely superseded once official 1.16.0 added native flood traffic management.\n",
      "repository": "https://github.com/mattzzw/MeshCore-Evo",
      "website": "https://meshcore.io",
      "license": "MIT",
      "status": "maintenance",
      "lifecycle": "maintenance",
      "maturity": "beta",
      "distribution": "community",
      "lineage": {
        "kind": "fork",
        "upstreamFirmwareId": "meshcore-official",
        "upstreamRepository": "https://github.com/meshcore-dev/MeshCore"
      },
      "runtime": {
        "framework": "arduino",
        "language": "cpp"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "features": [
        "Flood-advert traffic mitigation",
        "Enhanced denyf \"*\" handling",
        "Tuned for dense repeater meshes",
        "Tracks upstream MeshCore releases"
      ],
      "capabilities": {
        "protocol": {
          "meshcoreCompatible": true
        },
        "transports": {
          "ble": true,
          "usbSerial": true,
          "nativeTcp": true,
          "wifiAp": true
        },
        "operations": {
          "ota": true,
          "webFlasher": false
        },
        "networking": {
          "repeater": true,
          "roomServer": true,
          "observer": false,
          "kissModem": false
        },
        "hardware": {
          "gps": true,
          "display": true,
          "sensors": true,
          "lowPowerRx": true
        }
      },
      "devices": [
        {
          "id": "heltec-v3",
          "status": "supported"
        },
        {
          "id": "heltec-wsl3",
          "status": "supported"
        },
        {
          "id": "heltec-t114",
          "status": "supported"
        },
        {
          "id": "rak-4631",
          "status": "supported"
        },
        {
          "id": "uart-solar-node-station",
          "status": "supported"
        },
        {
          "id": "lilygo-t-beam-sx1262",
          "status": "supported"
        },
        {
          "id": "xiao-esp32s3",
          "status": "supported"
        },
        {
          "id": "station-g2",
          "status": "partial",
          "notes": "Builds available; less frequently tested than core repeater boards."
        }
      ],
      "latest_version": "1.15.0-evo_0.1.21",
      "released": "2026-05-25",
      "releases": [
        {
          "version": "v1.15.0-evo_0.1.21",
          "name": "Meshcore-evo build 1.15.0_0.1.21 - 25-May-2026",
          "datetime": "2026-05-25T18:49:27Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.15.0-evo_0.1.21",
          "prerelease": false,
          "notes": "⚠️ Check that `radio.rxgain`(on) and `flood.advert.base` (0.308) are set correctly after flashing! ⚠️ \r\n\r\nThis build is based on official MeshCore 1.15.0 `dev` branch (as of 25-May-2026 and **additionally** includes the following unmerged upstream PRs/changes:\r\n\r\n- PR2553: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/2553) --> `set flood.advert.base 0...1`   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n- :new: PR1727: [Use hardware channel activity detection for checking interference](https://github.com/meshcore-dev/MeshCore/pull/1727) --> Use `set int.thresh 1` to activate hw based channel activity detection.\r\n- :new: PR2377:    [Disable NRF52 undervoltage bootlock feature](https://github.com/meshcore-dev/MeshCore/pull/2377)\r\n\r\nAdditional changes:\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n- :new: modified PR1810 to not block flood adverts but only `PAYLOAD_TYPE_GRP_TXT` and `PAYLOAD_TYPE_GRP_DATA` so that some limited flood advert distribution can be managed via PR2553 to support e.g. observer maps.\r\n\r\nChangelog:\r\n- Based on `dev` v1.15.0 as of 25-May-2026\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.15.0-evo_0.1.20...v1.15.0-evo_0.1.21",
          "notesHtml": "<p>⚠️ Check that <code>radio.rxgain</code>(on) and <code>flood.advert.base</code> (0.308) are set correctly after flashing! ⚠️ </p>\n<p>This build is based on official MeshCore 1.15.0 <code>dev</code> branch (as of 25-May-2026 and <strong>additionally</strong> includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li>PR2553: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2553\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a> --&gt; <code>set flood.advert.base 0...1</code>   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)</li>\n<li>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></li>\n<li>:new: PR1727: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1727\" target=\"_blank\" rel=\"noopener noreferrer\">Use hardware channel activity detection for checking interference</a> --&gt; Use <code>set int.thresh 1</code> to activate hw based channel activity detection.</li>\n<li>:new: PR2377:    <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2377\" target=\"_blank\" rel=\"noopener noreferrer\">Disable NRF52 undervoltage bootlock feature</a></li>\n</ul>\n<p>Additional changes:</p>\n<ul>\n<li>Flood adverts are disabled (flood.advert.interval set to 0) by default</li>\n<li>:new: modified PR1810 to not block flood adverts but only <code>PAYLOAD_TYPE_GRP_TXT</code> and <code>PAYLOAD_TYPE_GRP_DATA</code> so that some limited flood advert distribution can be managed via PR2553 to support e.g. observer maps.</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.15.0 as of 25-May-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.15.0-evo_0.1.20...v1.15.0-evo_0.1.21\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.15.0-evo_0.1.20...v1.15.0-evo_0.1.21</a></p>\n"
        },
        {
          "version": "v1.15.0-evo_0.1.20",
          "name": "Meshcore-evo build 1.15.0_0.1.20 - 14-May-2026",
          "datetime": "2026-05-14T13:10:54Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.15.0-evo_0.1.20",
          "prerelease": false,
          "notes": "⚠️ Check that `radio.rxgain`(on) and `flood.advert.base` (0.308) are set correctly after flashing! ⚠️ \r\n\r\nThis build is based on official MeshCore 1.15.0 `dev` branch (as of 14-May-2026 and **additionally** includes the following unmerged upstream PRs/changes:\r\n\r\n- PR2553: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/2553) --> `set flood.advert.base 0...1`   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n- :new: PR1727: [Use hardware channel activity detection for checking interference](https://github.com/meshcore-dev/MeshCore/pull/1727) --> Use `set int.thresh 1` to activate hw based channel activity detection.\r\n\r\nAdditional changes:\r\n\r\n- RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n- :new: LORA_CR set to 8 as default in `platformio.ini`\r\n- :new: modified PR1810 to not block flood adverts but only `PAYLOAD_TYPE_GRP_TXT` and `PAYLOAD_TYPE_GRP_DATA` so that some limited flood advert distribution can be managed via PR2553 to support e.g. observer maps.\r\n\r\nChangelog:\r\n- Based on `dev` v1.15.0 as of 14-May-2026\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.15.0-evo_0.1.19...v1.15.0-evo_0.1.20",
          "notesHtml": "<p>⚠️ Check that <code>radio.rxgain</code>(on) and <code>flood.advert.base</code> (0.308) are set correctly after flashing! ⚠️ </p>\n<p>This build is based on official MeshCore 1.15.0 <code>dev</code> branch (as of 14-May-2026 and <strong>additionally</strong> includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li>PR2553: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/2553\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a> --&gt; <code>set flood.advert.base 0...1</code>   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)</li>\n<li>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></li>\n<li>:new: PR1727: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1727\" target=\"_blank\" rel=\"noopener noreferrer\">Use hardware channel activity detection for checking interference</a> --&gt; Use <code>set int.thresh 1</code> to activate hw based channel activity detection.</li>\n</ul>\n<p>Additional changes:</p>\n<ul>\n<li>RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n<li>Flood adverts are disabled (flood.advert.interval set to 0) by default</li>\n<li>:new: LORA_CR set to 8 as default in <code>platformio.ini</code></li>\n<li>:new: modified PR1810 to not block flood adverts but only <code>PAYLOAD_TYPE_GRP_TXT</code> and <code>PAYLOAD_TYPE_GRP_DATA</code> so that some limited flood advert distribution can be managed via PR2553 to support e.g. observer maps.</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.15.0 as of 14-May-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.15.0-evo_0.1.19...v1.15.0-evo_0.1.20\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.15.0-evo_0.1.19...v1.15.0-evo_0.1.20</a></p>\n"
        },
        {
          "version": "v1.15.0-evo_0.1.19",
          "name": "Meshcore-evo build 1.15.0_0.1.19 - 24-Apr-2026",
          "datetime": "2026-04-24T20:34:26Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.15.0-evo_0.1.19",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.15.0 `dev` branch (as of 24-Apr-2026 and **additionally** includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338) --> `set flood.advert.base 0...1`   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n\r\n- :new: PR1727: [Use hardware channel activity detection for checking interference](https://github.com/meshcore-dev/MeshCore/pull/1727) --> Use `set int.thresh 1` to activate hw based channel activity detection.\r\n- \r\nAdditional changes:\r\n\r\n- RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n- :new: LORA_CR set to 8 as default in `platformio.ini`\r\n- :new: modified PR1810 to not block flood adverts but only `PAYLOAD_TYPE_GRP_TXT` and `PAYLOAD_TYPE_GRP_DATA` so that some limited flood advert distribution can be managed via PR1338 to support e.g. observer maps.\r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.15.0 as of 24-Apr-2026\r\n\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.1-evo_0.1.18...v1.15.0-evo_0.1.19",
          "notesHtml": "<p>This build is based on official MeshCore 1.15.0 <code>dev</code> branch (as of 24-Apr-2026 and <strong>additionally</strong> includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><p>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a> --&gt; <code>set flood.advert.base 0...1</code>   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)</p>\n</li>\n<li><p>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></p>\n</li>\n<li><p>:new: PR1727: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1727\" target=\"_blank\" rel=\"noopener noreferrer\">Use hardware channel activity detection for checking interference</a> --&gt; Use <code>set int.thresh 1</code> to activate hw based channel activity detection.</p>\n</li>\n<li></li>\n</ul>\n<p>Additional changes:</p>\n<ul>\n<li>RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n<li>Flood adverts are disabled (flood.advert.interval set to 0) by default</li>\n<li>:new: LORA_CR set to 8 as default in <code>platformio.ini</code></li>\n<li>:new: modified PR1810 to not block flood adverts but only <code>PAYLOAD_TYPE_GRP_TXT</code> and <code>PAYLOAD_TYPE_GRP_DATA</code> so that some limited flood advert distribution can be managed via PR1338 to support e.g. observer maps.</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.15.0 as of 24-Apr-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.1-evo_0.1.18...v1.15.0-evo_0.1.19\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.1-evo_0.1.18...v1.15.0-evo_0.1.19</a></p>\n"
        },
        {
          "version": "v1.14.1-evo_0.1.18",
          "name": "Meshcore-evo build 1.14.1_0.1.18 - 05-Apr-2026",
          "datetime": "2026-04-05T16:19:35Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.14.1-evo_0.1.18",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.14.1 `dev` branch (as of 05-Apr-2026 and **additionally** includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338) --> `set flood.advert.base 0...1`   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n- :new: PR1727: [Use hardware channel activity detection for checking interference](https://github.com/meshcore-dev/MeshCore/pull/1727) --> Use `set int.thresh 1` to activate hw based channel activity detection.\r\n- \r\nAdditional changes:\r\n\r\n- RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n- :new: LORA_CR set to 8 as default in `platformio.ini`\r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.14.1 as of 05-Apr-2026\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.1-evo_0.1.17...v1.14.1-evo_0.1.18",
          "notesHtml": "<p>This build is based on official MeshCore 1.14.1 <code>dev</code> branch (as of 05-Apr-2026 and <strong>additionally</strong> includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a> --&gt; <code>set flood.advert.base 0...1</code>   (0: no flood adv. forwarding, 0.308: default, 1: all flood adv. forwarding)</li>\n<li>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></li>\n<li>:new: PR1727: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1727\" target=\"_blank\" rel=\"noopener noreferrer\">Use hardware channel activity detection for checking interference</a> --&gt; Use <code>set int.thresh 1</code> to activate hw based channel activity detection.</li>\n<li></li>\n</ul>\n<p>Additional changes:</p>\n<ul>\n<li>RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n<li>Flood adverts are disabled (flood.advert.interval set to 0) by default</li>\n<li>:new: LORA_CR set to 8 as default in <code>platformio.ini</code></li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.14.1 as of 05-Apr-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.1-evo_0.1.17...v1.14.1-evo_0.1.18\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.1-evo_0.1.17...v1.14.1-evo_0.1.18</a></p>\n"
        },
        {
          "version": "v1.14.1-evo_0.1.17",
          "name": "Meshcore-evo build 1.14.1_0.1.17 - 29-Mar-2026",
          "datetime": "2026-03-29T09:44:50Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.14.1-evo_0.1.17",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.14.1 `dev` branch (as of 29-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n- RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n\r\nPR1297, [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297), has been merged upstream and is now part of the official dev branch. So this PR is also part of this firmware.\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- will handle packet forwarding better in case of `denyf *`\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is disabled for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.14.1 as of 29-Mar-2026\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.16...v1.14.1-evo_0.1.17",
          "notesHtml": "<p>This build is based on official MeshCore 1.14.1 <code>dev</code> branch (as of 29-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></li>\n<li>RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n<li>Flood adverts are disabled (flood.advert.interval set to 0) by default</li>\n</ul>\n<p>PR1297, <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a>, has been merged upstream and is now part of the official dev branch. So this PR is also part of this firmware.</p>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>will handle packet forwarding better in case of <code>denyf *</code></li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is disabled for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.14.1 as of 29-Mar-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.16...v1.14.1-evo_0.1.17\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.16...v1.14.1-evo_0.1.17</a></p>\n"
        },
        {
          "version": "v1.14.0-evo_0.1.16",
          "name": "Meshcore-evo build 1.14.0_0.1.16 - 17-Mar-2026",
          "datetime": "2026-03-17T12:49:02Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.14.0-evo_0.1.16",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.14.0 `dev` branch (as of 17-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n- RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n\r\nPR1297, [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297), has been merged upstream and is now part of the official dev branch. So this PR is also part of this firmware.\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- will handle packet forwarding better in case of `denyf *`\r\n\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is disabled for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.14.0 as of 17-Mar-2026\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.15...v1.14.0-evo_0.1.16",
          "notesHtml": "<p>This build is based on official MeshCore 1.14.0 <code>dev</code> branch (as of 17-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></li>\n<li>RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n<li>Flood adverts are disabled (flood.advert.interval set to 0) by default</li>\n</ul>\n<p>PR1297, <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a>, has been merged upstream and is now part of the official dev branch. So this PR is also part of this firmware.</p>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>will handle packet forwarding better in case of <code>denyf *</code></li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is disabled for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.14.0 as of 17-Mar-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.15...v1.14.0-evo_0.1.16\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.15...v1.14.0-evo_0.1.16</a></p>\n"
        },
        {
          "version": "v1.14.0-evo_0.1.15",
          "name": "Meshcore-evo build 1.14.0_0.1.15 - 08-Mar-2026",
          "datetime": "2026-03-08T09:49:11Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.14.0-evo_0.1.15",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.14.0 `dev` branch (as of 08-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1297: [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n\r\n- RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is disabled for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.14.0 as of 08-Mar-2026\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.14...v1.14.0-evo_0.1.15",
          "notesHtml": "<p>This build is based on official MeshCore 1.14.0 <code>dev</code> branch (as of 08-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><p>PR1297: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></p>\n</li>\n<li><p>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></p>\n</li>\n<li><p>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></p>\n</li>\n<li><p>RAK 4631, Xiao NRf, T114 variant: Lowered lockout voltage from 3.3V to 0V, preventing boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</p>\n</li>\n<li><p>Flood adverts are disabled (flood.advert.interval set to 0) by default</p>\n</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is disabled for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.14.0 as of 08-Mar-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.14...v1.14.0-evo_0.1.15\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.14.0-evo_0.1.14...v1.14.0-evo_0.1.15</a></p>\n"
        },
        {
          "version": "v1.14.0-evo_0.1.14",
          "name": "Meshcore-evo build v1.14.0_0.1.14 - 06-Mar-2026",
          "datetime": "2026-03-06T19:38:46Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.14.0-evo_0.1.14",
          "prerelease": false,
          "notes": "This build is based on the same commits as evo v0.1.13 is, just hours before the merge to main. But in order to prevent confusion I decided to re-release the evo firmware based on the [official MeshCore v1.14.0 release](https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.14.0).\r\n\r\nSo here it goes:\r\n\r\nThis build is based on official MeshCore 1.14.0 `main` branch (as of 06-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1297: [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n\r\n- RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is disabled for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `main` v1.14.0 as of 06-Mar-2026 \r\n\r\n\r\nChange log of [MeshCore v1.14.0](https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.14.0):\r\n\r\n- multibyte path hash support\r\n- new ‘auto add max hops’ preference\r\n- new radio AGC reset implementation\r\n- HeltecV4 power fixes\r\n- RAK3401 power optimisations\r\n- Heltec Tracker V2 power fixes\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.13...v1.14.0-evo_0.1.14",
          "notesHtml": "<p>This build is based on the same commits as evo v0.1.13 is, just hours before the merge to main. But in order to prevent confusion I decided to re-release the evo firmware based on the <a href=\"https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.14.0\" target=\"_blank\" rel=\"noopener noreferrer\">official MeshCore v1.14.0 release</a>.</p>\n<p>So here it goes:</p>\n<p>This build is based on official MeshCore 1.14.0 <code>main</code> branch (as of 06-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><p>PR1297: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></p>\n</li>\n<li><p>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></p>\n</li>\n<li><p>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></p>\n</li>\n<li><p>RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</p>\n</li>\n<li><p>Flood adverts are disabled (flood.advert.interval set to 0) by default</p>\n</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is disabled for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>main</code> v1.14.0 as of 06-Mar-2026</li>\n</ul>\n<p>Change log of <a href=\"https://github.com/meshcore-dev/MeshCore/releases/tag/companion-v1.14.0\" target=\"_blank\" rel=\"noopener noreferrer\">MeshCore v1.14.0</a>:</p>\n<ul>\n<li>multibyte path hash support</li>\n<li>new ‘auto add max hops’ preference</li>\n<li>new radio AGC reset implementation</li>\n<li>HeltecV4 power fixes</li>\n<li>RAK3401 power optimisations</li>\n<li>Heltec Tracker V2 power fixes</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.13...v1.14.0-evo_0.1.14\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.13...v1.14.0-evo_0.1.14</a></p>\n"
        },
        {
          "version": "v1.13.0-evo_0.1.13",
          "name": "Meshcore-evo build 1.13.0_0.1.13- 05-Mar-2026",
          "datetime": "2026-03-05T22:50:53Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.13.0-evo_0.1.13",
          "prerelease": false,
          "notes": "⚠️ I had to pull  previous evo release v0.1.11 due to a build issue leading to a boot loop with ESP32 based repeaters (e.g. heltec v3/v4) when upgrading (#8).  This has been fixed with this release. ⚠️ \r\n\r\nOK, it has only been a few days since the last evo build but many bugfixes (thanks @weebl2000!) have been merged upstream since. (AGC reset fix PR1743 being one of them, yay.)\r\n\r\nSo here it goes.\r\n\r\nThis build is based on official MeshCore 1.30 `dev` branch as of 05-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1297: [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n\r\n- RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is disabled for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.13.0 as of 05-Mar-2026 \r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.12...v1.13.0-evo_0.1.13",
          "notesHtml": "<p>⚠️ I had to pull  previous evo release v0.1.11 due to a build issue leading to a boot loop with ESP32 based repeaters (e.g. heltec v3/v4) when upgrading (#8).  This has been fixed with this release. ⚠️ </p>\n<p>OK, it has only been a few days since the last evo build but many bugfixes (thanks @weebl2000!) have been merged upstream since. (AGC reset fix PR1743 being one of them, yay.)</p>\n<p>So here it goes.</p>\n<p>This build is based on official MeshCore 1.30 <code>dev</code> branch as of 05-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><p>PR1297: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></p>\n</li>\n<li><p>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></p>\n</li>\n<li><p>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></p>\n</li>\n<li><p>RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</p>\n</li>\n<li><p>Flood adverts are disabled (flood.advert.interval set to 0) by default</p>\n</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is disabled for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.13.0 as of 05-Mar-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.12...v1.13.0-evo_0.1.13\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.12...v1.13.0-evo_0.1.13</a></p>\n"
        },
        {
          "version": "v1.13.0-evo_0.1.12",
          "name": "Meshcore-evo build 1.13.0_0.1.12- 04-Mar-2026",
          "datetime": "2026-03-04T22:48:24Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.13.0-evo_0.1.12",
          "prerelease": false,
          "notes": "⚠️ I had to pull  previous evo release v0.1.11 due to a build issue leading to a boot loop with ESP32 based repeaters (e.g. heltec v3/v4) when upgrading (#8).  This has been fixed with this release. ⚠️ \r\n\r\nOK, it has only been a few days since the last evo build but many bugfixes (thanks @weebl2000!) have been merged upstream since. (AGC reset fix PR1743 being one of them, yay.)\r\n\r\nSo here it goes.\r\n\r\nThis build is based on official MeshCore 1.30 `dev` branch as of 04-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1297: [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n\r\n- RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is disabled for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.13.0 as of 04-Mar-2026 \r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.10...v1.13.0-evo_0.1.12",
          "notesHtml": "<p>⚠️ I had to pull  previous evo release v0.1.11 due to a build issue leading to a boot loop with ESP32 based repeaters (e.g. heltec v3/v4) when upgrading (#8).  This has been fixed with this release. ⚠️ </p>\n<p>OK, it has only been a few days since the last evo build but many bugfixes (thanks @weebl2000!) have been merged upstream since. (AGC reset fix PR1743 being one of them, yay.)</p>\n<p>So here it goes.</p>\n<p>This build is based on official MeshCore 1.30 <code>dev</code> branch as of 04-Mar-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><p>PR1297: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></p>\n</li>\n<li><p>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></p>\n</li>\n<li><p>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></p>\n</li>\n<li><p>RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</p>\n</li>\n<li><p>Flood adverts are disabled (flood.advert.interval set to 0) by default</p>\n</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is disabled for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.13.0 as of 04-Mar-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.10...v1.13.0-evo_0.1.12\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.10...v1.13.0-evo_0.1.12</a></p>\n"
        },
        {
          "version": "v1.13.0-evo_0.1.10",
          "name": "Meshcore-evo build 1.13.0_0.1.10- 28-Feb-2026",
          "datetime": "2026-02-28T15:46:42Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.13.0-evo_0.1.10",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.30 `dev` branch as of 28-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- PR1297: [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- PR1338: [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- PR1743: [fix agc reset on SX126x, SX1276 & LR11x0 chips](https://github.com/meshcore-dev/MeshCore/pull/1743)\r\n- PR1810: [Allow direct message paths when denyf * is set](https://github.com/meshcore-dev/MeshCore/pull/1810)\r\n\r\n- RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- Flood adverts are disabled (flood.advert.interval set to 0) by default\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is disabled for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.13.0 as of 28-Feb-2026 \r\n\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.9...v1.13.0-evo_0.1.10",
          "notesHtml": "<p>This build is based on official MeshCore 1.30 <code>dev</code> branch as of 28-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><p>PR1297: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></p>\n</li>\n<li><p>PR1338: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></p>\n</li>\n<li><p>PR1743: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1743\" target=\"_blank\" rel=\"noopener noreferrer\">fix agc reset on SX126x, SX1276 &amp; LR11x0 chips</a></p>\n</li>\n<li><p>PR1810: <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1810\" target=\"_blank\" rel=\"noopener noreferrer\">Allow direct message paths when denyf * is set</a></p>\n</li>\n<li><p>RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</p>\n</li>\n<li><p>Flood adverts are disabled (flood.advert.interval set to 0) by default</p>\n</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is disabled for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.13.0 as of 28-Feb-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.9...v1.13.0-evo_0.1.10\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore-Evo/compare/v1.13.0-evo_0.1.9...v1.13.0-evo_0.1.10</a></p>\n"
        },
        {
          "version": "v1.13.0-evo_0.1.9",
          "name": "Meshcore-evo build 1.13.0_0.1.9- 21-Feb-2026",
          "datetime": "2026-02-21T19:13:02Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.13.0-evo_0.1.9",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.30 `dev` branch as of 21-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is 48h for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.13.0 as of 21-Feb-2026 \r\n\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v1.13.0_0.1.8...v1.13.0-evo_0.1.9",
          "notesHtml": "<p>This build is based on official MeshCore 1.30 <code>dev</code> branch as of 21-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li>RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is 48h for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.13.0 as of 21-Feb-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v1.13.0_0.1.8...v1.13.0-evo_0.1.9\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v1.13.0_0.1.8...v1.13.0-evo_0.1.9</a></p>\n"
        },
        {
          "version": "v1.13.0_0.1.8",
          "name": "Meshcore-evo build 1.13.0_0.1.8 - 15-Feb-2026",
          "datetime": "2026-02-16T12:06:55Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.13.0_0.1.8",
          "prerelease": false,
          "notes": "This build is based on official MeshCore 1.30 release, `main` branch as of 15-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is 48h for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `main` v1.13.0 as of 15-Feb-2026 \r\n\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v1.12.0_0.1.7...v1.13.0_0.1.8",
          "notesHtml": "<p>This build is based on official MeshCore 1.30 release, <code>main</code> branch as of 15-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li>RAK 4631 variant: Lowered lockout voltage from 3.3V to 0V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is 48h for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>main</code> v1.13.0 as of 15-Feb-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v1.12.0_0.1.7...v1.13.0_0.1.8\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v1.12.0_0.1.7...v1.13.0_0.1.8</a></p>\n"
        },
        {
          "version": "v1.12.0_0.1.7",
          "name": "Meshcore-evo build 1.12.0_0.1.7 - 10-Feb-2026",
          "datetime": "2026-02-10T20:34:18Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.12.0_0.1.7",
          "prerelease": false,
          "notes": "This build is based on official MeshCore `dev` branch as of 10-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- RAK 4631 variant: Lowered lockout voltage from 3.3V to 3.1V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)\r\n- [Improve Heltec v4 RX reception with undocumented register patch](https://github.com/meshcore-dev/MeshCore/pull/1398)\r\nThis is now part of dev, the PR has been merged upstream and is also part of this build.\r\n\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is 48h for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.12.0 as of 10-Feb-2026 \r\n\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v1.12.0_0.1.6...v1.12.0_0.1.7",
          "notesHtml": "<p>This build is based on official MeshCore <code>dev</code> branch as of 10-Feb-2026 and additionally includes the following unmerged upstream PRs/changes:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li>RAK 4631 variant: Lowered lockout voltage from 3.3V to 3.1V, preventing RAK 4631 boards operated with different battery chemistries like LTO or LiFePo4 from booting. This is an issue e.g. if uart.cz boards are being used.  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1398\" target=\"_blank\" rel=\"noopener noreferrer\">Improve Heltec v4 RX reception with undocumented register patch</a>\nThis is now part of dev, the PR has been merged upstream and is also part of this build.</li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is 48h for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.12.0 as of 10-Feb-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v1.12.0_0.1.6...v1.12.0_0.1.7\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v1.12.0_0.1.6...v1.12.0_0.1.7</a></p>\n"
        },
        {
          "version": "v1.12.0_0.1.6",
          "name": "Meshcore-evo build 1.12.0_0.1.6 - 01-Feb-2026",
          "datetime": "2026-02-01T22:03:46Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.12.0_0.1.6",
          "prerelease": false,
          "notes": "This build is based on official MeshCore `dev` branch as of 01-Feb-2026 and includes the following unmerged upstream PRs:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- [Improve Heltec v4 RX reception with undocumented register patch](https://github.com/meshcore-dev/MeshCore/pull/1398)\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n- Improve Heltec V4 RX performance\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is 48h for new installations\r\n- Set `advert.interval` to 240 (every 4h) \r\n\r\n\r\nChangelog:\r\n- Based on `dev` v1.12.0 as of 01-Feb-2026 \r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v1.12.0-evo...v1.12.0_0.1.6\r\n\r\nFor RAK4630 boards operated with LiFePo batteries I added a fw build `RAK_4631_repeater-v1.12.0-evo_0.1.6_lockoutfix-f34a1f8` with `PWRMGT_VOLTAGE_BOOTLOCK` set to 3100 (3.1V).  (See discussion [here](https://github.com/meshcore-dev/MeshCore/issues/1572).)",
          "notesHtml": "<p>This build is based on official MeshCore <code>dev</code> branch as of 01-Feb-2026 and includes the following unmerged upstream PRs:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1398\" target=\"_blank\" rel=\"noopener noreferrer\">Improve Heltec v4 RX reception with undocumented register patch</a></li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n<li>Improve Heltec V4 RX performance</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is 48h for new installations</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h)</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>dev</code> v1.12.0 as of 01-Feb-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v1.12.0-evo...v1.12.0_0.1.6\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v1.12.0-evo...v1.12.0_0.1.6</a></p>\n<p>For RAK4630 boards operated with LiFePo batteries I added a fw build <code>RAK_4631_repeater-v1.12.0-evo_0.1.6_lockoutfix-f34a1f8</code> with <code>PWRMGT_VOLTAGE_BOOTLOCK</code> set to 3100 (3.1V).  (See discussion <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1572\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.)</p>\n"
        },
        {
          "version": "v1.12.0-evo",
          "name": "Meshcore-evo build 1.12.0-evo - 29-Jan-2026",
          "datetime": "2026-01-29T11:22:03Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.12.0-evo",
          "prerelease": false,
          "notes": "This build is based on the official 1.12 release (`main` branch) as of 29-Jan-2026 and includes the following unmerged upstream PRs:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n\r\nAs a result this firmware will be suited for large and/or high density meshes:\r\n- only send a zero hop advert on boot \r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nAdditionally the LORA settings are defaulting to EU/narrow for erase/flash installs.\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or to 168 (weekly flood adverts), default is 48h\r\n- Set `advert.interval` to 240 (every 4h) \r\n- check `flood.advert.base`- should be ~0.308 \r\n\r\n\r\nChangelog:\r\n- Based on `main` v1.12.0 as of 29-Jan-2026 \r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.5...v1.12.0-evo",
          "notesHtml": "<p>This build is based on the official 1.12 release (<code>main</code> branch) as of 29-Jan-2026 and includes the following unmerged upstream PRs:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n</ul>\n<p>As a result this firmware will be suited for large and/or high density meshes:</p>\n<ul>\n<li>only send a zero hop advert on boot </li>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Additionally the LORA settings are defaulting to EU/narrow for erase/flash installs.</p>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or to 168 (weekly flood adverts), default is 48h</li>\n<li>Set <code>advert.interval</code> to 240 (every 4h) </li>\n<li>check <code>flood.advert.base</code>- should be ~0.308</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on <code>main</code> v1.12.0 as of 29-Jan-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.5...v1.12.0-evo\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.5...v1.12.0-evo</a></p>\n"
        },
        {
          "version": "v1.11.0_0.1.5",
          "name": "Meshcore-evo build 1.11.0_0.1.5 - 28-Jan-2026",
          "datetime": "2026-01-28T17:58:09Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.11.0_0.1.5",
          "prerelease": false,
          "notes": "This build is based on the `dev` branch as of 28-Jan-2026 and includes the following unmerged upstream PRs:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n\r\nIt does NOT include\r\n- [Default to zero hop advert when booting + STEALTH_MODE flag](https://github.com/meshcore-dev/MeshCore/pull/1199)\r\nanymore, BUT the same functionality has been merged to dev officially as part of PR1488\r\n\r\nAs a result this firmware will\r\n- only send a zero hop advert on boot \r\n- will be set to 48h flood advert interval (this is the minimum allowed in this fw)\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nAdditionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.\r\n\r\n- Includes updated PR [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338):\r\n-- Use `set flood.advert.base x: float in [0,1], defaults to 0.308`, 0 will disable flood advert forwarding, 1 forwards all.\r\n\r\n- You can now use way longer advert interval limits up to 168h.\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or higher than 168 (weekly flood adverts), default is 48h\r\n- Set `advert.interval` to 300 (every 5h) \r\n- check `flood.advert.base`- should be ~0.308\r\n\r\n\r\nChangelog:\r\n- Based on dev as of 28-Jan-2026 \r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.4...v1.11.0_0.1.5",
          "notesHtml": "<p>This build is based on the <code>dev</code> branch as of 28-Jan-2026 and includes the following unmerged upstream PRs:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n</ul>\n<p>It does NOT include</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1199\" target=\"_blank\" rel=\"noopener noreferrer\">Default to zero hop advert when booting + STEALTH_MODE flag</a>\nanymore, BUT the same functionality has been merged to dev officially as part of PR1488</li>\n</ul>\n<p>As a result this firmware will</p>\n<ul>\n<li>only send a zero hop advert on boot </li>\n<li>will be set to 48h flood advert interval (this is the minimum allowed in this fw)</li>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Additionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.</p>\n<ul>\n<li><p>Includes updated PR <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a>:\n-- Use <code>set flood.advert.base x: float in [0,1], defaults to 0.308</code>, 0 will disable flood advert forwarding, 1 forwards all.</p>\n</li>\n<li><p>You can now use way longer advert interval limits up to 168h.</p>\n</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or higher than 168 (weekly flood adverts), default is 48h</li>\n<li>Set <code>advert.interval</code> to 300 (every 5h) </li>\n<li>check <code>flood.advert.base</code>- should be ~0.308</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on dev as of 28-Jan-2026</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.4...v1.11.0_0.1.5\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.4...v1.11.0_0.1.5</a></p>\n"
        },
        {
          "version": "v1.11.0_0.1.4",
          "name": "Meshcore-evo build 1.11.0_0.1.4 - 26-Jan-2026",
          "datetime": "2026-01-26T12:34:12Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.11.0_0.1.4",
          "prerelease": false,
          "notes": "This build is based on the `dev` branch as of 26-Jan-2026 and includes the following unmerged upstream PRs:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n\r\nIt does NOT include\r\n- [Default to zero hop advert when booting + STEALTH_MODE flag](https://github.com/meshcore-dev/MeshCore/pull/1199)\r\nanymore, BUT the same functionality has been merged to dev officially as part of PR1488\r\n\r\nAs a result this firmware will\r\n- only send a zero hop advert on boot \r\n- will be set to 48h flood advert interval (this is the minimum allowed in this fw)\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nAdditionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.\r\n\r\n- Includes updated PR [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338):\r\n-- Use `set flood.advert.base x: float in [0,1], defaults to 0.308`, 0 will disable flood advert forwarding, 1 forwards all.\r\n\r\n- You can now use way longer advert interval limits up to 168h.\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or higher than 168 (weekly flood adverts), default is 48h\r\n- Set `advert.interval` to 300 (every 5h) \r\n- check `flood.advert.base`- should be ~0.308\r\n\r\n\r\nChangelog:\r\n- Based on dev as of 26-Jan-2026 \r\n- The former releases did not include PR [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297) due to a bug in a build script. Now it's properly included\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.3...v1.11.0_0.1.4",
          "notesHtml": "<p>This build is based on the <code>dev</code> branch as of 26-Jan-2026 and includes the following unmerged upstream PRs:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n</ul>\n<p>It does NOT include</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1199\" target=\"_blank\" rel=\"noopener noreferrer\">Default to zero hop advert when booting + STEALTH_MODE flag</a>\nanymore, BUT the same functionality has been merged to dev officially as part of PR1488</li>\n</ul>\n<p>As a result this firmware will</p>\n<ul>\n<li>only send a zero hop advert on boot </li>\n<li>will be set to 48h flood advert interval (this is the minimum allowed in this fw)</li>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Additionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.</p>\n<ul>\n<li><p>Includes updated PR <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a>:\n-- Use <code>set flood.advert.base x: float in [0,1], defaults to 0.308</code>, 0 will disable flood advert forwarding, 1 forwards all.</p>\n</li>\n<li><p>You can now use way longer advert interval limits up to 168h.</p>\n</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or higher than 168 (weekly flood adverts), default is 48h</li>\n<li>Set <code>advert.interval</code> to 300 (every 5h) </li>\n<li>check <code>flood.advert.base</code>- should be ~0.308</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on dev as of 26-Jan-2026 </li>\n<li>The former releases did not include PR <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a> due to a bug in a build script. Now it's properly included</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.3...v1.11.0_0.1.4\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v1.11.0_0.1.3...v1.11.0_0.1.4</a></p>\n"
        },
        {
          "version": "v1.11.0_0.1.3",
          "name": "Meshcore-evo build v1.11.0_0.1.3 - 17-Jan-2026",
          "datetime": "2026-01-17T14:59:19Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v1.11.0_0.1.3",
          "prerelease": false,
          "notes": "This build is based on the `dev` branch as of 17-Jan-2026 and includes the following unmerged upstream PRs:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- [Default to zero hop advert when booting + STEALTH_MODE flag](https://github.com/meshcore-dev/MeshCore/pull/1199)\r\n\r\nAs a result this firmware will\r\n- only send a zero hop advert on boot \r\n- will be set to 48h flood advert interval (this is the minimum allowed in this fw)\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nAdditionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.\r\n\r\n- Includes updated PR [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338):\r\n-- Use `set flood.advert.base x: float in [0,1], defaults to 0.308`, 0 will disable flood advert forwarding, 1 forwards all.\r\n\r\n- You can now use way longer advert interval limits than 48h (e.g. weekly, monthly, ...)\r\n\r\nRecommended use:\r\n- Set `flood.advert.interval` to zero or higher than 168 (weekly flood adverts), default is 48h\r\n- Set `advert.interval` to 300 (every 5h) \r\n- check `flood.advert.base`- should be ~0.308\r\n\r\n\r\nChangelog:\r\n- Based on dev as of 17-Jan-2026 \r\n- Changed default advert.interval limits \r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v0.1.2...v1.11.0_0.1.3",
          "notesHtml": "<p>This build is based on the <code>dev</code> branch as of 17-Jan-2026 and includes the following unmerged upstream PRs:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1199\" target=\"_blank\" rel=\"noopener noreferrer\">Default to zero hop advert when booting + STEALTH_MODE flag</a></li>\n</ul>\n<p>As a result this firmware will</p>\n<ul>\n<li>only send a zero hop advert on boot </li>\n<li>will be set to 48h flood advert interval (this is the minimum allowed in this fw)</li>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Additionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.</p>\n<ul>\n<li><p>Includes updated PR <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a>:\n-- Use <code>set flood.advert.base x: float in [0,1], defaults to 0.308</code>, 0 will disable flood advert forwarding, 1 forwards all.</p>\n</li>\n<li><p>You can now use way longer advert interval limits than 48h (e.g. weekly, monthly, ...)</p>\n</li>\n</ul>\n<p>Recommended use:</p>\n<ul>\n<li>Set <code>flood.advert.interval</code> to zero or higher than 168 (weekly flood adverts), default is 48h</li>\n<li>Set <code>advert.interval</code> to 300 (every 5h) </li>\n<li>check <code>flood.advert.base</code>- should be ~0.308</li>\n</ul>\n<p>Changelog:</p>\n<ul>\n<li>Based on dev as of 17-Jan-2026 </li>\n<li>Changed default advert.interval limits</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v0.1.2...v1.11.0_0.1.3\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v0.1.2...v1.11.0_0.1.3</a></p>\n"
        },
        {
          "version": "v0.1.2",
          "name": "Meshcore-evo build 1.11.0_0.1.2 - 14-Jan-2026",
          "datetime": "2026-01-14T11:18:05Z",
          "url": "https://github.com/mattzzw/MeshCore-Evo/releases/tag/v0.1.2",
          "prerelease": false,
          "notes": "This build is based on the `dev` branch as of 14-Jan-2026 and includes the following unmerged upstream PRs:\r\n\r\n- [Implement token bucket duty cycle enforcement](https://github.com/meshcore-dev/MeshCore/pull/1297)\r\n- [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338)\r\n- [Default to zero hop advert when booting + STEALTH_MODE flag](https://github.com/meshcore-dev/MeshCore/pull/1199)\r\n\r\nAs a result this firmware will\r\n- only send a zero hop advert on boot \r\n- will be set to 48h flood advert interval (this is the minimum allowed in this fw)\r\n- will reduce flood advert forwarding based on [this proposal](https://github.com/meshcore-dev/MeshCore/issues/1223)\r\n- Implement [rolling window duty cycle management](https://github.com/meshcore-dev/MeshCore/issues/817), allowing for more robust tx operations of central/busy repeaters\r\n\r\nAdditionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.\r\n\r\nChangelog:\r\n- Based on dev 14-Jan-2026 \r\n- Includes updated PR [Limit flood advert packet forwarding](https://github.com/meshcore-dev/MeshCore/pull/1338):\r\n-- Use `set flood.advert.base x: float in [0,1], defaults to 0.308`, 0 will disable flood advert forwarding, 1 forwards all.\r\n\r\n**Full Changelog**: https://github.com/mattzzw/MeshCore/compare/v0.1.1...v0.1.2",
          "notesHtml": "<p>This build is based on the <code>dev</code> branch as of 14-Jan-2026 and includes the following unmerged upstream PRs:</p>\n<ul>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1297\" target=\"_blank\" rel=\"noopener noreferrer\">Implement token bucket duty cycle enforcement</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a></li>\n<li><a href=\"https://github.com/meshcore-dev/MeshCore/pull/1199\" target=\"_blank\" rel=\"noopener noreferrer\">Default to zero hop advert when booting + STEALTH_MODE flag</a></li>\n</ul>\n<p>As a result this firmware will</p>\n<ul>\n<li>only send a zero hop advert on boot </li>\n<li>will be set to 48h flood advert interval (this is the minimum allowed in this fw)</li>\n<li>will reduce flood advert forwarding based on <a href=\"https://github.com/meshcore-dev/MeshCore/issues/1223\" target=\"_blank\" rel=\"noopener noreferrer\">this proposal</a></li>\n<li>Implement <a href=\"https://github.com/meshcore-dev/MeshCore/issues/817\" target=\"_blank\" rel=\"noopener noreferrer\">rolling window duty cycle management</a>, allowing for more robust tx operations of central/busy repeaters</li>\n</ul>\n<p>Additionally the LORA settings are defaulting to EU/narrow and the min/max/defaults for adverts have been adjusted, see platformio.ini.</p>\n<p>Changelog:</p>\n<ul>\n<li>Based on dev 14-Jan-2026 </li>\n<li>Includes updated PR <a href=\"https://github.com/meshcore-dev/MeshCore/pull/1338\" target=\"_blank\" rel=\"noopener noreferrer\">Limit flood advert packet forwarding</a>:\n-- Use <code>set flood.advert.base x: float in [0,1], defaults to 0.308</code>, 0 will disable flood advert forwarding, 1 forwards all.</li>\n</ul>\n<p><strong>Full Changelog</strong>: <a href=\"https://github.com/mattzzw/MeshCore/compare/v0.1.1...v0.1.2\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/mattzzw/MeshCore/compare/v0.1.1...v0.1.2</a></p>\n"
        }
      ],
      "changelogSource": "github",
      "changelogUpdatedAt": "2026-06-21T09:55:33.290Z"
    }
  ],
  "devices": [
    {
      "id": "ebyte-eora-s3",
      "name": "Ebyte EoRa-S3-XXXTB Radio",
      "vendorId": "ebyte",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "ebyte-ebyte-eora-s3-xxxtb-radio",
      "aliases": [
        "Ebyte EoRa-S3-900TB"
      ],
      "product_url": "https://www.cdebyte.com/products/EoRa-S3-900TB",
      "official": true,
      "refs": {
        "mesh-sh-device": "ebyte-eora-s3-900tb"
      },
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Compact ESP32-S3 + SX1262 development board with a 0.96-inch OLED, SD card slot, USB-C, and LiPo charging circuit. Suited to small MeshCore/Meshtastic builds where a low-cost board with display and rechargeable battery support is enough.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 4,
          "psramMb": 2,
          "ramKb": 2048
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "900"
            ],
            "txPowerDbm": 22,
            "antenna": "U.FL/IPEX"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "gnss": {
          "status": "none"
        },
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryChemistry": "li-po",
          "charging": true,
          "batteryConnector": "JST LiPo charging circuit (external)",
          "consumptionIdleMa": 30,
          "consumptionTxMa": 110
        },
        "physical": {
          "dimensionsMm": {
            "width": 27,
            "height": 64,
            "depth": 12
          },
          "weightG": 12
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Ebyte"
    },
    {
      "id": "thinknode-m1",
      "name": "Elecrow ThinkNode M1",
      "vendorId": "elecrow",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "elecrow-elecrow-thinknode-m1",
      "refs": {
        "mesh-sh-device": "elecrow-thinknode-m1"
      },
      "aliases": [
        "ThinkNode M1"
      ],
      "image": "thinknode_m1.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://www.elecrow.com/thinknode-m1-meshtastic-lora-signal-transceiver-powered-by-nrf52840-with-154-screen-support-gps.html",
      "price": {
        "amount": 54,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Handheld nRF52840 + SX1262 Meshtastic/MeshCore transceiver with a 1.54-inch E-Paper display, front-light, GPS, RTC, buzzer, and 1200 mAh battery. Ships in an ABS+PC enclosure with RP-SMA LoRa antenna and USB-C charging/programming.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "RP-SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "controller": "SSD1681",
          "size": 1.54,
          "resolution": {
            "width": 200,
            "height": 200
          },
          "colors": "monochrome",
          "touch": false
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "encoder",
            "description": "rotary power/backlight knob"
          },
          {
            "type": "button",
            "description": "function button (location ping, backlight, SOS, sleep)"
          },
          {
            "type": "button",
            "description": "page turn button"
          },
          {
            "type": "button",
            "description": "reset button"
          },
          {
            "type": "button",
            "description": "GPS switch"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1200,
          "batteryChemistry": "li-po",
          "charging": true,
          "consumptionIdleMa": 6,
          "consumptionTxMa": 85
        },
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 118.5,
            "height": 52.1,
            "depth": 25
          },
          "weightG": 82.5
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        },
        "certifications": [
          "FCC",
          "CE",
          "IC",
          "UL"
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Elecrow"
    },
    {
      "id": "thinknode-m2",
      "name": "Elecrow ThinkNode M2 Mini",
      "vendorId": "elecrow",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "elecrow-elecrow-thinknode-m2",
      "aliases": [
        "Elecrow ThinkNode M2",
        "ThinkNode M2 Mini",
        "ThinkNode M2"
      ],
      "image": "thinknode_m2.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://www.elecrow.com/thinknode-m2-meshtastic-lora-signal-transceiver-powered-by-esp32-s3-with-1-3-oled-display.html",
      "refs": {
        "mesh-sh-device": "elecrow-thinknode-m2"
      },
      "price": {
        "amount": 41,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Compact Meshtastic/MeshCore LoRa transceiver with ESP32-S3, SX1262, and a 1.3-inch OLED status display. Built-in 1000 mAh battery, USB-C charging, Wi-Fi, and BLE. Ships with ABS enclosure and external LoRa antenna via internal IPEX connector. Pre-flashed for Meshtastic; no GPS.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 4,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "antenna": "IPEX"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SH1106",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "PWR button"
          },
          {
            "type": "button",
            "description": "function button"
          },
          {
            "type": "button",
            "description": "BOOT button"
          },
          {
            "type": "button",
            "description": "reset button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1000,
          "batteryChemistry": "li-po",
          "batteryConnector": "JST1.25-2",
          "charging": true,
          "consumptionIdleMa": 35,
          "consumptionTxMa": 120
        },
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 88.5,
            "height": 46.3,
            "depth": 23.8
          },
          "weightG": 45.3
        },
        "environmental": {
          "operatingTempC": {
            "min": -10,
            "max": 50
          }
        },
        "certifications": [
          "FCC"
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "bridge": "CH9102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 a/b/g/n"
        }
      },
      "vendorName": "Elecrow"
    },
    {
      "id": "thinknode-m3",
      "name": "Elecrow ThinkNode M3",
      "vendorId": "elecrow",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "elecrow-elecrow-thinknode-m3",
      "aliases": [
        "ThinkNode M3",
        "ThinkNode M3 Tracker Card"
      ],
      "image": "thinknode_m3.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://www.elecrow.com/thinknode-m3-meshtastic-tracker-with-gps-wifi-ble-function-for-positioning.html",
      "refs": {
        "mesh-sh-device": "elecrow-thinknode-m3"
      },
      "price": {
        "amount": 40,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Credit-card-sized nRF52840 + LR1110 tracker for Meshtastic/MeshCore or LoRaWAN (separate firmware SKUs). GNSS plus Wi-Fi scan and BLE beacon positioning via LR1110; temperature, humidity, and accelerometer sensors. Built-in 770 mAh battery, magnetic charging, SOS button, and IP66 enclosure. No display — BLE configuration only.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "lr1110",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 20,
            "antenna": "internal"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "present"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "power / SOS"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 770,
          "batteryChemistry": "li-po",
          "batteryConnector": "magnetic",
          "charging": true,
          "consumptionIdleMa": 5,
          "consumptionTxMa": 80
        },
        "enclosure": {
          "builtIn": true,
          "ipRating": "IP66"
        },
        "physical": {
          "dimensionsMm": {
            "width": 64,
            "height": 64,
            "depth": 10
          },
          "weightG": 40
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 60
          }
        },
        "certifications": [
          "FCC",
          "CE"
        ]
      },
      "interfaces": {
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Elecrow"
    },
    {
      "id": "thinknode-m5",
      "name": "Elecrow ThinkNode M5",
      "vendorId": "elecrow",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "elecrow-elecrow-thinknode-m5",
      "refs": {
        "mesh-sh-device": "elecrow-thinknode-m5"
      },
      "aliases": [
        "ThinkNode M5"
      ],
      "image": "thinknode_m5.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://www.elecrow.com/thinknode-m5-meshtastic-lora-signal-transceiver-esp32-s3-1-54-screen-gps-function.html",
      "price": {
        "amount": 54,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Handheld ESP32-S3 + SX1262 Meshtastic/MeshCore transceiver with a 1.54-inch E-Paper display, front-light, GPS, RTC, buzzer, and 1200 mAh battery. Ships in an ABS enclosure with RP-SMA LoRa antenna and USB-C charging/programming.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 4,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "RP-SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "controller": "SSD1681",
          "size": 1.54,
          "resolution": {
            "width": 200,
            "height": 200
          },
          "colors": "monochrome",
          "touch": false
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "encoder",
            "description": "rotary power/backlight knob"
          },
          {
            "type": "button",
            "description": "function button (location ping, backlight, SOS, standby)"
          },
          {
            "type": "button",
            "description": "page turn button"
          },
          {
            "type": "button",
            "description": "reset button"
          },
          {
            "type": "button",
            "description": "GPS switch"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1200,
          "batteryChemistry": "li-po",
          "batteryConnector": "Built-in LiPo 1200mAh",
          "charging": true,
          "consumptionIdleMa": 34,
          "consumptionTxMa": 340
        },
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 78,
            "height": 52,
            "depth": 18
          },
          "weightG": 65
        },
        "environmental": {
          "operatingTempC": {
            "min": -10,
            "max": 50
          }
        },
        "certifications": [
          "FCC",
          "CE",
          "IC",
          "UL"
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Elecrow"
    },
    {
      "id": "thinknode-m6",
      "name": "Elecrow ThinkNode M6",
      "vendorId": "elecrow",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "elecrow-elecrow-thinknode-m6",
      "refs": {
        "mesh-sh-device": "elecrow-thinknode-m6"
      },
      "aliases": [
        "ThinkNode M6",
        "ThinkNode M6 Outdoor Solar Power"
      ],
      "image": "thinknode_m6.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://www.elecrow.com/thinknode-m6-outdoor-solar-power-for-meshtastic-powered-by-nrf52840-supports-gps.html",
      "price": {
        "amount": 80,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "IP65 outdoor solar Meshtastic/MeshCore node with nRF52840, SX1262 LoRa, and L76K GPS. Integrated 6W panel and ~7000 mAh dual-18650 pack; BLE configuration only — no on-device display.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "antenna": "RP-SMA"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "multifunction power button (power on/off, location update, GPS toggle)"
          },
          {
            "type": "button",
            "description": "reset button (double-click enters DFU/programming mode)"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 7000,
          "batteryChemistry": "li-ion",
          "charging": true,
          "solarInput": true,
          "solarPanelBuiltIn": true,
          "solarPanelWatts": 6,
          "consumptionIdleMa": 10,
          "consumptionTxMa": 85
        },
        "expansion": [
          {
            "type": "SP11 aviation",
            "count": 2,
            "interfaces": [
              "I2C",
              "UART"
            ]
          }
        ],
        "enclosure": {
          "builtIn": true,
          "ipRating": "IP65"
        },
        "physical": {
          "dimensionsMm": {
            "width": 210,
            "height": 156,
            "depth": 42
          },
          "weightG": 530
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 60
          }
        },
        "certifications": [
          "FCC",
          "CE"
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.4",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Elecrow"
    },
    {
      "id": "gatiot-gat562-30s",
      "name": "GAT-IoT GAT562 30s",
      "vendorId": "gatiot",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "gatiot-gat562",
      "variantOf": "gatiot-gat562",
      "aliases": [
        "GAT562 30S Mesh Kit (1W)",
        "GAT562 30s"
      ],
      "image": "gatiot_gat562_30s.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "product_url": "https://www.gat-iot.com/products/gat562-30s-mesh-kit/",
      "refs": {
        "mesh-sh-device": "gat562-30s-mesh-kit-1w"
      },
      "price": {
        "amount": 76,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 30,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "color"
        },
        "gnss": {
          "status": "present",
          "chip": "ATGM336H"
        },
        "leds": {
          "status": "present",
          "description": "RGB LEDs"
        },
        "input": [
          {
            "type": "joystick",
            "description": "4-way"
          },
          {
            "type": "button",
            "description": "user"
          },
          {
            "type": "button",
            "description": "boot"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "2x18650 holders",
          "charging": true,
          "solarInput": true,
          "batteryChemistry": "li-ion",
          "consumptionIdleMa": 15,
          "consumptionTxMa": 350
        },
        "physical": {
          "dimensionsMm": {
            "width": 100,
            "height": 65,
            "depth": 30
          },
          "weightG": 200
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "GAT-IoT"
    },
    {
      "id": "gatiot-gat562-evb-pro",
      "name": "GAT-IoT GAT562 Mesh EVB Pro",
      "vendorId": "gatiot",
      "kind": "kit",
      "lifecycle": "active",
      "familyId": "gatiot-gat562",
      "variantOf": "gatiot-gat562",
      "aliases": [
        "GAT562 Mesh EVB Pro",
        "GAT562 EVB Pro"
      ],
      "official": true,
      "datasheet": "datasheet.pdf",
      "product_url": "https://www.gat-iot.com/products/gat562-mesh-evb-pro/",
      "refs": {
        "mesh-sh-device": "gat562-mesh-evb-pro"
      },
      "price": {
        "amount": 17,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "power button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "batteryConnector": "extern (JST)",
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 60,
            "height": 40,
            "depth": 10
          },
          "weightG": 20
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "GAT-IoT"
    },
    {
      "id": "gatiot-gat562-tracker-pro",
      "name": "GAT-IoT GAT562 Mesh Tracker Pro",
      "vendorId": "gatiot",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "gatiot-gat562",
      "variantOf": "gatiot-gat562",
      "aliases": [
        "GAT562 Mesh Tracker Pro"
      ],
      "official": true,
      "refs": {
        "mesh-sh-device": "gat562-mesh-tracker-pro"
      },
      "price": {
        "amount": 39,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "internal"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display"
        },
        "gnss": {
          "status": "present"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 2500,
          "batteryChemistry": "li-ion",
          "charging": true,
          "solarInput": false,
          "batteryConnector": "Built-in Li-ion 2500mAh",
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 70,
            "height": 40,
            "depth": 20
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "GAT-IoT"
    },
    {
      "id": "gatiot-gat562-watch13",
      "name": "GAT-IoT GAT562 Mesh Watch13",
      "vendorId": "gatiot",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "gatiot-gat562",
      "variantOf": "gatiot-gat562",
      "aliases": [
        "GAT562 Watch13",
        "GAT562 Mesh Watch"
      ],
      "official": true,
      "refs": {
        "mesh-sh-device": "gat562-mesh-watch"
      },
      "price": {
        "amount": 30,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "datasheet": "datasheet.pdf",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "internal"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "size": 1.3,
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "ATGM336H"
        },
        "input": [
          {
            "type": "button",
            "description": "power"
          }
        ],
        "leds": {
          "status": "present",
          "description": "RGB status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 800,
          "batteryChemistry": "li-po",
          "charging": true,
          "solarInput": false,
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "enclosure": {
          "builtIn": true,
          "ipRating": "IP65"
        },
        "physical": {
          "dimensionsMm": {
            "width": 46,
            "height": 46,
            "depth": 14
          },
          "weightG": 60
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "GAT-IoT"
    },
    {
      "id": "gatiot-gat562",
      "name": "GAT-IoT GAT562 Tracker",
      "vendorId": "gatiot",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "gatiot-gat562",
      "aliases": [
        "GAT562 Tracker"
      ],
      "image": "gatiot_gat562.svg",
      "official": true,
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "price": {
        "amount": 49,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "ramKb": 256
        },
        "display": {
          "status": "present",
          "size": 1.3
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 2500,
          "batteryChemistry": "li-po",
          "charging": true,
          "solarInput": false
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "unknown",
          "ble": true
        },
        "wifi": {
          "status": "unknown"
        }
      },
      "vendorName": "GAT-IoT"
    },
    {
      "id": "generic-e22",
      "name": "Generic E22 SX126x",
      "kind": "generic-build",
      "lifecycle": "active",
      "familyId": "generic-e22",
      "official": true,
      "description": "Generic ESP32-based build target for SX1262 or SX1268 LoRa hardware. Used as a fallback profile for E22-family modules when a vendor-specific record is unavailable.",
      "price": {
        "amount": 12,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32",
          "ramKb": 520
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          },
          {
            "technology": "lora",
            "chip": "sx1268"
          }
        ],
        "display": {
          "status": "unknown"
        },
        "leds": {
          "status": "unknown"
        },
        "gnss": {
          "status": "unknown"
        }
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": null
    },
    {
      "id": "generic-espnow",
      "name": "Generic ESP-NOW",
      "kind": "generic-build",
      "lifecycle": "active",
      "familyId": "generic-espnow",
      "official": true,
      "price": {
        "amount": 5,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "transports": [
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-c3",
          "ramKb": 400
        },
        "display": {
          "status": "none"
        },
        "leds": {
          "status": "unknown"
        },
        "gnss": {
          "status": "none"
        }
      },
      "interfaces": {
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": null
    },
    {
      "id": "heltec-ct62",
      "name": "Heltec CT62",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-ct62",
      "aliases": [
        "Heltec CT62 (Capsule Sensor)",
        "HT-CT62"
      ],
      "product_url": "https://heltec.org/project/ht-ct62/",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "heltec-ct62-capsule-sensor"
      },
      "description": "Compact ESP32-C3 + SX1262 LoRa node module with integrated 2.4 GHz Wi-Fi, Bluetooth LE, and IPEX antenna sockets. Designed for low-power IoT use cases such as Meshtastic, MeshCore and LoRaWAN, the CT62 is a stamp-hole package with long-range LoRa connectivity and a minimal module footprint.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "wifi"
      ],
      "price": {
        "amount": 7,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "esp32-c3",
          "flashMb": 4,
          "ramKb": 400
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "extern",
          "charging": false,
          "consumptionIdleMa": 10,
          "consumptionTxMa": 80
        },
        "physical": {
          "dimensionsMm": {
            "width": 17.78,
            "height": 17.78,
            "depth": 2.8
          },
          "weightG": 2
        }
      },
      "interfaces": {
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "cubecell-htcc-ab01",
      "name": "Heltec CubeCell HTCC-AB01",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "heltec-cubecell",
      "aliases": [
        "CubeCell Board",
        "HTCC-AB01"
      ],
      "official": false,
      "description": "Ultra-low-power LoRa development board based on the ASR6601 (Cortex-M4) with integrated SX1262 radio. Designed for solar-powered and battery-operated IoT deployments.",
      "roles": [
        "repeater"
      ],
      "transports": [
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "stm32wl",
          "flashMb": 0.25
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": true,
          "consumptionIdleMa": 0.01
        }
      },
      "interfaces": {
        "usb": {
          "connector": "Micro-USB",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-t1",
      "name": "Heltec Mesh Node T1",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-mesh-node-t1",
      "product_url": "https://heltec.org/",
      "official": true,
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Compact Heltec nRF52 + SX1262 mesh target for portable low-power LoRa builds. The upstream firmware target exists, but the public product page is still sparse.",
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "none"
        },
        "leds": {
          "status": "unknown"
        },
        "gnss": {
          "status": "none"
        }
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-meshpocket",
      "name": "Heltec MeshPocket",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-meshpocket",
      "aliases": [
        "MeshPocket Qi2",
        "MeshPocket Power Bank",
        "MeshPocket Qi2 Magnetic Charging Power Bank"
      ],
      "image": "heltec_meshpocket.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "meshpocket-qi2-magnetic-charging-power-bank"
      },
      "product_url": "https://heltec.org/project/meshpocket/",
      "price": {
        "amount": 60,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Heltec MeshPocket is a compact nRF52840 + SX1262 LoRa node integrated into a power bank with Qi2 magnetic wireless charging, dual USB-C (5V input/output), and a small LCD display. Designed for Meshtastic and MeshCore portable mesh networking with 4000+ mAh battery and low-power BLE companion mode.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915"
            ],
            "txPowerDbm": 20,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-ink",
          "size": 2.13,
          "resolution": {
            "width": 122,
            "height": 250
          },
          "colors": "monochrome"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 5000,
          "charging": true,
          "batteryChemistry": "li-po",
          "pmic": "BQ25970",
          "consumptionIdleMa": 8,
          "consumptionTxMa": 164
        },
        "physical": {
          "dimensionsMm": {
            "width": 102,
            "height": 74.1,
            "depth": 17
          },
          "weightG": 220
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 1,
            "pins": 10
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-mesh-solar",
      "name": "Heltec MeshSolar / MeshTower",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-meshsolar-meshtower",
      "aliases": [
        "Heltec Mesh Solar",
        "Heltec MeshTower"
      ],
      "image": "heltec_mesh_solar.svg",
      "official": true,
      "product_url": "https://heltec.org/project/meshsolar/",
      "refs": {
        "mesh-sh-device": "heltec-mesh-solar"
      },
      "price": {
        "amount": 39,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Outdoor solar-ready power and communication platform combining a BMS board with an BLE + LoRa control board. Built for long-lived mesh deployments with solar charging, interchangeable battery chemistry support, and optional GNSS/display expansion.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "ramKb": 256
        },
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "JST LiPo + Solar",
          "charging": true,
          "solarInput": true,
          "batteryChemistry": "li-po",
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "physical": {
          "weightG": 35
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-t096",
      "name": "Heltec T096",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-t096",
      "aliases": [
        "Heltec Mesh Node T096",
        "Mesh Node T096"
      ],
      "product_url": "https://heltec.org/project/t096/",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "heltec-mesh-node-t096"
      },
      "description": "Low-power nRF52840 + SX1262 LoRa development board with integrated GNSS, Bluetooth LE, USB-C power/serial, and optional solar input. It is built for Meshtastic, MeshCore and LoRaWAN applications with external IPEX LoRa and GNSS antennas.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "price": {
        "amount": 34,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 28,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7735S",
          "size": 0.96,
          "resolution": {
            "width": 80,
            "height": 160
          },
          "colors": "color"
        },
        "gnss": {
          "status": "present",
          "chip": "UC6580"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button"
          },
          {
            "type": "button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": true,
          "batteryConnector": "SH1.25-2",
          "batteryChemistry": "li-po",
          "consumptionIdleMa": 13,
          "consumptionTxMa": 130
        },
        "physical": {
          "dimensionsMm": {
            "width": 52,
            "height": 25.4,
            "depth": 10.26
          }
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 13
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-t114",
      "name": "Heltec T114",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-t114",
      "aliases": [
        "Heltec Mesh Node T114 V2",
        "Mesh Node T114",
        "Heltec Mesh Node T114",
        "HT-n5262"
      ],
      "image": "heltec_t114.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/mesh-node-t114/",
      "refs": {
        "mesh-sh-device": "heltec-mesh-node-t114-v2"
      },
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Compact nRF52840 + SX1262 development board for Meshtastic/MeshCore and LoRaWAN. Optional 1.14-inch TFT display and L76K GNSS module, dual battery and solar connectors, IPEX-1 LoRa antenna, and USB-C. No built-in battery.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "LH114T-IF03",
          "size": 1.14,
          "resolution": {
            "width": 135,
            "height": 240
          },
          "colors": "color",
          "touch": false
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "user button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": true,
          "batteryConnector": "SH1.25-2P",
          "consumptionIdleMa": 11,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 53,
            "height": 29,
            "depth": 8
          },
          "weightG": 10
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 13
          },
          {
            "type": "connector",
            "count": 1,
            "pins": 8,
            "interfaces": [
              "GNSS"
            ]
          }
        ],
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-t190",
      "name": "Heltec T190",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "heltec-vision-master-t190",
      "aliases": [
        "Vision Master T190",
        "HT-VMT190"
      ],
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/vision-master-t190/",
      "description": "ESP32-S3R8 + optional SX1262 LoRa dev board with built-in 1.9-inch TFT (170×320, ST7789) for Meshtastic/MeshCore. USB-C, SH1.25 battery connector with charge management, SH1.0 QuickLink sensor port, and IPEX Wi-Fi/LoRa antennas. Two user buttons; no built-in GPS.",
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7789",
          "size": 1.9,
          "resolution": {
            "width": 170,
            "height": 320
          },
          "colors": "color"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "input": [
          {
            "type": "button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "solarInput": false,
          "consumptionIdleMa": 0.018
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 13
          },
          {
            "type": "quicklink-sh1.0-4p",
            "count": 1,
            "pins": 4
          }
        ],
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 60,
            "height": 25.4,
            "depth": 10.2
          },
          "weightG": 35
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 60
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-v2",
      "name": "Heltec V2",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "discontinued",
      "familyId": "heltec-wifi-lora-32",
      "revision": "2",
      "aliases": [
        "Heltec WiFi LoRa 32 V2",
        "WiFi LoRa 32 V2"
      ],
      "image": "heltec_v2.svg",
      "official": true,
      "product_url": "https://heltec.org/project/wifi-lora-32v2/",
      "datasheet": "datasheet.pdf",
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "refs": {
        "mesh-sh-device": "heltec-wifi-lora-32-v2"
      },
      "description": "Classic ESP32 + SX1276/SX1278 LoRa development board with integrated 0.96-inch OLED, Wi-Fi, and BLE. Micro USB and CP2102 serial, SH1.25 battery connector with charge management, and IPEX LoRa antenna. Phased out — Heltec recommends V3 or newer for new projects.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32",
          "flashMb": 8,
          "ramKb": 520
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1276",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 19,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "White user LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "batteryChemistry": "li-po",
          "consumptionIdleMa": 50,
          "consumptionTxMa": 125
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 18
          }
        ],
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 51,
            "height": 25.5,
            "depth": 10.6
          },
          "weightG": 35
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "Micro-USB",
          "bridge": "CP2102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "4.2",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-v3",
      "name": "Heltec V3",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "heltec-wifi-lora-32",
      "revision": "3",
      "aliases": [
        "Heltec WiFi LoRa 32 V3",
        "WiFi LoRa 32 V3"
      ],
      "replaces": "heltec-v2",
      "image": "heltec_v3.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/wifi-lora-32-v3/",
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "refs": {
        "mesh-sh-device": "heltec-wifi-lora-32-v3"
      },
      "description": "Classic ESP32-S3 + SX1262 LoRa development board with integrated 0.96-inch OLED, Wi-Fi, and BLE. USB-C power and CP2102 serial, SH1.25 battery connector with charge management, and IPEX LoRa antenna. Widely used for Meshtastic and MeshCore companion, repeater, and room-server nodes.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "batteryChemistry": "li-po",
          "consumptionIdleMa": 45,
          "consumptionTxMa": 120
        },
        "leds": {
          "status": "present",
          "description": "White user LED (GPIO35)"
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 18
          }
        ],
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 50.2,
            "height": 25.5,
            "depth": 10.2
          },
          "weightG": 35
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "bridge": "CP2102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-v4",
      "name": "Heltec V4",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "heltec-wifi-lora-32",
      "revision": "4.3",
      "aliases": [
        "Heltec WiFi LoRa 32 V4",
        "WiFi LoRa 32 V4",
        "WiFi LoRa 32 V4.3.1"
      ],
      "replaces": "heltec-v3",
      "image": "heltec_v4.svg",
      "official": true,
      "product_url": "https://heltec.org/project/wifi-lora-32-v4/",
      "datasheet": "datasheet.pdf",
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "refs": {
        "mesh-sh-device": "heltec-wifi-lora-32-v4"
      },
      "description": "ESP32-S3R2 + SX1262 successor to Heltec V3 with 16 MB flash, 2 MB PSRAM, and up to 28 dBm LoRa TX power. Same 0.96-inch OLED and largely V3-compatible pinout, plus solar input, optional GNSS header, and built-in 2.4 GHz FPC antenna. Native USB-C (no CP2102). Widely used for Meshtastic and MeshCore.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 2,
          "ramKb": 2048
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 28,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "White user LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "solarInput": true,
          "batteryChemistry": "li-po",
          "consumptionIdleMa": 20,
          "consumptionTxMa": 120
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 18
          },
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 2
          },
          {
            "type": "gnss-1.25-8",
            "count": 1,
            "pins": 8
          }
        ],
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 51.7,
            "height": 25.4,
            "depth": 10.7
          },
          "weightG": 35
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-v4-exp",
      "name": "Heltec V4 + Expansion Kit (Touch)",
      "vendorId": "heltec",
      "kind": "kit",
      "lifecycle": "active",
      "familyId": "heltec-wifi-lora-32",
      "revision": "4",
      "variantOf": "heltec-v4",
      "aliases": [
        "Heltec LoRa 32 V4 + Expansion Kit",
        "WiFi LoRa 32 Expansion Kit",
        "WiFi LoRa 32 V4 Expansion Kit"
      ],
      "image": "heltec_v4_exp.svg",
      "official": true,
      "product_url": "https://heltec.org/project/wifi-lora-32-v4-expansion-housing/",
      "datasheet": "datasheet.pdf",
      "price": {
        "amount": 50,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "refs": {
        "mesh-sh-device": "heltec-wifi-lora-32-v4-expansion-housing"
      },
      "description": "Heltec V4 kit with aluminum/PC enclosure and 320×240 touch front panel for Meshtastic/MeshCore handheld use. V4 board, expansion carrier, and LoRa antenna included; GNSS module and 18650 optional at purchase. MeshCore touch UI available; full touch input still in development.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 2,
          "ramKb": 2048
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 28,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "size": 2,
          "resolution": {
            "width": 320,
            "height": 240
          },
          "touch": true,
          "colors": "color"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "consumptionIdleMa": 20,
          "consumptionTxMa": 120
        },
        "expansion": [
          {
            "type": "b2b-female",
            "count": 1
          },
          {
            "type": "l76k-gnss",
            "count": 1
          }
        ],
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 52,
            "height": 52,
            "depth": 15
          },
          "weightG": 200
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-e213",
      "name": "Heltec Vision Master E213",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "heltec-vision-master-e213",
      "aliases": [
        "Vision Master E213",
        "HT-VME213"
      ],
      "image": "heltec_e213.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/vision-master-e213/",
      "price": {
        "amount": 20,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3R8 E-Ink development board with an optional SX1262 LoRa module and QuickLink sensor ports. Compatible with Meshtastic/MeshCore; LoRa is a build-time option, not present on every SKU.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 16,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "controller": "LCMEN2R13EFC1",
          "size": 2.13,
          "resolution": {
            "width": 250,
            "height": 122
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "solarInput": false,
          "consumptionIdleMa": 0.02
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 18
          },
          {
            "type": "quicklink-sh2.0-4p",
            "count": 2,
            "interfaces": [
              "I2C",
              "GPIO",
              "UART"
            ]
          }
        ],
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 66.75,
            "height": 30.41,
            "depth": 10
          },
          "weightG": 35
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-e290",
      "name": "Heltec Vision Master E290",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "heltec-vision-master-e290",
      "aliases": [
        "Vision Master E290",
        "HT-VME290"
      ],
      "image": "heltec_e290.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/vision-master-e290/",
      "price": {
        "amount": 21,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3R8 E-Ink development board with an optional SX1262 LoRa module, 2×20-pin Raspberry Pi-compatible female header, and a QuickLink sensor port. Compatible with Meshtastic/MeshCore; LoRa is a build-time option, not present on every SKU.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "size": 2.9,
          "resolution": {
            "width": 296,
            "height": 128
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "solarInput": false,
          "consumptionIdleMa": 0.018
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 20
          },
          {
            "type": "quicklink-sh2.0-4p",
            "count": 1,
            "interfaces": [
              "I2C",
              "GPIO",
              "UART"
            ]
          }
        ],
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 87.96,
            "height": 36.63,
            "depth": 12
          },
          "weightG": 35
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-paper",
      "name": "Heltec Wireless Paper",
      "vendorId": "heltec",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "heltec-wireless-paper",
      "aliases": [
        "Wireless Paper"
      ],
      "image": "heltec_paper.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "heltec-wireless-paper"
      },
      "product_url": "https://heltec.org/project/wireless-paper/",
      "price": {
        "amount": 16,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3FN8 + SX1262 E-Ink development board with a 2.13-inch black-and-white display. USB-C power/programming and SH1.25 battery connector; compatible with Meshtastic/MeshCore.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "size": 2.13,
          "resolution": {
            "width": 250,
            "height": 122
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "White status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "batteryChemistry": "li-po",
          "consumptionIdleMa": 0.02,
          "consumptionTxMa": 215
        },
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 88,
            "height": 88,
            "depth": 25
          },
          "weightG": 60
        },
        "environmental": {
          "operatingTempC": {
            "min": 0,
            "max": 50
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-wt2",
      "name": "Heltec Wireless Tracker v2",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-wireless-tracker",
      "revision": "2",
      "aliases": [
        "Heltec Wireless Tracker V1.1",
        "Heltec Wireless Tracker V2",
        "Wireless Tracker v2"
      ],
      "image": "heltec_wt2.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/wireless-tracker-v2/",
      "refs": {
        "mesh-sh-device": "heltec-wireless-tracker-v2"
      },
      "price": {
        "amount": 31,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3 based tracker with SX1262 LoRa, UC6580 GNSS, Wi-Fi, BLE, and a 0.96-inch 160×80 TFT display. Built for object tracking and mesh networking, with USB-C, battery management, and solar-panel support.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "865",
              "868",
              "915",
              "920",
              "923"
            ],
            "txPowerDbm": 28,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "size": 0.96,
          "resolution": {
            "width": 160,
            "height": 80
          },
          "colors": "color"
        },
        "gnss": {
          "status": "present",
          "chip": "UC6580"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "USER_SW"
          },
          {
            "type": "button",
            "description": "RST_SW"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 600,
          "batteryConnector": "Built-in 600mAh LiPo",
          "charging": true,
          "solarInput": false,
          "batteryChemistry": "li-po",
          "consumptionIdleMa": 35,
          "consumptionTxMa": 110
        },
        "physical": {
          "dimensionsMm": {
            "width": 53,
            "height": 25.4,
            "depth": 9.37
          },
          "weightG": 55
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 18
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-wt3",
      "name": "Heltec Wireless Tracker v3",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-wireless-tracker",
      "revision": "3",
      "aliases": [
        "Wireless Tracker",
        "Wireless Tracker v3"
      ],
      "replaces": "heltec-wt2",
      "image": "heltec_wt3.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/wireless-tracker/",
      "refs": {
        "mesh-sh-device": "heltec-wireless-tracker"
      },
      "price": {
        "amount": 45,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Heltec Wireless Tracker v3 is an ESP32-S3 + SX1262 LoRa tracker with built-in GNSS (GPS), 4000+ mAh battery, solar input, and optional display. Designed for Meshtastic mesh networking, IoT tracking, and LoRaWAN applications with extended outdoor operation via solar charging and efficient power management.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7735S",
          "size": 0.96,
          "resolution": {
            "width": 80,
            "height": 160
          },
          "colors": "color"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "input": [
          {
            "type": "button"
          },
          {
            "type": "button"
          }
        ],
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryCapacityMah": 4000,
          "batteryConnector": "SH1.25-2",
          "charging": true,
          "solarInput": true,
          "pmic": "AXP2101"
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 1,
            "pins": 12
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 65.48,
            "height": 28.06,
            "depth": 13.52
          },
          "weightG": 55
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "heltec-wsl3",
      "name": "Heltec WSL3",
      "vendorId": "heltec",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "heltec-wsl3",
      "image": "heltec_wsl3.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "product_url": "https://heltec.org/project/wireless-shell-v3/",
      "description": "Compact ESP32-S3 + SX1262 LoRa module with Wi-Fi and BLE, built as a stamp-hole package for embedding into custom products. The V3 revision uses a USB-C interface and a smaller low-power form factor than the classic WiFi LoRa 32 boards.",
      "price": {
        "amount": 12,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "unknown"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 0.009
        },
        "physical": {
          "dimensionsMm": {
            "width": 38.4,
            "height": 16.1,
            "depth": 2.8
          },
          "weightG": 3
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Heltec Automation"
    },
    {
      "id": "ikoka-handheld",
      "name": "Ikoka Handheld nRF",
      "vendorId": "ikoka",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "ikoka-handheld-nrf",
      "official": true,
      "refs": {
        "mesh-sh-device": "ikoka-handheld"
      },
      "aliases": [
        "Ikoka Handheld Meshtastic Device",
        "Ikoka Handheld"
      ],
      "product_url": "https://github.com/ndoo/ikoka-handheld-meshtastic-device",
      "price": {
        "amount": 40,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Long-range handheld mesh board based on XIAO nRF52840 plus an EBYTE E22 LoRa module, with a 0.96-inch OLED and optional lithium battery charging. The feature set varies with part selection, but the design targets compact companion and repeater builds.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915",
              "923"
            ],
            "txPowerDbm": 33,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "input": [
          {
            "type": "button",
            "description": "user button"
          }
        ],
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "LiPo-Pouch extern (JST PicoBlade 1.25mm)",
          "batteryChemistry": "li-po",
          "charging": true,
          "solarInput": false,
          "consumptionIdleMa": 6,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 80,
            "height": 35,
            "depth": 15
          },
          "weightG": 20
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Ikoka"
    },
    {
      "id": "ikoka-nano",
      "name": "Ikoka Nano",
      "vendorId": "ikoka",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "ikoka-nano",
      "image": "ikoka_nano.svg",
      "official": true,
      "aliases": [
        "Ikoka Nano Meshtastic Device"
      ],
      "price": {
        "amount": 39,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Compact Meshtastic node based on the Seeed XIAO nRF52840 and EBYTE E22 LoRa module. Small, battery-powered board with USB-C and Qwiic connectors; no onboard display — intended as a tiny companion/repeater or remote node.\n",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "none"
        },
        "leds": {
          "status": "unknown"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryChemistry": "other",
          "charging": true,
          "solarInput": false
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Ikoka"
    },
    {
      "id": "ikoka-stick",
      "name": "Ikoka Stick",
      "vendorId": "ikoka",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "ikoka-stick",
      "image": "ikoka_stick.svg",
      "official": true,
      "aliases": [
        "Ikoka Stick Meshtastic Device"
      ],
      "product_url": "https://github.com/ndoo/ikoka-stick-meshtastic-device",
      "price": {
        "amount": 39,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Compact mesh stick built around XIAO and EBYTE E22 options, with a 0.96-inch OLED and lithium battery charging support. The design supports both nRF52840 and ESP32-S3 variants, with LoRa power and frequency selected per build.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915",
              "923"
            ],
            "txPowerDbm": 33,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "input": [
          {
            "type": "button",
            "description": "D0 button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": false,
          "batteryChemistry": "li-ion"
        },
        "leds": {
          "status": "unknown"
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Ikoka"
    },
    {
      "id": "keepteen-lt1",
      "name": "Keepteen LT1",
      "vendorId": "keepteen",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "keepteen-keepteen-lt1",
      "image": "keepteen_lt1.svg",
      "product_url": "https://www.keepteen.com/GAT562-Pocket-Lora-Node-Radio-for-Meshtastic-Meshcore-Mesh-Tracker-with-SX1262-NRF53840-L76K-GPS-p6556031.html",
      "official": true,
      "refs": {
        "mesh-sh-device": "keepteen-lt1"
      },
      "price": {
        "amount": 49,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "863",
              "868",
              "915",
              "920",
              "923"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "size": 1.3
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "power / SOS"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 2500,
          "batteryChemistry": "li-po",
          "charging": true,
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 58,
            "height": 29,
            "depth": 130
          },
          "weightG": 130
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Keepteen"
    },
    {
      "id": "lilygo-tlora-1-6",
      "name": "LilyGo LoRa32 V2.1_1.6",
      "vendorId": "lilygo",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "lilygo-lora32-1-1-6",
      "revision": "2",
      "aliases": [
        "LoRa32 V1.6.1",
        "T3 V1.6.1"
      ],
      "image": "lilygo_tlora_1.6.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-lora32-v21-16"
      },
      "product_url": "https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series",
      "description": "ESP32-PICO-D4 + SX1276 LoRa development board with SSD1306 OLED and micro-SD slot. USB-C with CH9102 bridge and PH2.0 battery connector. No on-board BMS — use a protected Li-ion cell.",
      "price": {
        "amount": 24,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32",
          "flashMb": 4,
          "ramKb": 520
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1276",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 20,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "JST 1.25mm",
          "charging": true,
          "consumptionIdleMa": 55,
          "consumptionTxMa": 130
        },
        "physical": {
          "dimensionsMm": {
            "width": 51,
            "height": 28,
            "depth": 11
          },
          "weightG": 13
        },
        "expansion": [
          {
            "type": "micro-SD",
            "count": 1
          }
        ],
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "bridge": "CH9102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "4.2",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t-beam-sx1262",
      "name": "LilyGo T-Beam (SX1262)",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-beam",
      "revision": "1.2",
      "aliases": [
        "T-Beam SX1262",
        "T-Beam V1.2 SX1262"
      ],
      "image": "lilygo_tbeam.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-beam-sx1262"
      },
      "product_url": "https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series",
      "price": {
        "amount": 41,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32 + SX1262 LoRa tracker with built-in u-blox GNSS, SSD1306 OLED, and AXP2101 power management. USB-C with CH9102 bridge; external IPEX LoRa and Wi-Fi antennas. Widely used for Meshtastic/MeshCore companion and repeater nodes.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32",
          "flashMb": 4,
          "psramMb": 8,
          "ramKb": 520
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "NEO-6"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "PWR/PMU button (power on/off, customizable)"
          },
          {
            "type": "button",
            "description": "user button (IO38, customizable)"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "pmic": "AXP2101",
          "batteryChemistry": "li-ion",
          "batteryConnector": "18650 Holder",
          "solarInput": true,
          "consumptionIdleMa": 50,
          "consumptionTxMa": 120
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 18
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 75,
            "height": 33,
            "depth": 15
          },
          "weightG": 50
        },
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "bridge": "CH9102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "4.2",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t-beam-1-2-sx1276",
      "name": "LilyGo T-Beam 1.2 (SX1276)",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-beam",
      "revision": "1.2",
      "aliases": [
        "LilyGo T-Beam V1.2 (SX1276)",
        "T-Beam 1.2 SX1276",
        "T-Beam V1.2 SX1276"
      ],
      "image": "lilygo_tbeam.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-beam-v12-sx1276"
      },
      "product_url": "https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series",
      "price": {
        "amount": 41,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32 + SX1276 LoRa tracker with built-in u-blox GNSS, SSD1306 OLED, and AXP2101 power management. USB-C with CH9102 bridge; external IPEX LoRa and Wi-Fi antennas. The SX1276 variant of the T-Beam family, widely used for Meshtastic/MeshCore companion and repeater nodes.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32",
          "flashMb": 4,
          "psramMb": 8,
          "ramKb": 520
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1276",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 20,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "NEO-6"
        },
        "input": [
          {
            "type": "button",
            "description": "PWR/PMU button (power on/off, customizable)"
          },
          {
            "type": "button",
            "description": "user button (IO38, customizable)"
          }
        ],
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "18650 Holder",
          "charging": true,
          "pmic": "AXP2101",
          "solarInput": true,
          "consumptionIdleMa": 55,
          "consumptionTxMa": 130
        },
        "physical": {
          "dimensionsMm": {
            "width": 75,
            "height": 33,
            "depth": 15
          },
          "weightG": 50
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 18
          }
        ],
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "bridge": "CH9102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "4.2",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-tbeam-1w",
      "name": "LilyGo T-Beam 1W",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-beam",
      "aliases": [
        "T-Beam 1W"
      ],
      "product_url": "https://lilygo.cc/en-us/products/t-beam-1w",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-beam-1w"
      },
      "price": {
        "amount": 47,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3 T-Beam variant with higher-power LoRa front end, GNSS, OLED, and an 18650 battery bay. Designed for long-range mesh nodes where a 1 W class radio and the standard T-Beam layout are desired.",
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915"
            ],
            "txPowerDbm": 32,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SH1106",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": false,
          "pmic": "AXP2101",
          "batteryConnector": "18650 Holder",
          "consumptionIdleMa": 60,
          "consumptionTxMa": 500
        },
        "physical": {
          "dimensionsMm": {
            "width": 120,
            "height": 50,
            "depth": 20
          },
          "weightG": 80
        },
        "input": [
          {
            "type": "button",
            "description": "boot"
          },
          {
            "type": "button",
            "description": "reset"
          },
          {
            "type": "button",
            "description": "power"
          },
          {
            "type": "button",
            "description": "io03"
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-tbeam-supreme",
      "name": "LilyGo T-Beam Supreme (SX1262)",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-beam",
      "revision": "supreme",
      "aliases": [
        "T-Beam Supreme",
        "T-Beam S3 Supreme"
      ],
      "image": "lilygo_tbeam_supreme.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-beam-supreme-sx1262"
      },
      "product_url": "https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series",
      "description": "ESP32-S3 + SX1262 LoRa tracker with L76K GNSS, SH1106 OLED, and a rich sensor suite (QMI8658 IMU, QMC6310 magnetometer, BME280, PCF8563 RTC). AXP2101 power management, M.2 socket, and micro-SD expansion. USB-C with CH9102 bridge.",
      "price": {
        "amount": 40,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SH1106",
          "size": 1.13,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "PWR/PMU button (power on/off, customizable)"
          },
          {
            "type": "button",
            "description": "BOOT button (boot mode, customizable)"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "pmic": "AXP2101",
          "batteryConnector": "JST + 18650 Holder",
          "solarInput": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 70,
            "height": 30,
            "depth": 15
          },
          "weightG": 25
        },
        "expansion": [
          {
            "type": "M.2",
            "count": 1,
            "interfaces": [
              "USB",
              "UART",
              "I2C",
              "GPIO"
            ]
          },
          {
            "type": "qwiic",
            "count": 1,
            "interfaces": [
              "I2C"
            ]
          },
          {
            "type": "micro-SD",
            "count": 1
          }
        ],
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "bridge": "CH9102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t-deck",
      "name": "LilyGo T-Deck",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-deck",
      "aliases": [
        "T-Deck"
      ],
      "image": "lilygo_tdeck.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-deck"
      },
      "product_url": "https://lilygo.cc/en-us/products/t-deck",
      "price": {
        "amount": 43,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Pocket Meshtastic/MeshCore handheld with ESP32-S3, optional SX1262 LoRa, 2.8-inch IPS display, mini QWERTY keyboard, and trackball. Built-in microphone and speaker for standalone messaging and UI. Wi-Fi and BLE; no built-in GPS (external module optional).",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915"
            ],
            "txPowerDbm": 22
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7789",
          "size": 2.8,
          "resolution": {
            "width": 320,
            "height": 240
          },
          "colors": "color"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "keyboard",
            "description": "mini QWERTY"
          },
          {
            "type": "trackball"
          },
          {
            "type": "microphone"
          },
          {
            "type": "speaker"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 2000,
          "batteryChemistry": "li-po",
          "charging": true,
          "consumptionIdleMa": 80,
          "consumptionTxMa": 140
        },
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 140,
            "height": 70,
            "depth": 25
          },
          "weightG": 145
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "bridge": "CH9102",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t-deck-community",
      "name": "LilyGo T-Deck (community)",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-deck",
      "variantOf": "lilygo-t-deck",
      "aliases": [
        "T-Deck community build"
      ],
      "image": "lilygo_tdeck.svg",
      "official": true,
      "product_url": "https://lilygo.cc/en-us/products/t-deck",
      "price": {
        "amount": 43,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Community firmware build of the LilyGo T-Deck handheld, inheriting the same ESP32-S3, SX1262, 2.8-inch IPS display, and keyboard/trackball layout as the retail T-Deck.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915"
            ],
            "txPowerDbm": 22
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7789",
          "size": 2.8,
          "resolution": {
            "width": 320,
            "height": 240
          },
          "colors": "color"
        },
        "gnss": {
          "status": "none"
        },
        "input": [
          {
            "type": "keyboard",
            "description": "mini QWERTY"
          },
          {
            "type": "trackball"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "charging": true,
          "solarInput": false
        },
        "enclosure": {
          "builtIn": true
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-tdeck-pro",
      "name": "LilyGo T-Deck Pro",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-deck",
      "revision": "pro",
      "aliases": [
        "T-Deck Pro"
      ],
      "image": "lilygo_tdeck_pro.svg",
      "product_url": "https://lilygo.cc/en-us/products/t-deck-pro",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-deck-pro"
      },
      "price": {
        "amount": 103,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 2048
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "display": {
          "status": "present",
          "technology": "e-paper",
          "controller": "GDEQ031T10",
          "size": 3.1,
          "resolution": {
            "width": 320,
            "height": 240
          },
          "touch": true,
          "colors": "grayscale"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1400,
          "batteryChemistry": "li-po",
          "charging": true,
          "solarInput": false,
          "consumptionIdleMa": 50,
          "consumptionTxMa": 120
        },
        "physical": {
          "dimensionsMm": {
            "width": 140,
            "height": 72,
            "depth": 12
          },
          "weightG": 135
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-tdisplay-p4",
      "name": "LilyGo T-Display P4",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-display-p4",
      "aliases": [
        "T-Display-P4"
      ],
      "image": "lilygo_tdisplay_p4.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-display-p4"
      },
      "product_url": "https://github.com/Xinyuan-LilyGO/T-Display-P4",
      "description": "ESP32-P4 development board with a 4.05″ MIPI TFT touchscreen (540×1168), SX1262 LoRa, L76K GNSS, MIPI camera, speaker, microphone, and ICM20948 IMU. Auxiliary ESP32-C6-MINI-1U provides WiFi 6 and BLE 5.0. Ships in AMOLED and TFT display variants; optional keyboard expansion adds a physical QWERTY keyboard with CC1101/NRF24L01/NFC radios.",
      "price": {
        "amount": 124,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-p4",
          "flashMb": 16,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "HI8561",
          "size": 4.05,
          "resolution": {
            "width": 540,
            "height": 1168
          },
          "colors": "color",
          "touch": true
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "microphone"
          },
          {
            "type": "speaker"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryChemistry": "li-ion",
          "charging": true,
          "pmic": "LGS4056H",
          "consumptionIdleMa": 35,
          "consumptionTxMa": 110
        },
        "physical": {
          "dimensionsMm": {
            "width": 80,
            "height": 45,
            "depth": 10
          },
          "weightG": 30
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 a/b/g/n/ac/ax"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-tdisplay",
      "name": "LilyGo T-Display Pro",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-display",
      "image": "lilygo_tdisplay.svg",
      "product_url": "https://lilygo.cc/en-us/products/t-display-s3-pro",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-display-pro"
      },
      "price": {
        "amount": 47,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7796",
          "size": 2.33,
          "resolution": {
            "width": 222,
            "height": 480
          },
          "colors": "color",
          "touch": true
        },
        "gnss": {
          "status": "unknown"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryChemistry": "li-po",
          "charging": true,
          "consumptionIdleMa": 45,
          "consumptionTxMa": 80
        },
        "physical": {
          "dimensionsMm": {
            "width": 65,
            "height": 35,
            "depth": 8
          },
          "weightG": 16
        },
        "input": [
          {
            "type": "button",
            "description": "boot button"
          },
          {
            "type": "button",
            "description": "reset button"
          },
          {
            "type": "button",
            "description": "io12 button"
          },
          {
            "type": "button",
            "description": "io16 button"
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-techo",
      "name": "LilyGo T-Echo",
      "refs": {
        "mesh-sh-device": "lilygo-t-echo"
      },
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-echo",
      "aliases": [
        "T-Echo",
        "T-Echo LILYGO"
      ],
      "image": "lilygo_techo.svg",
      "official": true,
      "product_url": "https://lilygo.cc/en-us/products/t-echo-lilygo",
      "price": {
        "amount": 45,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Ultra-low-power nRF52840 + SX1262 Meshtastic/MeshCore handheld with a 1.54-inch e-paper display and built-in L76K GNSS. Bluetooth 5 only, with an optional BME280 environmental sensor variant and ABS enclosure.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 2,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915",
              "920-923MHz"
            ],
            "txPowerDbm": 22
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "controller": "SSD1680",
          "size": 1.54,
          "resolution": {
            "width": 200,
            "height": 200
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1100,
          "batteryChemistry": "li-po",
          "batteryConnector": "MX1.25-2",
          "charging": true,
          "consumptionIdleMa": 8,
          "consumptionTxMa": 90
        },
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 66,
            "height": 53.5,
            "depth": 24
          },
          "weightG": 131
        },
        "certifications": [
          "FCC",
          "CE",
          "MIC"
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-techo-card",
      "name": "LilyGo T-Echo Card",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-echo-card",
      "aliases": [
        "T-Echo Card"
      ],
      "official": true,
      "product_url": "https://github.com/Xinyuan-LilyGO/T-Echo-Card",
      "price": {
        "amount": 45,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Low-power nRF52840 + SX1262 card-sized node with a 0.42-inch OLED, L76K GNSS, ICM20948 IMU, speaker, microphone, and WS2812 LED. Solar panel for continuous power supply. Bluetooth 5 only - no Wi-Fi.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.42,
          "resolution": {
            "width": 72,
            "height": 40
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "WS2812 status LED"
        },
        "input": [
          {
            "type": "microphone"
          },
          {
            "type": "speaker"
          }
        ],
        "power": {
          "batterySupported": false,
          "charging": false,
          "solarInput": true,
          "solarPanelBuiltIn": true,
          "batteryConnector": "none"
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-techo-lite",
      "name": "LilyGo T-Echo Lite",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-echo",
      "variantOf": "lilygo-techo",
      "aliases": [
        "T-Echo Lite"
      ],
      "image": "lilygo_techo_lite.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-echo-lite"
      },
      "product_url": "https://lilygo.cc/en-us/products/t-echo-lite",
      "price": {
        "amount": 27,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Lightweight nRF52840 + SX1262 Meshtastic/MeshCore node with a 1.22-inch e-paper display for ultra-low power use. Core/base split design with optional shell, solar charging, and external L76K GPS module. Bluetooth 5 only — no Wi-Fi. Optional KeyShield base adds keyboard, speaker, and microphone.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "controller": "SSD1681",
          "size": 1.22,
          "resolution": {
            "width": 176,
            "height": 192
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": true,
          "consumptionIdleMa": 6,
          "consumptionTxMa": 85
        },
        "expansion": [
          {
            "type": "l76k-gnss",
            "count": 1
          }
        ],
        "enclosure": {
          "builtIn": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 50,
            "height": 30,
            "depth": 8
          },
          "weightG": 8
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-teth-elite",
      "name": "LilyGo T-ETH Elite",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-eth-elite",
      "aliases": [
        "T-ETH Elite"
      ],
      "official": true,
      "product_url": "https://lilygo.cc/en-us/products/t-eth-elite-1",
      "price": {
        "amount": 23,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3R8 board with Wi-Fi, BLE, and built-in Ethernet via W5500, designed for always-on wired IoT gateways and automation projects. USB-C power, PoE support, and soldered headers make it a compact network-first controller.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "ethernet",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "physical": {
          "dimensionsMm": {
            "width": 50,
            "height": 67
          }
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t-impulse-plus",
      "name": "LilyGo T-Impulse Plus",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-impulse",
      "product_url": "https://www.lilygo.cc/",
      "official": true,
      "description": "Low-power nRF52840 wristband with SX1262 LoRa, a 64x32 OLED, GPS, and a touch-button wake flow. Built for wearable MeshCore companions with very low deep-sleep current.",
      "price": {
        "amount": 37,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1315",
          "resolution": {
            "width": 64,
            "height": 32
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "MIA-M10Q"
        },
        "leds": {
          "status": "present",
          "description": "Status LED"
        }
      },
      "interfaces": {
        "bluetooth": {
          "version": "unknown",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-tlora-c6",
      "name": "LilyGo T-LoRa C6",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-lora-c6",
      "aliases": [
        "LilyGo T-Lora C6"
      ],
      "product_url": "https://lilygo.cc/en-us/products/t-lora-c6",
      "price": {
        "amount": 17,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-lora-c6"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-c6",
          "flashMb": 4,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ]
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "BOOT"
          },
          {
            "type": "button",
            "description": "RESET"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 33,
            "height": 29,
            "depth": 6
          },
          "weightG": 6
        },
        "power": {
          "batterySupported": false,
          "charging": false,
          "consumptionIdleMa": 5,
          "consumptionTxMa": 90
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 ax"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-pager",
      "name": "LilyGo T-Lora Pager",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-lora-pager",
      "aliases": [
        "T-Lora Pager"
      ],
      "image": "lilygo_pager.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-lora-pager"
      },
      "product_url": "https://lilygo.cc/en-us/products/t-lora-pager",
      "price": {
        "amount": 87,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3 handheld Meshtastic/MeshCore pager with SX1262 LoRa, 2.33-inch IPS display, QWERTY keyboard, and rotary encoder. Built-in u-blox MIA-M10Q GNSS, 1500 mAh battery, microphone/speaker, NFC, and BHI260AP AI IMU. Wi-Fi and BLE. Optional LR1121 or other radio variants available at purchase.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915",
              "920"
            ],
            "txPowerDbm": 22,
            "antenna": "foldable"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7796",
          "size": 2.33,
          "resolution": {
            "width": 222,
            "height": 480
          },
          "colors": "color"
        },
        "gnss": {
          "status": "present",
          "chip": "MIA-M10Q"
        },
        "input": [
          {
            "type": "keyboard",
            "description": "QWERTY"
          },
          {
            "type": "encoder"
          },
          {
            "type": "microphone"
          },
          {
            "type": "speaker"
          }
        ],
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1200,
          "batteryConnector": "Built-in LiPo 1200mAh",
          "charging": true,
          "pmic": "BQ25896",
          "consumptionIdleMa": 45,
          "consumptionTxMa": 115
        },
        "expansion": [
          {
            "type": "microsd",
            "count": 1
          }
        ],
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 110,
            "height": 55,
            "depth": 14
          },
          "weightG": 75
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-twatch-s3",
      "name": "LilyGo T-Watch S3",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-watch-s3",
      "aliases": [
        "T-Watch S3"
      ],
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-watch-s3"
      },
      "product_url": "https://lilygo.cc/en-us/products/t-watch-s3",
      "price": {
        "amount": 43,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915",
              "920"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7789",
          "size": 1.54,
          "resolution": {
            "width": 240,
            "height": 240
          },
          "colors": "color",
          "touch": true
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "physical": {
          "dimensionsMm": {
            "width": 46,
            "height": 46,
            "depth": 12
          },
          "weightG": 55
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 580,
          "batteryChemistry": "li-po",
          "charging": true,
          "solarInput": false,
          "batteryConnector": "Built-in LiPo 580mAh",
          "consumptionIdleMa": 40,
          "consumptionTxMa": 110
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-twatch-plus",
      "name": "LilyGo T-Watch S3 Plus",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t-watch-s3",
      "aliases": [
        "T-Watch S3 Plus",
        "T-Watch-S3-Plus"
      ],
      "image": "lilygo_twatch_plus.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t-watch-s3-plus"
      },
      "product_url": "https://lilygo.cc/products/t-watch-s3-plus",
      "price": {
        "amount": 59,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "ESP32-S3 smartwatch with SX1262 LoRa, 1.3-inch IPS touchscreen, and built-in GNSS (u-blox MIA-M10Q or Quectel LS550G). AXP2101 power management, BMA423 accelerometer, haptic driver, microphone, speaker, and IR transmitter.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7789",
          "size": 1.3,
          "resolution": {
            "width": 240,
            "height": 240
          },
          "colors": "color",
          "touch": true
        },
        "gnss": {
          "status": "present",
          "chip": "MIA-M10Q"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "physical": {
          "dimensionsMm": {
            "width": 46,
            "height": 46,
            "depth": 12
          },
          "weightG": 60
        },
        "input": [
          {
            "type": "microphone"
          },
          {
            "type": "speaker"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 940,
          "batteryChemistry": "li-po",
          "charging": true,
          "pmic": "AXP2101",
          "consumptionIdleMa": 40,
          "consumptionTxMa": 110
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "Micro-USB",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t3-s3-sx126x",
      "name": "LilyGo T3 S3 (SX126x)",
      "vendorId": "lilygo",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "lilygo-t3-s3",
      "aliases": [
        "T3 S3 SX126x",
        "T3-S3 SX1262",
        "LilyGo T3 S3 (SX1262)"
      ],
      "image": "lilygo_t3s3.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t3-s3-sx1262"
      },
      "product_url": "https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series",
      "description": "Compact ESP32-S3 + SX1262 LoRa development board with SSD1306 OLED, micro-SD slot, and Qwiic expansion connector. USB-C with PH2.0 battery connector and optional solar input (V1.3). No on-board BMS — use a protected Li-ion cell.",
      "price": {
        "amount": 24,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 4,
          "psramMb": 2,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 21,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "BOOT button (boot mode, customizable)"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "PH2.0",
          "charging": true,
          "solarInput": true,
          "consumptionIdleMa": 25,
          "consumptionTxMa": 105
        },
        "expansion": [
          {
            "type": "qwiic",
            "count": 1,
            "interfaces": [
              "I2C",
              "UART",
              "GPIO"
            ]
          },
          {
            "type": "micro-SD",
            "count": 1
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 75,
            "height": 36,
            "depth": 8
          },
          "weightG": 15
        },
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t3-s3-sx127x",
      "name": "LilyGo T3 S3 (SX127x)",
      "vendorId": "lilygo",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "lilygo-t3-s3",
      "aliases": [
        "T3 S3 SX127x",
        "T3-S3 SX1276",
        "LilyGo T3 S3 (SX1276)"
      ],
      "image": "lilygo_t3s3.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t3-s3-sx1276"
      },
      "product_url": "https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series",
      "description": "Compact ESP32-S3 + SX1276 LoRa development board with SSD1306 OLED, micro-SD slot, and Qwiic expansion connector. USB-C with PH2.0 battery connector and optional solar input (V1.3). No on-board BMS — use a protected Li-ion cell.",
      "price": {
        "amount": 24,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 4,
          "psramMb": 2,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1276",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 20,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "BOOT button (boot mode, customizable)"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "PH2.0",
          "charging": true,
          "solarInput": true,
          "consumptionIdleMa": 25,
          "consumptionTxMa": 105
        },
        "expansion": [
          {
            "type": "qwiic",
            "count": 1,
            "interfaces": [
              "I2C",
              "UART",
              "GPIO"
            ]
          },
          {
            "type": "micro-SD",
            "count": 1
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 75,
            "height": 36,
            "depth": 8
          },
          "weightG": 15
        },
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "lilygo-t5-pro",
      "name": "LilyGo T5 E-Paper S3 Pro (H752-XX)",
      "vendorId": "lilygo",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "lilygo-t5-s3",
      "image": "lilygo_t5_pro.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "lilygo-t5-e-paper-s3-pro"
      },
      "product_url": "https://lilygo.cc/en-us/products/t5-e-paper-s3-pro",
      "price": {
        "amount": 84,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "aliases": [
        "LilyGo T5 E-Paper S3 Pro",
        "T5 E-Paper S3 Pro"
      ],
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "868",
              "915"
            ],
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-paper",
          "controller": "ED047TC1",
          "size": 4.7,
          "resolution": {
            "width": 540,
            "height": 960
          },
          "colors": "grayscale",
          "touch": true
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1500,
          "batteryChemistry": "li-po",
          "charging": true,
          "pmic": "BQ25896",
          "consumptionIdleMa": 25,
          "consumptionTxMa": 110
        },
        "physical": {
          "dimensionsMm": {
            "width": 120,
            "height": 75,
            "depth": 10
          },
          "weightG": 95
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "LilyGO"
    },
    {
      "id": "m5stack-unit-c6l",
      "name": "M5Stack Unit C6L",
      "vendorId": "m5stack",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "m5stack-m5stack-unit-c6l",
      "official": true,
      "refs": {
        "mesh-sh-device": "m5stack-unit-c6l"
      },
      "price": {
        "amount": 23,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "product_url": "https://docs.m5stack.com/en/unit/Unit_C6L",
      "datasheet": "datasheet.pdf",
      "description": "ESP32-C6 LoRa unit with an onboard SX1262 radio, OLED status display, RGB indicator, buzzer, and a user button. The official documentation highlights Wi-Fi 6, Meshtastic support, and the pair of RP-SMA antenna connectors.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-c6",
          "flashMb": 16,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.66,
          "resolution": {
            "width": 64,
            "height": 48
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "RGB indicator + status LED"
        },
        "input": [
          {
            "type": "button",
            "description": "user button"
          }
        ],
        "power": {
          "batterySupported": false,
          "charging": false,
          "consumptionIdleMa": 1,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 62,
            "height": 24,
            "depth": 8
          },
          "weightG": 13.6
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 ax"
        }
      },
      "vendorName": "M5Stack"
    },
    {
      "id": "meshadventurer",
      "name": "MeshAdventurer",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "meshadventurer",
      "aliases": [
        "Meshadventurer"
      ],
      "official": true,
      "product_url": "https://github.com/chrismyers2000/MeshAdventurer",
      "price": {
        "amount": 28,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "DIY off-road ESP32 + E22 LoRa board with a 0.96-inch SSD1306 OLED, rotary encoder UI, GPS, and optional BME280 sensor support. Built for 1 W 433 or 868/915 MHz builds with an external SMA antenna and wide-range 9-28V input.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32",
          "ramKb": 520
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 30,
            "antenna": "SMA"
          },
          {
            "technology": "lora",
            "chip": "sx1268",
            "frequencyVariants": [
              "433"
            ],
            "txPowerDbm": 30,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "ATGM336H"
        },
        "input": [
          {
            "type": "button",
            "description": "user button"
          },
          {
            "type": "encoder",
            "description": "rotary encoder with push switch"
          }
        ],
        "leds": {
          "status": "unknown"
        },
        "power": {
          "batterySupported": false,
          "solarInput": true,
          "pmic": "CJ7805"
        },
        "expansion": [
          {
            "type": "header-2.54",
            "count": 2,
            "pins": 19
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "Micro-USB",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "4.2",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": null
    },
    {
      "id": "meshtiny",
      "name": "Meshtiny",
      "vendorId": "mtools",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "mtools-meshtiny",
      "product_url": "https://meshtiny.com/product/meshtiny/",
      "official": true,
      "price": {
        "amount": 60,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SSD1306",
          "size": 0.96,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "encoder",
            "description": "up/down encoder"
          },
          {
            "type": "button",
            "description": "user button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 250,
          "batteryChemistry": "li-po",
          "charging": true,
          "solarInput": false
        },
        "physical": {
          "dimensionsMm": {
            "width": 51.7,
            "height": 25.4,
            "depth": 10.7
          }
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 70
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "MTools Tec"
    },
    {
      "id": "minewsemi-me25ls01",
      "name": "MinewSemi ME25LS01",
      "vendorId": "minewsemi",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "minewsemi-minewsemi-me25ls01",
      "product_url": "https://en.minewsemi.com/lora-module/lr1110-nrf52840-me25LS01",
      "datasheet": "datasheet.pdf",
      "official": true,
      "price": {
        "amount": 11,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "lr1110",
            "txPowerDbm": 22
          }
        ],
        "display": {
          "status": "unknown"
        },
        "gnss": {
          "status": "present",
          "chip": "unknown"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 10.7,
          "consumptionTxMa": 118
        },
        "physical": {
          "dimensionsMm": {
            "width": 25.5,
            "height": 20,
            "depth": 2.5
          }
        }
      },
      "interfaces": {
        "bluetooth": {
          "version": "5.4",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "MinewSemi"
    },
    {
      "id": "muziworks-r1-neo",
      "name": "Muzi Works R1 Neo",
      "vendorId": "muziworks",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "muziworks-muzi-works-r1-neo",
      "official": true,
      "refs": {
        "mesh-sh-device": "muzi-works-r1-neo"
      },
      "price": {
        "amount": 40,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "unknown"
        },
        "gnss": {
          "status": "present"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1500,
          "batteryChemistry": "li-po",
          "charging": true,
          "batteryConnector": "Built-in LiPo 1500mAh",
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "enclosure": {
          "builtIn": true,
          "ipRating": "IP68"
        },
        "physical": {
          "dimensionsMm": {
            "width": 58,
            "height": 63,
            "depth": 18
          },
          "weightG": 84
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Muzi Works"
    },
    {
      "id": "nibble-screen-connect",
      "name": "Nibble Screen Connect",
      "vendorId": "nibble",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "nibble-nibble-screen-connect",
      "official": true,
      "product_url": "https://retia.io/products/nibble-screen-connect",
      "price": {
        "amount": 50,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Breadboard-friendly Nibble node with a built-in screen, buttons, and a through-hole expansion layout aimed at MeshCore and Meshtastic hacking. The design pairs a Waveshare ESP32-S3 Zero with a Seeed Wio SX1262 radio module.",
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "SSD1306",
          "size": 0.92,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Indicator LED"
        },
        "input": [
          {
            "type": "button",
            "description": "user button"
          },
          {
            "type": "button",
            "description": "reset button"
          }
        ],
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false
        }
      },
      "interfaces": {
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Nibble"
    },
    {
      "id": "nrf54l15",
      "name": "Nordic nRF54L15 DK",
      "vendorId": "nordic",
      "kind": "dev-board",
      "lifecycle": "unknown",
      "familyId": "nordic-nordic-nrf54l15-dk",
      "official": false,
      "price": {
        "amount": 35,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "nrf54l15",
          "ramKb": 256,
          "flashMb": 1.5
        },
        "display": {
          "status": "unknown"
        },
        "gnss": {
          "status": "unknown"
        }
      },
      "interfaces": {
        "wifi": {
          "status": "unknown"
        }
      },
      "vendorName": "Nordic Semiconductor"
    },
    {
      "id": "faketec",
      "name": "ProMicro nrf52 (faketec)",
      "vendorId": "promicro",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "promicro-nrf52",
      "aliases": [
        "ProMicro nRF52"
      ],
      "image": "faketec.svg",
      "official": true,
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "price": {
        "amount": 13,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "ramKb": 256
        },
        "display": {
          "status": "unknown"
        },
        "leds": {
          "status": "unknown"
        },
        "gnss": {
          "status": "unknown"
        }
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "unknown",
          "ble": true
        },
        "wifi": {
          "status": "unknown"
        }
      },
      "vendorName": "Pro Micro"
    },
    {
      "id": "rak-11310",
      "name": "RAK 11310",
      "vendorId": "rak",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "rak-11310",
      "aliases": [
        "RAK11310 WisBlock Core"
      ],
      "official": true,
      "refs": {
        "mesh-sh-device": "rak11310-wisblock-core"
      },
      "description": "WisBlock core module with RP2040 and SX1262 LoRa for compact mesh builds on WisBlock base boards. No Wi-Fi or BLE on board; designed to be combined with WisBlock communication modules and external antennas.",
      "price": {
        "amount": 10,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "rp2040",
          "ramKb": 264,
          "flashMb": 2
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "865",
              "868",
              "915",
              "920",
              "923"
            ],
            "antenna": "IPEX-1.0"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 20,
            "height": 30,
            "depth": 2
          }
        },
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": true,
          "batteryConnector": "WisBlock Battery Connector",
          "consumptionIdleMa": 15,
          "consumptionTxMa": 90
        }
      },
      "interfaces": {
        "usb": {
          "connector": "none",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "RAKwireless"
    },
    {
      "id": "rak-3x72",
      "name": "RAK 3x72",
      "vendorId": "rak",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "rak-3x72",
      "product_url": "https://store.rakwireless.com/products/wisduo-lpwan-module-rak3172",
      "official": true,
      "price": {
        "amount": 6,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "WisDuo LPWAN module based on STM32WL with an integrated LoRa transceiver for compact mesh builds and embedded devices. The MeshCore profile targets bare module integration rather than a finished handheld or display device.",
      "hardware": {
        "mcu": {
          "model": "stm32wl",
          "flashMb": 0.25,
          "ramKb": 64
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "stm32wl",
            "frequencyVariants": [
              "433",
              "470",
              "865",
              "868",
              "915",
              "920",
              "923"
            ],
            "txPowerDbm": 22,
            "antenna": "U.FL/IPEX"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 5.22,
          "consumptionTxMa": 87
        },
        "certifications": [
          "CE",
          "FCC",
          "ISED",
          "UKCA"
        ]
      },
      "interfaces": {
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "RAKwireless"
    },
    {
      "id": "rak-4631",
      "name": "RAK WisBlock / WisMesh (RAK 4631)",
      "vendorId": "rak",
      "kind": "module",
      "lifecycle": "active",
      "familyId": "rak-wisblock",
      "aliases": [
        "RAK4631 WisBlock Core",
        "RAK4631",
        "WisBlock Core RAK4631",
        "RAK4631-R"
      ],
      "image": "rak_4631.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "rak4631-wisblock-core"
      },
      "price": {
        "amount": 18,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "product_url": "https://docs.rakwireless.com/Product-Categories/WisBlock/RAK4631/Overview/",
      "description": "WisBlock Core module pairing an nRF52840 MCU with an SX1262 LoRa transceiver (RAK4630 stamp), designed to plug into a WisBlock base board (RAK5005-O / RAK19007). BLE 5.0, 22 dBm LoRa output, and 2.0 µA sleep current. The basis of the RAK WisMesh Base, WisMesh Tap, and Meshtastic Starter Kit.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "433",
              "470",
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "IPEX-1.0"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "WisBlock Battery Connector",
          "charging": true,
          "solarInput": true,
          "consumptionIdleMa": 12,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 30,
            "height": 20,
            "depth": 3
          },
          "weightG": 5
        },
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 85
          }
        },
        "certifications": [
          "FCC",
          "CE",
          "ISED",
          "KCC",
          "RCM"
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "Micro-USB",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "RAKwireless"
    },
    {
      "id": "rak-3112",
      "name": "RAK WisBlock 3112",
      "vendorId": "rak",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "rak-wisblock",
      "aliases": [
        "RAK3112"
      ],
      "image": "rak_3112.svg",
      "official": true,
      "product_url": "https://docs.rakwireless.com/product-categories/wisduo/rak3112-module/overview/",
      "description": "ESP32-S3 WisDuo module combining BLE, Wi-Fi, and SX1262 LoRa for compact MeshCore and Meshtastic builds. The datasheet covers regional LoRa bands, pinout, and certification details for the module.",
      "price": {
        "amount": 16,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "865",
              "868",
              "915",
              "920",
              "923"
            ],
            "txPowerDbm": 20
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 4.82,
          "consumptionTxMa": 87
        }
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "RAKwireless"
    },
    {
      "id": "rak-13302",
      "name": "RAK WisMesh 1W Booster (3401 + 13302)",
      "vendorId": "rak",
      "kind": "kit",
      "lifecycle": "active",
      "familyId": "rak-wisblock",
      "aliases": [
        "RAK3401 WisBlock (1W Booster)",
        "WisMesh 1W Booster",
        "RAK3401 + RAK13302"
      ],
      "image": "rak_13302.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "rak3401-wisblock-1w-booster"
      },
      "price": {
        "amount": 39,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "product_url": "https://docs.rakwireless.com/product-categories/wisblock/rak13302/overview/",
      "description": "WisBlock 1 W LoRa booster kit pairing the RAK3401 carrier with the RAK13302 LPWAN module and SKY66122 RF amplifier. The kit is aimed at longer-range LoRa operation in the 902-928 MHz band.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "902-928"
            ],
            "txPowerDbm": 30
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": true,
          "batteryConnector": "WisBlock Battery Connector",
          "consumptionIdleMa": 15,
          "consumptionTxMa": 350
        },
        "physical": {
          "dimensionsMm": {
            "width": 30,
            "height": 20,
            "depth": 5
          },
          "weightG": 8
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "RAKwireless"
    },
    {
      "id": "rak-wismesh-pocket-v2",
      "name": "RAK WisMesh Pocket V2",
      "vendorId": "rak",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "rak-wismesh-pocket-v2",
      "official": true,
      "product_url": "https://store.rakwireless.com/products/wismesh-pocket",
      "refs": {
        "mesh-sh-device": "rak-wismesh-pocket-v2"
      },
      "price": {
        "amount": 90,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 3200,
          "batteryChemistry": "li-ion",
          "charging": true,
          "consumptionIdleMa": 10,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 90,
            "height": 55,
            "depth": 20
          },
          "weightG": 95
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "RAKwireless"
    },
    {
      "id": "rak-wismesh-tag",
      "name": "RAK WisMesh Tag",
      "vendorId": "rak",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "rak-wismesh",
      "aliases": [
        "WisMesh Tag",
        "WisMesh Tap",
        "RAK10701"
      ],
      "image": "rak_wismesh_tag.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "rak-wismesh-tag"
      },
      "price": {
        "amount": 39,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "product_url": "https://docs.rakwireless.com/Product-Categories/Meshtastic/WisMesh-Tap/Quickstart/",
      "description": "All-in-one Meshtastic node based on the RAK10701 Field Tester, with a 320×240 TFT touchscreen and on-screen keyboard for phone-free messaging. nRF52840 + SX1262, integrated GNSS, 3200 mAh battery, and RP-SMA LoRa antenna. Pre-flashed with Meshtastic firmware.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "RP-SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "size": 2.8,
          "resolution": {
            "width": 320,
            "height": 240
          },
          "colors": "color",
          "touch": true
        },
        "gnss": {
          "status": "present",
          "chip": "MIA-M10Q"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "power button (hold 5s on/off, double-click forced uplink, single-click sleep/wake)"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 3200,
          "batteryChemistry": "li-po",
          "batteryConnector": "JST1.25-2",
          "charging": true,
          "consumptionIdleMa": 5,
          "consumptionTxMa": 82
        },
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 100,
            "height": 75,
            "depth": 38
          },
          "weightG": 244
        },
        "environmental": {
          "operatingTempC": {
            "min": -10,
            "max": 60
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "RAKwireless"
    },
    {
      "id": "rpi-pico2w-waveshare-sx1262",
      "name": "Raspberry Pi Pico2 W + Waveshare SX1262",
      "vendorId": "raspberry",
      "kind": "kit",
      "lifecycle": "active",
      "familyId": "raspberry-pi-pico2-w-waveshare-sx1262",
      "official": true,
      "refs": {
        "mesh-sh-device": "raspberry-pi-pico2-w-waveshare-sx1262"
      },
      "price": {
        "amount": 20,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Raspberry Pi Pico2 W paired with a Waveshare SX1262 LoRa HAT for compact MeshCore/Meshtastic builds. RP2350 + Wi-Fi/BLE on the Pico2 W, external antenna on the HAT, and a simple USB-powered kit format for low-cost testing.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "rp2350",
          "flashMb": 4,
          "ramKb": 520
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "On-board status LED"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 20,
          "consumptionTxMa": 100
        },
        "physical": {
          "dimensionsMm": {
            "width": 51,
            "height": 21
          },
          "weightG": 15
        }
      },
      "interfaces": {
        "usb": {
          "connector": "Micro-USB",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": "Raspberry Pi"
    },
    {
      "id": "rpi-picow",
      "name": "RPI Pico 2040 + WaveShare SX1262",
      "vendorId": "raspberry",
      "kind": "kit",
      "lifecycle": "active",
      "familyId": "raspberry-rpi-pico-2040-waveshare",
      "image": "rpi_picow.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "description": "Raspberry Pi Pico 2040 paired with a WaveShare SX1262 LoRa board for lightweight MeshCore and Meshtastic experimentation. The kit emphasizes USB flashing and a small RP2040 footprint over integrated display or GNSS hardware.",
      "price": {
        "amount": 6,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "rp2040",
          "flashMb": 2,
          "ramKb": 264
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "none"
        }
      },
      "interfaces": {
        "usb": {
          "connector": "Micro-USB",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "unknown",
          "ble": false
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Raspberry Pi"
    },
    {
      "id": "sensecap-indicator-espnow",
      "name": "Seeed Studio SenseCAP Indicator ESP-NOW",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-sensecap-indicator-esp-now",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/sensecap_indicator_meshtastic/",
      "price": {
        "amount": 61,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "standalone-ui"
      ],
      "description": "4-inch SenseCAP Indicator touchscreen platform for firmware experiments and mesh-network control panels. The Meshtastic-capable version pairs ESP32-S3 and RP2040 MCUs with Wi-Fi, BLE, LoRa, and a capacitive RGB touch display.",
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "862-930"
            ],
            "txPowerDbm": 27
          }
        ],
        "display": {
          "status": "present",
          "technology": "display",
          "controller": "ST7701S",
          "size": 3.95,
          "resolution": {
            "width": 480,
            "height": 480
          },
          "colors": "color",
          "touch": true
        },
        "gnss": {
          "status": "none"
        },
        "input": [
          {
            "type": "button",
            "description": "power / wake / reset button"
          }
        ],
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "sensecap-solar-p1",
      "name": "Seeed Studio SenseCAP Solar Node P1",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-sensecap-solar",
      "aliases": [
        "SenseCAP Solar Node P1",
        "SenseCAP Solar P1"
      ],
      "image": "sensecap_solar.svg",
      "official": true,
      "product_url": "https://www.seeedstudio.com/SenseCAP-Solar-Node-P1-for-Meshtastic-LoRa-p-6425.html",
      "refs": {
        "mesh-sh-device": "sensecap-solar-node-p1"
      },
      "price": {
        "amount": 66,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Economical solar-powered Meshtastic/MeshCore node or repeater for outdoor deployment. Integrates XIAO nRF52840 Plus and Wio-SX1262 with a built-in 5W solar panel and IPX6 enclosure. Four 18650 battery slots (cells not included) and optional XIAO L76K GPS module; no built-in GPS or batteries.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "2dBi rod"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryChemistry": "li-ion",
          "charging": true,
          "solarInput": true,
          "solarPanelBuiltIn": true,
          "solarPanelWatts": 5,
          "pmic": "CN3165",
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "expansion": [
          {
            "type": "grove",
            "count": 1,
            "interfaces": [
              "I2C",
              "GPIO",
              "UART"
            ]
          }
        ],
        "enclosure": {
          "builtIn": true,
          "ipRating": "IPX6"
        },
        "physical": {
          "dimensionsMm": {
            "width": 191.2,
            "height": 201.2,
            "depth": 42.1
          }
        },
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 60
          }
        },
        "certifications": [
          "FCC",
          "CE"
        ],
        "input": [
          {
            "type": "button",
            "description": "power button"
          },
          {
            "type": "button",
            "description": "reset button"
          },
          {
            "type": "button",
            "description": "user-defined button"
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "sensecap-solar-p1-pro",
      "name": "Seeed Studio SenseCAP Solar Node P1-Pro",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-sensecap-solar",
      "variantOf": "sensecap-solar-p1",
      "aliases": [
        "SenseCAP Solar Node P1 Pro",
        "SenseCAP Solar Node P1-Pro",
        "SenseCAP Solar P1-Pro"
      ],
      "image": "sensecap_solar.svg",
      "official": true,
      "product_url": "https://www.seeedstudio.com/SenseCAP-Solar-Node-P1-Pro-for-Meshtastic-LoRa-p-6412.html",
      "refs": {
        "mesh-sh-device": "sensecap-solar-node-p1-pro"
      },
      "price": {
        "amount": 96,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Solar-powered Meshtastic/MeshCore node or repeater with built-in XIAO L76K GNSS and four pre-installed 3350 mAh 18650 batteries. Same XIAO nRF52840 Plus and Wio-SX1262 core as the P1, plus a 5W solar panel and IPX6 outdoor enclosure with Grove expansion port.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "2dBi rod"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 13400,
          "batteryChemistry": "li-ion",
          "charging": true,
          "solarInput": true,
          "solarPanelBuiltIn": true,
          "solarPanelWatts": 5,
          "pmic": "CN3165",
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "expansion": [
          {
            "type": "grove",
            "count": 1,
            "interfaces": [
              "I2C",
              "GPIO",
              "UART"
            ]
          }
        ],
        "enclosure": {
          "builtIn": true,
          "ipRating": "IPX6"
        },
        "physical": {
          "dimensionsMm": {
            "width": 191.2,
            "height": 201.2,
            "depth": 42.1
          }
        },
        "environmental": {
          "operatingTempC": {
            "min": -40,
            "max": 60
          }
        },
        "certifications": [
          "FCC",
          "CE"
        ],
        "input": [
          {
            "type": "button",
            "description": "power button"
          },
          {
            "type": "button",
            "description": "reset button"
          },
          {
            "type": "button",
            "description": "user-defined button"
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "sensecap-t1000e",
      "name": "Seeed Studio SenseCAP T1000-E",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-sensecap-t1000-e",
      "aliases": [
        "SenseCAP Card Tracker T1000-E",
        "SenseCAP T1000-E",
        "T1000-E"
      ],
      "image": "sensecap_t1000e.svg",
      "datasheet": "datasheet.pdf",
      "official": true,
      "refs": {
        "mesh-sh-device": "sensecap-card-tracker-t1000-e"
      },
      "product_url": "https://www.seeedstudio.com/SenseCAP-Card-Tracker-T1000-E-for-Meshtastic-p-5913.html",
      "price": {
        "amount": 40,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Credit-card-sized Meshtastic/MeshCore tracker with nRF52840, Semtech LR1110 LoRa (863–928 MHz), and MediaTek AG3335 GNSS. Built-in 700 mAh battery, temperature and light sensors, buzzer, and IP65 enclosure. Charges via included magnetic USB cable; BLE configuration only — no display or Wi-Fi.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "lr1110",
            "frequencyVariants": [
              "863-928MHz"
            ],
            "antenna": "internal"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "present",
          "chip": "AG3335"
        },
        "leds": {
          "status": "present",
          "description": "Green status LED and buzzer"
        },
        "input": [
          {
            "type": "button"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 700,
          "batteryConnector": "magnetic-4pin",
          "charging": true
        },
        "enclosure": {
          "builtIn": true,
          "ipRating": "IP65"
        },
        "physical": {
          "dimensionsMm": {
            "width": 85,
            "height": 55,
            "depth": 6.5
          },
          "weightG": 32
        },
        "environmental": {
          "operatingTempC": {
            "min": -20,
            "max": 60
          }
        },
        "certifications": [
          "FCC",
          "CE"
        ]
      },
      "interfaces": {
        "bluetooth": {
          "version": "5.1",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "wio-tracker-l1",
      "name": "Seeed Studio Wio Tracker L1",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-wio-tracker-l1",
      "official": true,
      "product_url": "https://www.seeedstudio.com/Wio-Tracker-L1-p-6453.html",
      "price": {
        "amount": 33,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Low-power Meshtastic/MeshCore dev board with LoRa, L76K GNSS, a 1.3-inch OLED status display, and 4-way joystick. Supports USB-C, solar, and external Li-ion battery via JST connector. Board only — no integrated battery or enclosure.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "862-930MHz"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SH1106",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "joystick",
            "description": "4-way"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": true,
          "batteryConnector": "JST 1.0mm Li-ion",
          "batteryChemistry": "li-ion",
          "consumptionIdleMa": 5,
          "consumptionTxMa": 85
        },
        "enclosure": {
          "builtIn": false
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "wio-tracker-l1-eink",
      "name": "Seeed Studio Wio Tracker L1 E-ink",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-wio-tracker-l1",
      "variantOf": "wio-tracker-l1",
      "image": "wio_tracker_l1_eink.svg",
      "official": true,
      "product_url": "https://www.seeedstudio.com/Wio-Tracker-L1-E-ink-p-6456.html",
      "price": {
        "amount": 36,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Low-power Meshtastic/MeshCore node with LoRa, L76K GNSS, and a detachable 2.13-inch E-ink display for ultra-low-power status updates. Supports USB-C, solar, and Li-ion battery power.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "862-930MHz"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "e-ink",
          "controller": "SSD1680",
          "size": 2.13,
          "resolution": {
            "width": 122,
            "height": 250
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryChemistry": "li-ion",
          "charging": true,
          "solarInput": true
        },
        "enclosure": {
          "builtIn": false
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "wio-tracker-l1-pro",
      "name": "Seeed Studio Wio Tracker L1 Pro",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-wio-tracker-l1",
      "variantOf": "wio-tracker-l1",
      "image": "wio_tracker_l1.svg",
      "official": true,
      "aliases": [
        "Seeed Wio Tracker L1 Pro"
      ],
      "product_url": "https://www.seeedstudio.com/Wio-Tracker-L1-Pro-p-6454.html",
      "refs": {
        "mesh-sh-device": "seeed-wio-tracker-l1-pro"
      },
      "price": {
        "amount": 43,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Ready-to-use Meshtastic/MeshCore handheld with the same L1 board inside a durable enclosure, 1.3-inch OLED, built-in 2000 mAh battery, 4-way joystick, and L76K GNSS. Supports USB-C and solar charging.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "862-930MHz"
            ]
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "controller": "SH1106",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "L76K"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "joystick",
            "description": "4-way"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 2000,
          "batteryChemistry": "li-ion",
          "charging": true,
          "solarInput": true,
          "consumptionIdleMa": 5,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 60,
            "height": 35,
            "depth": 20
          },
          "weightG": 45
        },
        "enclosure": {
          "builtIn": true
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "wio-e5-dev",
      "name": "Seeed Studio Wio-E5 Dev Board",
      "vendorId": "seeed",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "seeed-wio-e5-dev-board",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/LoRa_E5_Dev_Board/",
      "description": "Compact Wio-E5 development board for STM32WLE5JC / LoRaWAN prototyping with external antenna and GPIO breakouts. Intended for quick bring-up and radio testing rather than a finished enclosure.",
      "transports": [
        "usb"
      ],
      "price": {
        "amount": 27,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "stm32wl",
          "flashMb": 0.25,
          "ramKb": 64
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "stm32wl",
            "frequencyVariants": [
              "868",
              "915",
              "923"
            ],
            "txPowerDbm": 22
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "batteryConnector": "2*AA battery holder",
          "batteryChemistry": "alkaline",
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 0.0021
        },
        "input": [
          {
            "type": "button",
            "description": "Boot"
          },
          {
            "type": "button",
            "description": "Reset"
          }
        ]
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "wio-e5-mini",
      "name": "Seeed Studio Wio-E5 mini",
      "vendorId": "seeed",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "seeed-wio-e5-mini",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/LoRa_E5_mini/",
      "description": "Compact Wio-E5 LoRaWAN development board with factory AT firmware support and a tiny 50 × 23 mm form factor. Intended for quick LoRa bring-up and GPIO-level prototyping rather than a finished enclosure.",
      "transports": [
        "usb"
      ],
      "price": {
        "amount": 22,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "stm32wl",
          "flashMb": 0.25,
          "ramKb": 64
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "stm32wl",
            "frequencyVariants": [
              "868",
              "915",
              "923"
            ],
            "txPowerDbm": 22
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 0.0021
        },
        "input": [
          {
            "type": "button",
            "description": "Boot"
          },
          {
            "type": "button",
            "description": "Reset"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 50,
            "height": 23
          }
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "xiao-esp32c3",
      "name": "Seeed Studio Xiao C3",
      "vendorId": "seeed",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "seeed-xiao-c3",
      "aliases": [
        "Seeed XIAO C3 + Wio-SX1262",
        "XIAO C3 + Wio-SX1262"
      ],
      "image": "xiao_esp32c3.svg",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/XIAO_ESP32C3_Getting_Started/",
      "refs": {
        "mesh-sh-device": "seeed-xiao-c3-wio-sx1262"
      },
      "roles": [
        "companion",
        "repeater"
      ],
      "description": "Thumb-sized ESP32-C3 board used as the host board in the Seeed XIAO C3 + Wio-SX1262 kit. The base board provides Wi-Fi, BLE, USB flashing, and a compact GPIO footprint; LoRa comes from the separate Wio-SX1262 module.",
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-c3",
          "ramKb": 400
        },
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "User LED"
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 22,
            "antenna": "PCB"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "batteryConnector": "JST 1.25mm (extern)",
          "consumptionIdleMa": 10,
          "consumptionTxMa": 85
        },
        "physical": {
          "dimensionsMm": {
            "width": 22,
            "height": 21,
            "depth": 15
          },
          "weightG": 3
        }
      },
      "price": {
        "amount": 10,
        "asOf": "2026-06"
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "unknown",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "xiao-esp32c6",
      "name": "Seeed Studio Xiao C6",
      "vendorId": "seeed",
      "kind": "dev-board",
      "lifecycle": "unknown",
      "familyId": "seeed-xiao-c6",
      "image": "xiao_esp32c6.svg",
      "official": false,
      "product_url": "https://wiki.seeedstudio.com/xiao_esp32c6_getting_started/",
      "description": "Thumb-sized ESP32-C6 XIAO board with Wi-Fi 6, BLE 5, and Thread/Zigbee-capable radio support. MeshCore uses it as a compact companion or repeater host with the Wio-SX1262 LoRa module attached.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-c6",
          "flashMb": 4,
          "ramKb": 400
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ]
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "User LED and charge LED"
        },
        "input": [
          {
            "type": "button",
            "description": "Boot"
          },
          {
            "type": "button",
            "description": "Reset"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 21,
            "height": 17.8
          }
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": false,
          "batteryChemistry": "other",
          "batteryConnector": "solder pads"
        }
      },
      "price": {
        "amount": 10,
        "asOf": "2026-06"
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.3",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 ax"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "xiao-esp32s3-plain",
      "name": "Seeed Studio XIAO ESP32S3",
      "vendorId": "seeed",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "seeed-xiao",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/",
      "description": "Thumb-sized ESP32-S3 XIAO board with Wi-Fi, BLE, USB flashing, and onboard user/charge LEDs. A compact host board for wireless and sensor projects, with battery charging support and the standard XIAO expansion footprint.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "User LED and charge LED"
        },
        "input": [
          {
            "type": "button",
            "description": "Boot"
          },
          {
            "type": "button",
            "description": "Reset"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 21,
            "height": 17.8
          }
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": false
        }
      },
      "price": {
        "amount": 10,
        "asOf": "2026-06"
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "xiao-nrf52",
      "name": "Seeed Studio Xiao nRF52 WIO",
      "vendorId": "seeed",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "seeed-xiao-wio",
      "aliases": [
        "Seeed XIAO nRF52840 + Wio-SX1262 Kit",
        "XIAO nRF52840 + Wio-SX1262 Kit"
      ],
      "image": "xiao_nrf52.svg",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/XIAO_BLE/",
      "refs": {
        "mesh-sh-device": "seeed-xiao-nrf52840-wio-sx1262-kit"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "description": "Thumb-sized nRF52840 board used as the host board in the Seeed XIAO nRF52840 + Wio-SX1262 kit. The base board provides BLE, USB flashing, and a compact wearable-friendly footprint; LoRa comes from the separate Wio-SX1262 module.",
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "input": [
          {
            "type": "button",
            "description": "Boot"
          },
          {
            "type": "button",
            "description": "Reset"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 21,
            "height": 17.8
          }
        },
        "leds": {
          "status": "present",
          "description": "User/status LED"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": false,
          "batteryConnector": "JST-PH 2-pin (external)"
        }
      },
      "price": {
        "amount": 13,
        "asOf": "2026-06"
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "xiao-rp2040",
      "name": "Seeed Studio XIAO RP2040",
      "vendorId": "seeed",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "seeed-xiao",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/XIAO-RP2040/",
      "description": "Tiny RP2040 XIAO board with USB flashing, a 14-pin footprint, and the standard Seeed user and charge LEDs. Suited to small companion-side controller projects and lightweight peripheral glue logic.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "rp2040",
          "flashMb": 2,
          "ramKb": 264
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "input": [
          {
            "type": "button",
            "description": "Boot"
          },
          {
            "type": "button",
            "description": "Reset"
          }
        ],
        "leds": {
          "status": "present",
          "description": "User LED, power LED, and RGB LED"
        },
        "physical": {
          "dimensionsMm": {
            "width": 21,
            "height": 17.8
          }
        },
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false
        }
      },
      "price": {
        "amount": 9,
        "asOf": "2026-06"
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "xiao-esp32s3",
      "name": "Seeed Studio Xiao S3 WIO",
      "vendorId": "seeed",
      "kind": "dev-board",
      "lifecycle": "active",
      "familyId": "seeed-xiao-s3-wio",
      "image": "xiao_esp32s3.svg",
      "official": true,
      "product_url": "https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/",
      "description": "Thumb-sized ESP32-S3 XIAO host board paired with the Wio-SX1262 LoRa module. Provides Wi-Fi, BLE, USB flashing, and the same compact Seeed XIAO footprint for tiny MeshCore companion and repeater builds.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 8,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "User LED and charge LED"
        },
        "input": [
          {
            "type": "button",
            "description": "Boot"
          },
          {
            "type": "button",
            "description": "Reset"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 21,
            "height": 17.8
          }
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": false,
          "charging": true,
          "solarInput": false,
          "batteryChemistry": "other",
          "batteryConnector": "solder pads"
        }
      },
      "price": {
        "amount": 10,
        "asOf": "2026-06"
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "tenstar-c3",
      "name": "Tenstar C3",
      "vendorId": "tenstar",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "tenstar-tenstar-c3",
      "official": true,
      "price": {
        "amount": 7,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-c3",
          "ramKb": 400
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          },
          {
            "technology": "lora",
            "chip": "sx1268"
          }
        ],
        "display": {
          "status": "none"
        },
        "leds": {
          "status": "unknown"
        },
        "gnss": {
          "status": "none"
        }
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present"
        }
      },
      "vendorName": "Tenstar Robot"
    },
    {
      "id": "tiny-relay",
      "name": "Tiny Relay",
      "vendorId": "yaoyao",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "yaoyao-tiny-relay",
      "product_url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wle5cc.html",
      "official": true,
      "price": {
        "amount": 5,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Minimal STM32WLE5CC relay target for MeshCore builds, intended for tiny always-on nodes and experimentation with a low-cost LoRa-enabled MCU.",
      "transports": [
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "stm32wl",
          "flashMb": 0.25,
          "ramKb": 64
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "stm32wl"
          }
        ],
        "display": {
          "status": "none"
        },
        "leds": {
          "status": "unknown"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 4.82,
          "consumptionTxMa": 87
        }
      },
      "interfaces": {
        "usb": {
          "connector": "unknown",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "YAOYAO"
    },
    {
      "id": "nano-g2",
      "name": "UnitEng Nano G2 Ultra",
      "vendorId": "uniteng",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "uniteng-nano-g2-ultra",
      "image": "nano_g2.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "nano-g2-ultra"
      },
      "aliases": [
        "Nano G2 Ultra"
      ],
      "product_url": "https://wiki.bqvoy.com/en/meshtastic/nano-g2-ultra",
      "price": {
        "amount": 86,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Pocket nRF52840 tracker with SX1262 LoRa, 1.3-inch OLED, GPS, buzzer, and a built-in 1200 mAh battery. Intended for MeshCore companion/repeater use with Bluetooth 5.4 and a compact on/off-switch form factor.",
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 2,
          "ramKb": 256
        },
        "display": {
          "status": "present",
          "technology": "oled",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "present",
          "chip": "ATGM336H"
        },
        "leds": {
          "status": "present",
          "description": "Status LED and buzzer indicator"
        },
        "input": [
          {
            "type": "button",
            "description": "program"
          },
          {
            "type": "button",
            "description": "message read"
          },
          {
            "type": "button",
            "description": "gps on/off"
          },
          {
            "type": "button",
            "description": "led or buzzer"
          },
          {
            "type": "button",
            "description": "power on/off"
          }
        ],
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 1200,
          "batteryChemistry": "li-po",
          "charging": true,
          "solarInput": false,
          "consumptionIdleMa": 8,
          "consumptionTxMa": 90
        },
        "physical": {
          "dimensionsMm": {
            "width": 75,
            "height": 40,
            "depth": 15
          },
          "weightG": 55
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.4",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "UnitEng"
    },
    {
      "id": "station-g2",
      "name": "UnitEng Station G2",
      "vendorId": "uniteng",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "uniteng-station-g2",
      "image": "station_g2.svg",
      "official": true,
      "refs": {
        "mesh-sh-device": "station-g2"
      },
      "price": {
        "amount": 109,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "product_url": "https://wiki.uniteng.com/en/meshtastic/station-g2",
      "aliases": [
        "Station G2"
      ],
      "description": "Station-class ESP32-S3 mesh device with a high-power LoRa front end, tuned for improved receive sensitivity and 35 dBm transmit capability. Intended for fixed installations or vehicle mounting with an external antenna.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "ramKb": 512,
          "flashMb": 16
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 35,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "size": 1.3,
          "resolution": {
            "width": 128,
            "height": 64
          },
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "present",
          "description": "Status LEDs"
        },
        "input": [
          {
            "type": "button",
            "description": "power button"
          }
        ],
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "batteryConnector": "extern (Netzteil)",
          "consumptionIdleMa": 250,
          "consumptionTxMa": 3550
        },
        "physical": {
          "dimensionsMm": {
            "width": 85,
            "height": 50,
            "depth": 25
          },
          "weightG": 150
        }
      },
      "interfaces": {
        "usb": {
          "connector": "none",
          "capabilities": [
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        }
      },
      "vendorName": "UnitEng"
    },
    {
      "id": "station-g3",
      "name": "UnitEng Station G3 ESP32",
      "vendorId": "uniteng",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "uniteng-station-g3",
      "description": "Modular Station board with an ESP32-S3 MCU daughterboard, an RF daughterboard, and a 1.3-inch OLED display. Designed for external 9-19 V power input and firmware compatibility with Station G2 profiles.",
      "product_url": "https://wiki.bqvoy.com/en/devkits/station-g3",
      "official": true,
      "price": {
        "amount": 109,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "roles": [
        "companion",
        "repeater",
        "room-server",
        "standalone-ui"
      ],
      "transports": [
        "ble",
        "usb",
        "wifi"
      ],
      "hardware": {
        "mcu": {
          "model": "esp32-s3",
          "flashMb": 16,
          "psramMb": 8,
          "ramKb": 512
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868",
              "915"
            ],
            "txPowerDbm": 35,
            "antenna": "SMA"
          }
        ],
        "display": {
          "status": "present",
          "technology": "oled",
          "size": 1.3,
          "colors": "monochrome"
        },
        "gnss": {
          "status": "none"
        },
        "input": [
          {
            "type": "button",
            "description": "Program"
          },
          {
            "type": "button",
            "description": "Firmware Download"
          },
          {
            "type": "button",
            "description": "Restart"
          }
        ],
        "physical": {
          "dimensionsMm": {
            "width": 110,
            "height": 58,
            "depth": 22
          },
          "weightG": 87.5
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "batteryConnector": "extern (Netzteil)"
        },
        "expansion": [
          {
            "type": "grove",
            "count": 2,
            "interfaces": [
              "I2C",
              "GPIO",
              "UART"
            ]
          },
          {
            "type": "qwiic",
            "count": 1,
            "interfaces": [
              "I2C"
            ]
          }
        ]
      },
      "interfaces": {
        "wifi": {
          "status": "present",
          "standard": "802.11 b/g/n"
        },
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        }
      },
      "vendorName": "UnitEng"
    },
    {
      "id": "waveshare-rp2040-lora",
      "name": "Waveshare RP2040-LoRa",
      "vendorId": "waveshare",
      "kind": "product",
      "lifecycle": "active",
      "familyId": "waveshare-waveshare-lora",
      "official": true,
      "price": {
        "amount": 13,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "hardware": {
        "mcu": {
          "model": "rp2040",
          "ramKb": 264
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262"
          }
        ],
        "display": {
          "status": "unknown"
        },
        "gnss": {
          "status": "unknown"
        }
      },
      "interfaces": {
        "wifi": {
          "status": "unknown"
        }
      },
      "vendorName": "Waveshare"
    },
    {
      "id": "wio-wm1110",
      "name": "Wio WM1110",
      "vendorId": "seeed",
      "kind": "module",
      "lifecycle": "active",
      "familyId": "seeed-wio-wm1110",
      "aliases": [
        "Seeed Studio Wio WM1110",
        "Wio-WM1110",
        "Wio-WM1110 Wireless Module"
      ],
      "official": true,
      "product_url": "https://www.seeedstudio.com/Wio-WM1110-Module-LR1110-and-nRF52840-p-5676.html",
      "transports": [
        "ble"
      ],
      "price": {
        "amount": 10,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Fusion-positioning module pairing LR1110 with nRF52840 for long-range IoT, BLE, and passive Wi-Fi/GNSS scanning. Compact 20×20 mm bare module intended as the radio core for tracking and geolocation designs, with no display or enclosure.",
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "lr1110",
            "frequencyVariants": [
              "865",
              "868",
              "915",
              "920",
              "923"
            ],
            "txPowerDbm": 20
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "leds": {
          "status": "none"
        },
        "power": {
          "batterySupported": false,
          "batteryBuiltIn": false,
          "charging": false,
          "solarInput": false,
          "consumptionIdleMa": 0.0076,
          "consumptionTxMa": 125
        },
        "physical": {
          "dimensionsMm": {
            "width": 20,
            "height": 20,
            "depth": 2.3
          }
        },
        "certifications": [
          "FCC",
          "CE",
          "TELEC"
        ]
      },
      "interfaces": {
        "bluetooth": {
          "version": "5.3",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "Seeed Studio"
    },
    {
      "id": "uart-solar-node-station",
      "name": "μArt.cz Solar Node Station",
      "vendorId": "uart-cz",
      "kind": "product",
      "lifecycle": "discontinued",
      "familyId": "uart-cz-solar-node",
      "variantOf": "rak-4631",
      "datasheet": "datasheet.pdf",
      "official": false,
      "product_url": "https://lectronz.com/products/fully-assembled-meshtastic-solar-node-station",
      "price": {
        "amount": 183,
        "currency": "USD",
        "asOf": "2026-06"
      },
      "description": "Fully assembled outdoor solar Meshtastic/MeshCore node built on the μArt Solar Mesh baseboard (RAK4630, RAK4631-compatible firmware). Ships with a 10 W panel and bundled battery; MPPT solar input 7–30 V.",
      "roles": [
        "companion",
        "repeater",
        "room-server"
      ],
      "transports": [
        "ble",
        "usb"
      ],
      "hardware": {
        "mcu": {
          "model": "nrf52840",
          "flashMb": 1,
          "ramKb": 256
        },
        "radios": [
          {
            "technology": "lora",
            "chip": "sx1262",
            "frequencyVariants": [
              "868"
            ],
            "txPowerDbm": 22,
            "antenna": "RP-SMA"
          }
        ],
        "display": {
          "status": "none"
        },
        "gnss": {
          "status": "none"
        },
        "power": {
          "batterySupported": true,
          "batteryBuiltIn": true,
          "batteryCapacityMah": 3000,
          "batteryChemistry": "other",
          "charging": true,
          "solarInput": true,
          "solarPanelBuiltIn": true,
          "solarPanelWatts": 10,
          "consumptionIdleMa": 8,
          "consumptionTxMa": 85
        },
        "expansion": [
          {
            "type": "IP-rated connector",
            "count": 2,
            "interfaces": [
              "I2C",
              "UART"
            ]
          }
        ],
        "enclosure": {
          "builtIn": true
        },
        "physical": {
          "dimensionsMm": {
            "width": 120,
            "height": 80,
            "depth": 50
          },
          "weightG": 21
        }
      },
      "interfaces": {
        "usb": {
          "connector": "USB-C",
          "capabilities": [
            "power",
            "serial",
            "flashing"
          ]
        },
        "bluetooth": {
          "version": "5.0",
          "ble": true
        },
        "wifi": {
          "status": "none"
        }
      },
      "vendorName": "μArt.cz"
    }
  ],
  "vendors": [
    {
      "id": "ebyte",
      "name": "Ebyte",
      "website": "https://www.cdebyte.com",
      "country": "China",
      "deviceCount": 1
    },
    {
      "id": "elecrow",
      "name": "Elecrow",
      "website": "https://www.elecrow.com",
      "country": "China",
      "logo": "logo.png",
      "description": "Electronics manufacturer producing the ThinkNode MeshCore handhelds.\n",
      "deviceCount": 5
    },
    {
      "id": "espressif",
      "name": "Espressif",
      "website": "https://www.espressif.com",
      "country": "China",
      "deviceCount": 0
    },
    {
      "id": "gatiot",
      "name": "GAT-IoT",
      "website": "http://www.gat-iot.com",
      "country": "China",
      "description": "Maker of the GAT562 tracker hardware.\n",
      "deviceCount": 5
    },
    {
      "id": "heltec",
      "name": "Heltec Automation",
      "website": "https://heltec.org",
      "country": "China",
      "logo": "logo.png",
      "description": "Maker of affordable ESP32 and nRF52 LoRa development boards widely used across the MeshCore ecosystem.\n",
      "deviceCount": 18
    },
    {
      "id": "ikoka",
      "name": "Ikoka",
      "website": "https://github.com/ndoo/ikoka-nano-meshtastic-device",
      "country": "Singapore",
      "description": "Maker of compact Ikoka Nano / Stick mesh nodes.\n",
      "deviceCount": 3
    },
    {
      "id": "keepteen",
      "name": "Keepteen",
      "website": "https://www.keepteen.com",
      "country": "China",
      "logo": "logo.png",
      "description": "Maker of the Keepteen LT1 node.\n",
      "deviceCount": 1
    },
    {
      "id": "lilygo",
      "name": "LilyGO",
      "website": "https://lilygo.cc",
      "country": "China",
      "logo": "logo.jpg",
      "description": "Maker of integrated LoRa handhelds and dev boards (T-Beam, T-Deck, T-Echo, …).\n",
      "deviceCount": 22
    },
    {
      "id": "m5stack",
      "name": "M5Stack",
      "website": "https://m5stack.com",
      "country": "China",
      "deviceCount": 1
    },
    {
      "id": "minewsemi",
      "name": "MinewSemi",
      "website": "https://en.minewsemi.com",
      "country": "China",
      "deviceCount": 1
    },
    {
      "id": "mtools",
      "name": "MTools Tec",
      "website": "https://shop.mtoolstec.com",
      "deviceCount": 1
    },
    {
      "id": "muziworks",
      "name": "Muzi Works",
      "deviceCount": 1
    },
    {
      "id": "nibble",
      "name": "Nibble",
      "deviceCount": 1
    },
    {
      "id": "nordic",
      "name": "Nordic Semiconductor",
      "website": "https://www.nordicsemi.com",
      "country": "Norway",
      "logo": "logo.svg",
      "description": "Semiconductor vendor; the nRF52/nRF54 SoCs power many low-power mesh nodes.\n",
      "deviceCount": 1
    },
    {
      "id": "promicro",
      "name": "Pro Micro",
      "country": "Various",
      "description": "Generic Pro Micro form-factor nRF52 boards.\n",
      "deviceCount": 1
    },
    {
      "id": "rak",
      "name": "RAKwireless",
      "website": "https://www.rakwireless.com",
      "country": "China",
      "logo": "logo.svg",
      "description": "WisBlock / WisMesh modular LoRa and IoT hardware vendor.\n",
      "deviceCount": 7
    },
    {
      "id": "raspberry",
      "name": "Raspberry Pi",
      "website": "https://www.raspberrypi.com",
      "country": "United Kingdom",
      "logo": "logo.svg",
      "description": "Raspberry Pi single-board computers and microcontrollers.\n",
      "deviceCount": 2
    },
    {
      "id": "seeed",
      "name": "Seeed Studio",
      "website": "https://www.seeedstudio.com",
      "country": "China",
      "logo": "logo.jpg",
      "description": "Hardware platform company behind the XIAO, Wio and SenseCAP LoRa product lines.\n",
      "deviceCount": 16
    },
    {
      "id": "tenstar",
      "name": "Tenstar Robot",
      "website": "https://www.tenstarrobot.com",
      "deviceCount": 1
    },
    {
      "id": "uniteng",
      "name": "UnitEng",
      "website": "https://uniteng.com",
      "country": "China",
      "description": "Maker of the Station G2 and Nano G2 MeshCore base stations.\n",
      "deviceCount": 3
    },
    {
      "id": "waveshare",
      "name": "Waveshare",
      "website": "https://www.waveshare.com",
      "country": "China",
      "deviceCount": 1
    },
    {
      "id": "yaoyao",
      "name": "YAOYAO",
      "deviceCount": 1
    },
    {
      "id": "uart-cz",
      "name": "μArt.cz",
      "website": "https://pcb.uart.cz/",
      "country": "Czechia",
      "logo": "logo.png",
      "description": "Independent maker of Meshtastic solar mesh baseboards, battery management PCBs, and fully assembled outdoor LoRa node stations.\n",
      "deviceCount": 1
    }
  ],
  "compatibility": [
    {
      "firmwareId": "meshcore-official",
      "firmwareVersionSlug": "1.16.0",
      "deviceId": "heltec-v3",
      "status": "supported",
      "support": {
        "availability": "available",
        "level": "official",
        "verification": "verified"
      },
      "roles": {
        "companion": {
          "status": "verified",
          "transports": {
            "ble": "verified",
            "usb": "verified"
          }
        },
        "repeater": {
          "status": "verified",
          "management": {
            "serialCli": "verified",
            "wifiOta": "verified"
          }
        },
        "room-server": {
          "status": "verified"
        }
      },
      "peripherals": {
        "display": "verified",
        "gnss": "verified",
        "battery": "verified",
        "buttons": "verified",
        "wifi": "verified",
        "ble": "verified"
      },
      "builds": [
        {
          "target": "heltec_v3",
          "platformio_board": "esp32-s3-devkitc-1",
          "role": "companion",
          "transports": [
            "ble",
            "usb"
          ],
          "artifactSource": "web-flasher"
        },
        {
          "target": "heltec_v3",
          "platformio_board": "esp32-s3-devkitc-1",
          "role": "repeater",
          "artifactSource": "web-flasher"
        },
        {
          "target": "heltec_v3",
          "platformio_board": "esp32-s3-devkitc-1",
          "role": "room-server",
          "artifactSource": "web-flasher"
        }
      ],
      "verification": {
        "firmwareVersion": "1.16.0",
        "testedAt": "2026-06-20",
        "testedBy": "user-report",
        "confidence": "community-tested"
      },
      "provenance": {
        "source": "user-report",
        "importedAt": "2026-06-20"
      },
      "notes": "Everything works on Heltec v3 with the latest official MeshCore firmware."
    },
    {
      "firmwareId": "meshcore-official",
      "firmwareVersionSlug": "1.16.0",
      "deviceId": "uart-solar-node-station",
      "status": "supported",
      "support": {
        "availability": "unavailable",
        "level": "vendor",
        "verification": "verified"
      },
      "roles": {
        "companion": {
          "status": "verified",
          "transports": {
            "ble": "verified",
            "usb": "verified"
          }
        },
        "repeater": {
          "status": "verified"
        },
        "room-server": {
          "status": "verified"
        }
      },
      "builds": [
        {
          "target": "rak4631",
          "platformio_board": "rak4631",
          "role": "companion",
          "transports": [
            "ble",
            "usb"
          ],
          "artifactSource": "github-release"
        },
        {
          "target": "rak4631",
          "platformio_board": "rak4631",
          "role": "repeater",
          "artifactSource": "github-release"
        },
        {
          "target": "rak4631",
          "platformio_board": "rak4631",
          "role": "room-server",
          "artifactSource": "github-release"
        }
      ],
      "verification": {
        "firmwareVersion": "1.16.0",
        "evidenceUrl": "https://lectronz.com/products/fully-assembled-meshtastic-solar-node-station",
        "confidence": "manufacturer"
      },
      "notes": "Vendor states the Meshtastic Motherboard is electrically compatible with RAK4631 — use the official RAK4631 MeshCore build. Product retired on Lectronz; baseboard docs remain at pcb.uart.cz."
    }
  ],
  "globals": {
    "family": {
      "nrf52": {
        "name": "Nordic nRF52 series",
        "vendor": "Nordic Semiconductor",
        "url": "https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52-Series",
        "architecture": "arm-cortex-m4",
        "models": {
          "nrf52840": {
            "name": "Nordic nRF52840",
            "url": "https://www.nordicsemi.com/Products/nRF52840"
          }
        }
      },
      "nrf54": {
        "name": "Nordic nRF54 series",
        "vendor": "Nordic Semiconductor",
        "url": "https://www.nordicsemi.com/Products/nRF54L-Series",
        "architecture": "arm-cortex-m33",
        "models": {
          "nrf54l15": {
            "name": "Nordic nRF54L15",
            "url": "https://www.nordicsemi.com/Products/nRF54L15"
          }
        }
      },
      "esp32": {
        "name": "Espressif ESP32 series",
        "vendor": "Espressif",
        "url": "https://www.espressif.com/en/products/socs/esp32",
        "architecture": "xtensa",
        "models": {
          "esp32": {
            "name": "Espressif ESP32 (original)",
            "url": "https://www.espressif.com/en/products/socs/esp32"
          },
          "esp32-s3": {
            "name": "Espressif ESP32-S3",
            "url": "https://www.espressif.com/en/products/socs/esp32-s3"
          },
          "esp32-c3": {
            "name": "Espressif ESP32-C3",
            "url": "https://www.espressif.com/en/products/socs/esp32-c3",
            "architecture": "risc-v"
          },
          "esp32-c6": {
            "name": "Espressif ESP32-C6",
            "url": "https://www.espressif.com/en/products/socs/esp32-c6",
            "architecture": "risc-v"
          },
          "esp32-p4": {
            "name": "Espressif ESP32-P4",
            "url": "https://www.espressif.com/en/products/socs/esp32-p4",
            "architecture": "risc-v"
          }
        }
      },
      "rp2040": {
        "name": "Raspberry Pi RP2040",
        "vendor": "Raspberry Pi",
        "url": "https://www.raspberrypi.com/products/rp2040/",
        "architecture": "arm-cortex-m0-plus"
      },
      "stm32wl": {
        "name": "ST STM32WL",
        "vendor": "STMicroelectronics",
        "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html",
        "architecture": "arm-cortex-m4"
      }
    },
    "architecture": {
      "arm-cortex-m0-plus": {
        "name": "ARM Cortex-M0+",
        "vendor": "ARM"
      },
      "arm-cortex-m4": {
        "name": "ARM Cortex-M4",
        "vendor": "ARM"
      },
      "arm-cortex-m33": {
        "name": "ARM Cortex-M33",
        "vendor": "ARM"
      },
      "xtensa": {
        "name": "Xtensa LX",
        "vendor": "Cadence"
      },
      "risc-v": {
        "name": "RISC-V"
      }
    },
    "radio": {
      "sx1262": {
        "name": "Semtech SX1262",
        "vendor": "Semtech",
        "url": "https://www.semtech.com/products/wireless-rf/lora-connect/sx1262"
      },
      "sx1268": {
        "name": "Semtech SX1268",
        "vendor": "Semtech",
        "url": "https://www.semtech.com/products/wireless-rf/lora-connect/sx1268"
      },
      "sx1276": {
        "name": "Semtech SX1276",
        "vendor": "Semtech",
        "url": "https://www.semtech.com/products/wireless-rf/lora-connect/sx1276"
      },
      "sx126x": {
        "name": "Semtech SX126x series",
        "vendor": "Semtech",
        "url": "https://www.semtech.com/products/wireless-rf/lora-connect"
      },
      "sx127x": {
        "name": "Semtech SX127x series",
        "vendor": "Semtech",
        "url": "https://www.semtech.com/products/wireless-rf/lora-connect"
      },
      "lr1110": {
        "name": "Semtech LR1110",
        "vendor": "Semtech",
        "url": "https://www.semtech.com/products/wireless-rf/lora-edge/lr1110"
      },
      "stm32wl": {
        "name": "ST STM32WL (integrated LoRa)",
        "vendor": "STMicroelectronics",
        "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html"
      }
    },
    "frequency": {
      "433": {
        "name": "433 MHz",
        "range": "433.05–434.79 MHz",
        "region": "EU433 / CN"
      },
      "470": {
        "name": "470 MHz",
        "range": "470–510 MHz",
        "region": "CN470"
      },
      "780": {
        "name": "780 MHz",
        "range": "779–787 MHz",
        "region": "CN779"
      },
      "865": {
        "name": "865 MHz",
        "range": "865–867 MHz",
        "region": "IN865"
      },
      "868": {
        "name": "868 MHz",
        "range": "863–870 MHz",
        "region": "EU868"
      },
      "915": {
        "name": "915 MHz",
        "range": "902–928 MHz",
        "region": "US915 / AU915"
      },
      "920": {
        "name": "920 MHz",
        "range": "920–923 MHz",
        "region": "KR920"
      },
      "923": {
        "name": "923 MHz",
        "range": "920–925 MHz",
        "region": "AS923"
      }
    },
    "display": {
      "oled": {
        "name": "OLED",
        "description": "Self-emissive monochrome or color panel, typically I²C/SPI."
      },
      "e-paper": {
        "name": "E-Paper",
        "description": "Reflective bistable display that holds an image without power."
      },
      "e-ink": {
        "name": "E-Ink",
        "description": "Reflective bistable display that holds an image without power."
      },
      "display": {
        "name": "LCD / TFT",
        "description": "Backlit liquid-crystal panel."
      }
    },
    "gnss": {
      "L76K": {
        "name": "Quectel L76K",
        "vendor": "Quectel",
        "url": "https://www.quectel.com/product/gnss-l76k"
      },
      "MIA-M10Q": {
        "name": "u-blox MIA-M10Q",
        "vendor": "u-blox",
        "url": "https://www.u-blox.com/en/product/mia-m10q-series"
      },
      "AG3335": {
        "name": "MediaTek AG3335",
        "vendor": "MediaTek",
        "url": "https://www.mediatek.com/products/iot-mt3335"
      },
      "ATGM336H": {
        "name": "Hangzhou ZhongKe ATGM336H-5N",
        "vendor": "Hangzhou ZhongKe Microelectronics",
        "url": "https://w2.electrodragon.com/Chip-cn-dat/ZHONGKEWEI-dat/ATGM336H-dat/ZHONGKEWEI-ATGM336H-5N31.pdf"
      },
      "NEO-6": {
        "name": "u-blox NEO-6",
        "vendor": "u-blox",
        "url": "https://www.u-blox.com/en/product/neo-6-series"
      }
    },
    "refs": {
      "mesh-sh-device": {
        "name": "mesh-sn.de",
        "urlTemplate": "https://mesh-sn.de/en/devices/details/{id}"
      }
    }
  }
}
