Compare commits

...
Author SHA1 Message Date
Ben Meadors 7e6a74f06c Remove unused Adafruit_SSD1306 library dependency 2026-05-13 07:00:33 -05:00
Ben Meadors 5f734dabf9 Trunk 2026-05-13 06:44:51 -05:00
Andros Fenollosa 039ad42758 Fix WiFi TCP/HTTP services not starting without USB serial connected (#10460)
Move WiFi.onEvent(WiFiEvent) registration before createSSLCert() to
prevent a race where the ESP32 auto-reconnects during cert generation
and fires GOT_IP before the handler is attached, causing
onNetworkConnected() to never run and the TCP/HTTP API services to
never initialize when booting without USB serial.

Also call onNetworkConnected() from reconnectWiFi() on all platforms
(not just RP2040) as a safety net; it is already guarded by
APStartupComplete so it only runs once.
2026-05-13 06:43:36 -05:00
Ben Meadors 593909c26b Radiolib excludes 2026-05-13 06:42:49 -05:00
Ben Meadors 29a61dc75c Fix type declaration for ambientLightingThread and correct uint32_t usage in PacketHistory 2026-05-12 21:45:16 -05:00
Ben Meadors eead467ce6 Added NodeDB fixtures and refactored to use std maps for better memory efficiency (#10464)
* Added NodeDB fixtures and refactored to use std maps for better efficiency

* Defer NodeDB save during xmodem transfer to prevent mid-transfer fsFormat
2026-05-12 17:23:29 -05:00
Ben Meadors f3ae02c425 Cleanup comments 2026-05-12 16:32:00 -05:00
Ben Meadors d9cb74e4dd XModemAdapter: ensure file truncation before receiving and add isBusy() method to prevent concurrent writes 2026-05-12 15:38:56 -05:00
Dirk MuellerandBen Meadors 7ff6641f97 Fix missing potential null termination in xmodem filename handling (#10308)
* Fix missing potential null termination in xmodem filename handling

The packet size max is 128 bytes, and the filename is 128 bytes, so
potentially there is no NUL at the end. use strlcpy() as that takes
care of null termination even if buffer size is exceeded.

* Protect against theoretical buffer overflows in BLE logging

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2026-05-12 06:26:13 -05:00
f7548e7c25 Remove gradient sync nonce and simplify replay handling (#10459)
* Remove gradient sync nonce and simplify replay handling

* Fix ONLY_CONFIG replay gating and stale gradient-sync comments

Agent-Logs-Url: https://github.com/meshtastic/firmware/sessions/cfa93978-e2e0-4dc2-ba5f-b82b5b43cef8

Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>

* Add transport mechanism to replay packets for client filtering

* Comments

* Update protobuf definitions to include precision_bits in PositionLite

* Propagate position precision_bits and remove verbose NodeInfo sync log

Agent-Logs-Url: https://github.com/meshtastic/firmware/sessions/41572cbc-408e-499d-b59e-00f330b5789f

Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-05-11 21:42:07 -05:00
HarukiToredaandCopilot Autofix powered by AI b960121464 BaseUI: remove legacy single-message runtime path and keep multimessage flow (#10450)
* cleanup

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-11 20:53:41 -05:00
Ben Meadors b074645586 Change node pointer to const in JsonSerialize function 2026-05-11 17:16:32 -05:00
Ben Meadors 811dd427dd Update protobufs 2026-05-11 16:36:35 -05:00
Jonathan Bennett 1c06b702dc Merge remote-tracking branch 'origin/master' into develop 2026-05-11 15:07:22 -05:00
github-actions[bot]andjp-bennett 59b4993861 Update protobufs (#10456)
Co-authored-by: jp-bennett <5630967+jp-bennett@users.noreply.github.com>
2026-05-11 15:06:37 -05:00
Jonathan Bennett 4446b0f1a2 Add variantDefaultConfig and set eth_enabled to default true (#10454) 2026-05-11 14:51:21 -05:00
64fd61706d ThinkNode M7 (#8077)
* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* rename variant and add guard macros

* older G3 operational. M7 next.

* Split out G3 and M7 to different variants. Completely new PCB design. The G3 stays on 'PRIVATE_HW'

* Define button behaviour and use all of the device flash

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: caveman99 <25002+caveman99@users.noreply.github.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2026-05-11 11:46:13 -05:00
Jonathan Bennett da61a0db7d Refactor mutex handling in PhoneAPI.cpp
Replace LockGuard with explicit lock and unlock calls to avoid deadlock
2026-05-11 11:45:14 -05:00
8e99ffbe7e ThinkNode M7 (#8077)
* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* ThinkNode G3, ETH support WIP

* rename variant and add guard macros

* older G3 operational. M7 next.

* Split out G3 and M7 to different variants. Completely new PCB design. The G3 stays on 'PRIVATE_HW'

* Define button behaviour and use all of the device flash

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: caveman99 <25002+caveman99@users.noreply.github.com>
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
2026-05-11 11:33:13 -05:00
Ben Meadors 8877608858 Protos 2026-05-11 09:32:55 -05:00
78 changed files with 6733 additions and 537 deletions
+14 -10
View File
@@ -193,22 +193,26 @@ Writers go through `setNodeStatus`, `updatePosition`, `updateTelemetry` (which d
Every code path that drops a node from the header table must also evict the satellites. The single chokepoint is `eraseNodeSatellites(NodeNum)`; it's already called from `getOrCreateMeshNode`'s oldest-boring eviction, `removeNodeByNum`, both branches of `resetNodes`, `cleanupMeshDB`, `addFromContact`'s ignored-branch, and `AdminModule`'s `set_ignored_node`. Add new eviction sites here, not by calling `.erase()` directly.
### Gradient sync (opt-in via special nonces)
### Sync flow: thin NodeInfo + post-COMPLETE_ID replay (no opt-in)
`client_capabilities` is **not** a thing in this branch. Phone clients opt into the new sync flow by sending one of two values in the `ToRadio.want_config_id`:
There is no capability flag and no special "gradient" nonce. The **default** sync flow is:
- `SPECIAL_NONCE_GRADIENT_SYNC` (69422) — full config + thin NodeInfo + replay phases.
- `SPECIAL_NONCE_GRADIENT_ONLY_NODES` (69423) — skip config segments, NodeInfo + replay only.
1. Config / module-config / channel / metadata segments (same as before).
2. `STATE_SEND_OWN_NODEINFO` — **our own** NodeInfo, still bundled with our position and device_metrics (because the replay snapshot excludes our own NodeNum). Emitted via `ConvertToNodeInfo(lite)`.
3. `STATE_SEND_OTHER_NODEINFOS` — every other peer's NodeInfo, **always thin** (no `position`, no `device_metrics`). Emitted via `ConvertToNodeInfoThin(lite)`.
4. `STATE_SEND_FILEMANIFEST` → `STATE_SEND_COMPLETE_ID` — the phone sees `config_complete_id` and treats sync as done.
5. `STATE_SEND_PACKETS` — live mesh packets, with a trailing replay drain interleaved. The replay drain walks four cached satellite stores in order (positions → telemetry → environment → status) and emits each cached entry as an ordinary `MeshPacket` on the matching portnum (`POSITION_APP`, `TELEMETRY_APP` device + environment variants, `NODE_STATUS_APP`). These are indistinguishable on the wire from live mesh traffic, so clients need no special handling — any code that already updates UI on `POSITION_APP` etc. works.
`PhoneAPI::clientWantsGradientSync()` is the single switch. When true, `STATE_SEND_OTHER_NODEINFOS` is followed by:
`PhoneAPI::sendConfigComplete()` arms `replayPhase = REPLAY_PHASE_POSITIONS` for default/full sync and `SPECIAL_NONCE_ONLY_NODES`, while `SPECIAL_NONCE_ONLY_CONFIG` skips replay. The drain runs inside `STATE_SEND_PACKETS` via `popReplayPacket()`, lower priority than live traffic. When all four phases drain, `replayPhase` flips back to `REPLAY_PHASE_IDLE` and the snapshot vectors get `shrink_to_fit`ed.
```text
STATE_REPLAY_POSITIONS → STATE_REPLAY_TELEMETRY → STATE_REPLAY_ENVIRONMENT → STATE_REPLAY_STATUS
```
STM32WL and any other build with all four `MESHTASTIC_EXCLUDE_*DB` flags set produces zero replay packets — `popReplayPacket` advances through each phase in microseconds without emitting anything.
Each replay phase walks the corresponding satellite map and emits synthetic `MeshPacket`s on the matching portnum (`POSITION_APP`, `TELEMETRY_APP` for both device + environment variants, `STATUS_MESSAGE_APP`). Legacy clients (no special nonce) get the bundled-NodeInfo path with position/device_metrics joined back in by `ConvertToNodeInfo(lite, pos*, dm*)` — wire bytes are byte-identical to pre-v25 for them.
Special nonces that still mean something:
`ConvertToNodeInfoThin(lite)` is the gradient-sync emitter (no position/telemetry).
- `SPECIAL_NONCE_ONLY_CONFIG` (69420) — skip node sync entirely, just config.
- `SPECIAL_NONCE_ONLY_NODES` (69421) — skip config segments, jump straight to `STATE_SEND_OWN_NODEINFO`. Still gets the post-COMPLETE_ID replay drain.
There are no other reserved nonces; everything else is a fresh random `want_config_id` from the client.
### v24 → v25 migration
+6
View File
@@ -56,3 +56,9 @@ CMakeLists.txt
.python3
.claude/scheduled_tasks.lock
userPrefs.jsonc.mcp-session-bak
# Fake-NodeDB fixture pipeline (bin/regen-fake-nodedbs.sh)
# JSONL seeds are committed (test/fixtures/nodedb/seed_v25_*.jsonl);
# compiled .proto outputs are ephemeral build artifacts.
build/fixtures/
bin/_generated/
+7
View File
@@ -34,6 +34,13 @@ lint:
- linters: [ALL]
paths:
- bin/**
# Fake-NodeDB fixture JSONL files contain deterministic synthetic
# public_key_hex (64-char hex) values that gitleaks misidentifies as
# generic-api-key. These are not secrets — they're test fixtures
# produced by bin/gen-fake-nodedb-seed.py with a fixed RNG seed.
- linters: [gitleaks]
paths:
- test/fixtures/nodedb/seed_v25_*.jsonl
runtimes:
enabled:
- python@3.14.4
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""Post-process protoc-generated Python files to live under a local namespace.
Called by bin/regen-py-protos.sh. Walks the generated *_pb2.py files in the
target directory and rewrites every `meshtastic` reference (imports, dotted
attribute access) to use the new namespace (e.g., `meshtastic_v25`).
Why: the .proto files declare `package meshtastic;`, so protoc emits
`from meshtastic import mesh_pb2 as ...` lines. That would shadow the PyPI
`meshtastic` package which other parts of the mcp-server depend on. Renaming
to a local namespace keeps both available.
Usage:
_rewrite_proto_namespace.py <generated_dir> <new_namespace>
"""
from __future__ import annotations
import pathlib
import re
import sys
def rewrite(dir_path: pathlib.Path, new_ns: str) -> int:
# Standard protoc import forms:
# from meshtastic.X_pb2 import ... (rare, for direct symbol pulls)
# from meshtastic import X_pb2 as ... (common, the cross-file ref)
# import meshtastic.X_pb2 (also possible)
pattern_dotted_from = re.compile(r"^from meshtastic\.", re.MULTILINE)
pattern_bare_from = re.compile(r"^from meshtastic import ", re.MULTILINE)
pattern_dotted_import = re.compile(r"^import meshtastic\.", re.MULTILINE)
count = 0
for p in dir_path.glob("*.py"):
text = p.read_text(encoding="utf-8")
new = pattern_dotted_from.sub(f"from {new_ns}.", text)
new = pattern_bare_from.sub(f"from {new_ns} import ", new)
new = pattern_dotted_import.sub(f"import {new_ns}.", new)
# NOTE: we deliberately leave `meshtastic/X.proto` source-filename
# references inside descriptor strings alone. The descriptor pool is
# keyed by source filename (independent of Python package layout), so
# those don't collide with the PyPI package's descriptors.
if new != text:
p.write_text(new, encoding="utf-8")
count += 1
return count
def main(argv: list[str]) -> int:
if len(argv) != 2:
print("usage: _rewrite_proto_namespace.py <generated_dir> <new_namespace>", file=sys.stderr)
return 2
dir_path = pathlib.Path(argv[0])
new_ns = argv[1]
if not dir_path.is_dir():
print(f"directory not found: {dir_path}", file=sys.stderr)
return 2
n = rewrite(dir_path, new_ns)
print(f"rewrote {n} file(s) in {dir_path} → namespace {new_ns}", file=sys.stderr)
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
+439
View File
@@ -0,0 +1,439 @@
#!/usr/bin/env python3
"""Deterministic seed-data generator for the fake NodeDB fixture pipeline.
Writes a JSONL file describing N fake-but-realistic Meshtastic peers.
The output is hand-editable and committed; a sibling compile step
(bin/seed-json-to-proto.py) turns it into a binary `meshtastic_NodeDatabase`
v25 protobuf with fresh "now-relative" timestamps.
Determinism contract:
Same --seed -> byte-identical JSONL output, regardless of wall clock.
All timestamps are stored as `*_offset_sec` (seconds before "now"); the
compile step resolves them to absolute epochs at compile time.
Structural fields covered:
* NodeInfoLite header: num, long_name, short_name, hw_model, role,
public_key, snr, channel, hops_away, next_hop, bitfield flags
* PositionLite: lat/long Gaussian around --centroid, altitude, source
* DeviceMetrics: battery/voltage/util/uptime
* EnvironmentMetrics: temp/humidity/pressure/iaq
* StatusMessage: error_code (usually zero)
Active-board allow-list:
hw_model values are restricted to the intersection of
(a) variants with `custom_meshtastic_support_level = 1` in
variants/*/*/platformio.ini, AND
(b) values present in the `HardwareModel` enum in mesh.proto.
See HW_MODEL_WEIGHTS below. Deprecated boards (legacy TLORA / Heltec V1-2 /
classic TBEAM / TBEAM_V0P7 / Nano G1 / etc.) and fuzzer-only sentinels
(PORTDUINO, ANDROID_SIM, DIY_V1, ...) are excluded.
Active-role allow-list:
Excludes ROUTER_CLIENT (deprecated v2.3.15) and REPEATER (deprecated v2.7.11).
"""
from __future__ import annotations
import argparse
import datetime as _dt
import json
import math
import pathlib
import random
import sys
# --------------------------------------------------------------------------
# Active-board allow-list (intersection of tier-1 variants + HardwareModel enum).
# Refresh by running:
# for f in $(find variants -name 'platformio.ini' | xargs grep -lE 'custom_meshtastic_support_level = 1'); do
# grep custom_meshtastic_hw_model_slug $f | awk -F= '{print $2}' | tr -d ' ';
# done | sort -u | comm -12 - <(python3 -c "from meshtastic.protobuf.mesh_pb2 import HardwareModel; print('\\n'.join(HardwareModel.keys()))" | sort)
# --------------------------------------------------------------------------
HW_MODEL_WEIGHTS: dict[str, float] = {
"HELTEC_V3": 14.0,
"T_DECK": 9.0,
"HELTEC_V4": 8.0,
"RAK4631": 8.0,
"HELTEC_MESH_POCKET": 6.0,
"TRACKER_T1000_E": 5.0,
"HELTEC_MESH_NODE_T114": 5.0,
"T_DECK_PRO": 5.0,
"LILYGO_TBEAM_S3_CORE": 4.0,
"HELTEC_WIRELESS_PAPER": 4.0,
"HELTEC_WSL_V3": 3.0,
"T_ECHO": 3.0,
"HELTEC_WIRELESS_TRACKER": 3.0,
"HELTEC_WIRELESS_TRACKER_V2": 2.0,
"HELTEC_VISION_MASTER_E290": 2.0,
"HELTEC_MESH_SOLAR": 2.0,
"SEEED_WIO_TRACKER_L1": 2.0,
"T_LORA_PAGER": 1.5,
"HELTEC_VISION_MASTER_E213": 1.5,
"T_ECHO_PLUS": 1.0,
"MUZI_BASE": 1.0,
"WISMESH_TAP_V2": 1.0,
"THINKNODE_M2": 1.0,
"THINKNODE_M5": 1.0,
"TLORA_T3_S3": 1.0,
# Long tail (uniform low weight across remaining tier-1 boards):
"HELTEC_V4_R8": 0.3,
"HELTEC_VISION_MASTER_T190": 0.3,
"HELTEC_HT62": 0.3,
"HELTEC_MESH_NODE_T096": 0.3,
"M5STACK_C6L": 0.3,
"MINI_EPAPER_S3": 0.3,
"MUZI_R1_NEO": 0.3,
"NOMADSTAR_METEOR_PRO": 0.3,
"RAK3312": 0.3,
"RAK3401": 0.3,
"SEEED_SOLAR_NODE": 0.3,
"SEEED_WIO_TRACKER_L1_EINK": 0.3,
"SENSECAP_INDICATOR": 0.3,
"TBEAM_1_WATT": 0.3,
"THINKNODE_M1": 0.3,
"THINKNODE_M3": 0.3,
"THINKNODE_M6": 0.3,
"T_ECHO_LITE": 0.3,
"WISMESH_TAG": 0.3,
"WISMESH_TAP": 0.3,
"XIAO_NRF52_KIT": 0.3,
"CROWPANEL": 0.3,
}
# Non-deprecated roles only.
ROLE_WEIGHTS: dict[str, float] = {
"CLIENT": 75.0,
"CLIENT_MUTE": 5.0,
"ROUTER": 7.0,
"TRACKER": 3.0,
"SENSOR": 2.0,
"CLIENT_HIDDEN": 2.0,
"ROUTER_LATE": 2.0,
"CLIENT_BASE": 2.0,
"TAK": 1.0,
"TAK_TRACKER": 0.5,
"LOST_AND_FOUND": 0.5,
}
# Name pools — 60 firsts × 60 lasts = 3600 combinations.
FIRSTS = [
"Quick", "Brave", "Silent", "Wild", "Lone", "Bright", "Red", "Blue",
"Green", "Black", "White", "Iron", "Steel", "Copper", "Silver", "Gold",
"Stone", "River", "Forest", "Mountain", "Canyon", "Desert", "Storm", "Sky",
"Solar", "Lunar", "Dawn", "Dusk", "Misty", "Frosty", "Sunny", "Shady",
"Happy", "Sleepy", "Drowsy", "Sneaky", "Sharp", "Smooth", "Rough", "Loud",
"Soft", "Slow", "Fast", "Tall", "Short", "Old", "New", "Tiny",
"Giant", "Hidden", "Lost", "Found", "Wandering", "Roving", "Drifting", "Floating",
"Burning", "Frozen", "Whispering", "Howling",
]
LASTS = [
"Phoenix", "Lion", "Bear", "Wolf", "Hawk", "Eagle", "Fox", "Lynx",
"Cougar", "Coyote", "Raven", "Owl", "Crow", "Falcon", "Heron", "Crane",
"Otter", "Badger", "Bison", "Elk", "Moose", "Stag", "Doe", "Hare",
"Marmot", "Mole", "Beaver", "Squirrel", "Mustang", "Bronco", "Pony", "Colt",
"Cobra", "Viper", "Mamba", "Adder", "Gecko", "Iguana", "Tortoise", "Turtle",
"Salmon", "Trout", "Bass", "Pike", "Shark", "Whale", "Dolphin", "Seal",
"Cactus", "Yucca", "Sage", "Juniper", "Pine", "Cedar", "Aspen", "Oak",
"Bluff", "Mesa", "Arroyo", "Ridge",
]
# Brief callsign pool for licensed-looking suffixes.
CALLSIGN_PREFIXES = ["KX", "WD", "N5", "KE", "AB", "W5", "K1", "KQ", "AE", "NM"]
# Only emojis that fit in 4 UTF-8 bytes (no variation selectors). short_name's
# nanopb max_size:5 (incl. NUL) limits content to 4 bytes. ❄️ / ☀️ would be
# 6 bytes due to U+FE0F variation selector — explicitly excluded.
EMOJI_SHORTNAMES = ["🦊", "🐺", "🦅", "🐢", "🌵", "🔥", "🌙",
"🌊", "🗻", "🌲", "🦌", "🐝", "🦂", "🦉",
"🦇", "🦋"]
# --------------------------------------------------------------------------
# Helpers
# --------------------------------------------------------------------------
NUM_RESERVED = 4 # firmware reserves 0..3 (per NodeDB constants)
NUM_MAX_EXCLUSIVE = 0x80000000 # restrict to positive int32 range for readability
def _weighted_choice(rng: random.Random, weights: dict[str, float]) -> str:
"""Deterministic weighted pick. Uses sorted keys so dict order is fixed."""
keys = sorted(weights.keys())
totals = [weights[k] for k in keys]
return rng.choices(keys, weights=totals, k=1)[0]
def _gen_long_name(rng: random.Random, is_licensed: bool) -> str:
base = f"{rng.choice(FIRSTS)} {rng.choice(LASTS)}"
if is_licensed:
prefix = rng.choice(CALLSIGN_PREFIXES)
# Two trailing alpha chars after the digit; keep within 25 - len(base) - 1
suffix = f" {prefix}{rng.randint(0,9)}{rng.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ')}{rng.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ')}"
# nanopb max_size:25 means C string fits 24 bytes + NUL.
if len(base) + len(suffix) <= 24:
base = base + suffix
# Hard cap to 24 chars (nanopb max_size:25 minus NUL).
return base[:24]
def _gen_short_name(rng: random.Random, long_name: str) -> str:
# 10% emoji-only short_name
if rng.random() < 0.10:
return rng.choice(EMOJI_SHORTNAMES)
first_char = long_name[0].upper() if long_name else "X"
alphanums = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return first_char + "".join(rng.choices(alphanums, k=3))
def _gen_hops_away(rng: random.Random) -> int:
# Geometric-ish: 0→55%, 1→25%, 2→12%, 3→5%, 4→2%, 5+→1%
r = rng.random()
if r < 0.55:
return 0
if r < 0.80:
return 1
if r < 0.92:
return 2
if r < 0.97:
return 3
if r < 0.99:
return 4
return rng.randint(5, 7)
def _gen_position(
rng: random.Random,
centroid_lat: float,
centroid_lon: float,
spread_km: float,
last_heard_offset_sec: int,
) -> dict:
# 1 deg ≈ 111 km at the equator; we use this as a flat approximation.
lat = centroid_lat + rng.gauss(0.0, spread_km / 111.0)
lon = centroid_lon + rng.gauss(0.0, spread_km / 111.0)
altitude = max(0, round(rng.gauss(1376.0, 250.0))) # T or C valley floor + relief
# Position was reported up to 300s before last_heard.
time_offset_sec = last_heard_offset_sec + rng.randint(0, 300)
return {
"latitude": round(lat, 6),
"longitude": round(lon, 6),
"altitude": altitude,
"time_offset_sec": time_offset_sec,
"location_source": "LOC_INTERNAL",
}
def _gen_telemetry(rng: random.Random) -> dict:
# 5% plugged-in (battery_level == 101); rest uniform [10..100].
if rng.random() < 0.05:
battery_level = 101
voltage = 4.20
else:
battery_level = rng.randint(10, 100)
voltage = round(3.3 + (battery_level / 100.0) * 0.9, 3)
# Beta distributions for low/right-skewed metrics; randomly draw via gammavariate.
def _beta(a: float, b: float) -> float:
x = rng.gammavariate(a, 1.0)
y = rng.gammavariate(b, 1.0)
return x / (x + y)
channel_utilization = round(_beta(2.0, 15.0) * 100.0, 2)
air_util_tx = round(_beta(1.5, 20.0) * 10.0, 3)
uptime_seconds = int(rng.expovariate(1.0 / 86400.0))
return {
"battery_level": battery_level,
"voltage": voltage,
"channel_utilization": channel_utilization,
"air_util_tx": air_util_tx,
"uptime_seconds": uptime_seconds,
}
def _gen_environment(rng: random.Random) -> dict:
return {
"temperature": round(rng.gauss(22.0, 8.0), 2),
"relative_humidity": round(min(100.0, max(0.0, rng.gauss(55.0, 20.0))), 2),
"barometric_pressure": round(rng.gauss(1013.0, 8.0), 2),
"iaq": int(min(500, max(0, round(rng.gauss(50.0, 30.0))))),
}
def _gen_status(rng: random.Random) -> dict:
# `StatusMessage` (mesh.proto:1445) has a single free-form `string status`.
# Most peers report a healthy short status; occasional alert string.
healthy = ["OK", "online", "active", "running", "ready", "nominal"]
alert = ["low-batt", "no-gps", "weak-signal", "rebooted", "offline-soon"]
if rng.random() < 0.92:
return {"status": rng.choice(healthy)}
return {"status": rng.choice(alert)}
def _gen_node(
rng: random.Random,
num: int,
centroid_lat: float,
centroid_lon: float,
spread_km: float,
coverage: dict[str, float],
last_heard_mean_sec: int,
last_heard_max_sec: int,
) -> dict:
is_licensed = rng.random() < 0.05
long_name = _gen_long_name(rng, is_licensed)
short_name = _gen_short_name(rng, long_name)
hw_model = _weighted_choice(rng, HW_MODEL_WEIGHTS)
role = _weighted_choice(rng, ROLE_WEIGHTS)
has_public_key = rng.random() < 0.92
public_key_hex = (
"".join(f"{rng.randint(0,255):02x}" for _ in range(32)) if has_public_key else ""
)
snr = round(max(-20.0, min(12.0, rng.gauss(6.0, 4.0))), 2)
channel = 0 if rng.random() < 0.90 else rng.randint(1, 7)
hops_away = _gen_hops_away(rng)
next_hop = rng.randint(0, 255) if hops_away > 0 else 0
last_heard_offset_sec = int(min(rng.expovariate(1.0 / last_heard_mean_sec), last_heard_max_sec))
bitfield = {
"has_user": True,
"is_favorite": rng.random() < 0.08,
"is_muted": rng.random() < 0.03,
"via_mqtt": rng.random() < 0.12,
"is_ignored": rng.random() < 0.01,
"is_licensed": is_licensed,
"has_is_unmessagable": True,
"is_unmessagable": rng.random() < 0.02,
"is_key_manually_verified": rng.random() < 0.04,
}
node: dict = {
"num": f"0x{num:08x}",
"long_name": long_name,
"short_name": short_name,
"hw_model": hw_model,
"role": role,
"public_key_hex": public_key_hex,
"snr": snr,
"channel": channel,
"hops_away": hops_away,
"next_hop": next_hop,
"last_heard_offset_sec": last_heard_offset_sec,
"bitfield": bitfield,
"position": (
_gen_position(rng, centroid_lat, centroid_lon, spread_km, last_heard_offset_sec)
if rng.random() < coverage["position"]
else None
),
"telemetry": _gen_telemetry(rng) if rng.random() < coverage["telemetry"] else None,
"environment": _gen_environment(rng) if rng.random() < coverage["environment"] else None,
"status": _gen_status(rng) if rng.random() < coverage["status"] else None,
}
return node
def _parse_my_node_num(s: str | None) -> int | None:
if s is None:
return None
s = s.strip()
if s.startswith("0x") or s.startswith("0X"):
return int(s, 16)
return int(s)
def main(argv: list[str]) -> int:
p = argparse.ArgumentParser(
description="Deterministic JSONL seed for the fake NodeDB fixture.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p.add_argument("--count", type=int, required=True, help="Number of fake nodes to emit.")
p.add_argument("--seed", type=int, required=True, help="Deterministic seed.")
p.add_argument("--out", required=True, help="Output JSONL path.")
p.add_argument(
"--centroid",
default="33.1284,-107.2528",
help="LAT,LON centroid (default: Truth or Consequences, NM).",
)
p.add_argument("--spread-km", type=float, default=60.0, help="Gaussian std-dev in km.")
p.add_argument("--position-coverage", type=float, default=0.85)
p.add_argument("--telemetry-coverage", type=float, default=0.70)
p.add_argument("--environment-coverage", type=float, default=0.25)
p.add_argument("--status-coverage", type=float, default=0.40)
p.add_argument("--my-node-num", default=None, help="Exclude this NodeNum from generated set (hex or dec).")
p.add_argument("--last-heard-mean-sec", type=int, default=3600)
p.add_argument("--last-heard-max-sec", type=int, default=7 * 86400)
args = p.parse_args(argv)
if args.count <= 0:
print("--count must be positive", file=sys.stderr)
return 2
try:
centroid_lat, centroid_lon = (float(s) for s in args.centroid.split(","))
except ValueError:
print(f"--centroid must be LAT,LON; got {args.centroid!r}", file=sys.stderr)
return 2
my_node_num = _parse_my_node_num(args.my_node_num)
rng = random.Random(args.seed)
# 1) Generate a unique deterministic set of NodeNums.
nums: set[int] = set()
while len(nums) < args.count:
n = rng.randrange(NUM_RESERVED, NUM_MAX_EXCLUSIVE)
if my_node_num is not None and n == my_node_num:
continue
nums.add(n)
ordered_nums = sorted(nums) # sort to fix output order independent of set hash
# 2) Per-node generation (in num order, single RNG continues).
coverage = {
"position": args.position_coverage,
"telemetry": args.telemetry_coverage,
"environment": args.environment_coverage,
"status": args.status_coverage,
}
nodes = [
_gen_node(
rng,
n,
centroid_lat,
centroid_lon,
args.spread_km,
coverage,
args.last_heard_mean_sec,
args.last_heard_max_sec,
)
for n in ordered_nums
]
# 3) Write JSONL.
out_path = pathlib.Path(args.out)
out_path.parent.mkdir(parents=True, exist_ok=True)
# `generated_at_iso` is informational; it does NOT affect determinism because
# we derive it from the seed, not from wall clock. (Same seed -> same string.)
generated_at = _dt.datetime.fromtimestamp(args.seed, tz=_dt.timezone.utc).isoformat().replace("+00:00", "Z")
meta = {
"_meta": {
"version": 25,
"seed": args.seed,
"count": args.count,
"centroid": [centroid_lat, centroid_lon],
"spread_km": args.spread_km,
"generated_at_iso": generated_at,
"my_node_num_excluded": (None if my_node_num is None else f"0x{my_node_num:08x}"),
"coverage": coverage,
"last_heard_mean_sec": args.last_heard_mean_sec,
"last_heard_max_sec": args.last_heard_max_sec,
}
}
with out_path.open("w", encoding="utf-8") as f:
# `ensure_ascii=False` so emoji short_names survive. `sort_keys=True` for
# determinism (insertion order varies by Python version otherwise).
f.write(json.dumps(meta, ensure_ascii=False, sort_keys=True) + "\n")
for node in nodes:
f.write(json.dumps(node, ensure_ascii=False, sort_keys=True) + "\n")
print(f"wrote {args.count} nodes to {out_path} ({out_path.stat().st_size} bytes)", file=sys.stderr)
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
# Regenerate the fake-NodeDB fixtures: produces 250 / 500 / 1000 / 2000-node
# JSONL seed files + their compiled v25 protobufs.
#
# Layout:
# test/fixtures/nodedb/seed_v25_<N>.jsonl — COMMITTED, hand-editable.
# build/fixtures/nodedb/nodes_v25_<N>.proto — .gitignored, build artifact.
# Drop into /prefs/nodes.proto.
#
# Daily use: ./bin/regen-fake-nodedbs.sh
# - Recompiles protos from committed seeds (fresh wall-clock timestamps).
# Intentional seed bump: REGEN_SEEDS=yes ./bin/regen-fake-nodedbs.sh
# - Overwrites the committed JSONL files with freshly-seeded data.
set -euo pipefail
cd "$(dirname "$0")/.."
# 1) Make sure the Python protobuf bindings exist (in-tree generation; .gitignored).
if [[ ! -d bin/_generated/meshtastic ]]; then
echo "regenerating Python protobuf bindings (one-time)..."
./bin/regen-py-protos.sh
fi
# 2) Pick a Python interpreter that has the meshtastic deps installed.
# Prefer the mcp-server venv (most likely to be set up by the operator).
PY="python3"
for cand in mcp-server/.venv/bin/python3 .venv/bin/python3; do
if [[ -x "$cand" ]]; then
PY="$cand"
break
fi
done
# 3) Pinned seeds per size — bump only when you intentionally want different
# structural data committed. Parallel arrays so the script works on
# macOS bash 3.2 (no `declare -A`).
SIZES=(250 500 1000 2000)
SEEDS=(20260511 20260512 20260513 20260514)
REGEN_SEEDS="${REGEN_SEEDS:-no}"
mkdir -p build/fixtures/nodedb test/fixtures/nodedb
for i in 0 1 2 3; do
n="${SIZES[$i]}"
seed="${SEEDS[$i]}"
jsonl=$(printf "test/fixtures/nodedb/seed_v25_%04d.jsonl" "$n")
proto=$(printf "build/fixtures/nodedb/nodes_v25_%04d.proto" "$n")
if [[ "$REGEN_SEEDS" == "yes" || ! -f "$jsonl" ]]; then
$PY bin/gen-fake-nodedb-seed.py \
--count "$n" \
--seed "$seed" \
--out "$jsonl" \
--centroid 33.1284,-107.2528 \
--spread-km 60 \
--position-coverage 0.85 \
--telemetry-coverage 0.70 \
--environment-coverage 0.25 \
--status-coverage 0.40
echo " seed: $jsonl ($(wc -c < "$jsonl") bytes)"
fi
$PY bin/seed-json-to-proto.py --in "$jsonl" --out "$proto"
echo " proto: $proto ($(wc -c < "$proto") bytes)"
done
echo ""
echo "Done. To load on Portduino native:"
echo " cp build/fixtures/nodedb/nodes_v25_1000.proto ~/.portduino/default/prefs/nodes.proto"
echo ""
echo "To push to a hardware device:"
echo " Use the mcp-server tool: push_fake_nodedb(size=1000, target=\"hardware\", port=\"/dev/cu.usbmodemXXXX\", confirm=True)"
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# Regenerate Python protobuf bindings from the in-tree `protobufs/` submodule
# into `bin/_generated/`. Called by bin/regen-fake-nodedbs.sh; also useful as
# a standalone refresh after any change to a .proto file.
#
# Output is .gitignored — bindings are a build artifact.
#
# Namespace rewrite:
# The .proto files declare `package meshtastic;`, which makes protoc emit
# imports like `from meshtastic import mesh_pb2`. That conflicts with the
# PyPI `meshtastic` package (which the mcp-server relies on for its
# SerialInterface/BLEInterface transport). We post-process the generated
# files to live under `meshtastic_v25` instead — both the directory layout
# and all internal imports — so they coexist cleanly with the PyPI package.
set -euo pipefail
cd "$(dirname "$0")/.."
if ! command -v protoc >/dev/null 2>&1; then
echo "ERROR: protoc not found in PATH." >&2
echo " macOS: brew install protobuf" >&2
echo " Ubuntu/Debian: apt install protobuf-compiler" >&2
exit 1
fi
OUT=bin/_generated
LOCAL_NS=meshtastic_v25
rm -rf "$OUT"
mkdir -p "$OUT"
# 1) Generate from the in-tree protos. nanopb.proto first so its descriptor
# is available for the [(nanopb).*] options on other messages.
protoc \
--proto_path=protobufs \
--python_out="$OUT" \
protobufs/nanopb.proto \
protobufs/meshtastic/*.proto
# 2) Move the generated `meshtastic/` directory to `meshtastic_v25/`.
mv "$OUT/meshtastic" "$OUT/$LOCAL_NS"
# 3) Rewrite internal imports: any reference to `meshtastic.X_pb2` or
# `from meshtastic import X_pb2` becomes `meshtastic_v25.*`.
python3 bin/_rewrite_proto_namespace.py "$OUT/$LOCAL_NS" "$LOCAL_NS"
# 4) Make the package importable.
touch "$OUT/__init__.py"
touch "$OUT/$LOCAL_NS/__init__.py"
echo "regenerated Python protobuf bindings -> $OUT/$LOCAL_NS/ (namespace: $LOCAL_NS)" >&2
+342
View File
@@ -0,0 +1,342 @@
#!/usr/bin/env python3
"""Compile a committed seed JSONL into a binary meshtastic_NodeDatabase v25 proto.
The input is produced by `bin/gen-fake-nodedb-seed.py`. Timestamps in the JSONL
are stored as `*_offset_sec` (seconds before "now"); this script resolves them
to absolute epochs using `--now-epoch` (default: current wall clock).
Output is a raw `pb_encode`-compatible binary that can be dropped at
`/prefs/nodes.proto` on the device (Portduino prefs dir or hardware via
XModem) and loaded by `NodeDB::loadFromDisk` at boot.
Wire format reference:
protobufs/meshtastic/deviceonly.proto (NodeDatabase, NodeInfoLite, sat entries)
src/mesh/NodeDB.h:467-484 (bitfield bit positions)
src/mesh/NodeDB.cpp:1523-1524 (pb_decode entry point)
"""
from __future__ import annotations
import argparse
import json
import pathlib
import sys
import time
from typing import Any
# Prefer the in-tree generated Python protobuf bindings (bin/_generated/meshtastic_v25/)
# because the firmware branch's protos (v25 NodeDatabase satellite arrays, slim
# NodeInfoLite) are typically newer than what the PyPI `meshtastic` package
# ships. Run `bin/regen-py-protos.sh` to (re)generate.
#
# Namespace note: the local bindings live under `meshtastic_v25` (NOT `meshtastic`)
# to avoid shadowing the PyPI `meshtastic` package — bin/regen-py-protos.sh
# post-processes the protoc output to rename the package.
_HERE = pathlib.Path(__file__).resolve().parent
_LOCAL_PROTO_DIR = _HERE / "_generated"
if _LOCAL_PROTO_DIR.is_dir():
sys.path.insert(0, str(_LOCAL_PROTO_DIR))
try:
from meshtastic_v25.deviceonly_pb2 import ( # type: ignore[import-not-found]
NodeDatabase,
NodeInfoLite,
NodePositionEntry,
NodeTelemetryEntry,
NodeEnvironmentEntry,
NodeStatusEntry,
PositionLite,
)
from meshtastic_v25.mesh_pb2 import HardwareModel, Position, StatusMessage # type: ignore[import-not-found]
from meshtastic_v25.config_pb2 import Config # type: ignore[import-not-found]
from meshtastic_v25.telemetry_pb2 import DeviceMetrics, EnvironmentMetrics # type: ignore[import-not-found]
except ImportError as local_err:
# Fall back to the PyPI package if in-tree bindings haven't been generated.
# Will fail the v25 assertion below if the PyPI package predates the
# satellite-DB schema, but at least gives a clear "run regen-py-protos.sh"
# error message instead of an opaque ImportError.
try:
from meshtastic.protobuf.deviceonly_pb2 import (
NodeDatabase,
NodeInfoLite,
NodePositionEntry,
NodeTelemetryEntry,
NodeEnvironmentEntry,
NodeStatusEntry,
PositionLite,
)
from meshtastic.protobuf.mesh_pb2 import HardwareModel, Position, StatusMessage
from meshtastic.protobuf.config_pb2 import Config
from meshtastic.protobuf.telemetry_pb2 import DeviceMetrics, EnvironmentMetrics
except ImportError as pypi_err:
print(
"ERROR: could not import meshtastic protobuf bindings.\n"
" In-tree generation: run `bin/regen-py-protos.sh` (requires protoc).\n"
" PyPI fallback: `pip install meshtastic` (may lag firmware branch).\n"
f" local error (meshtastic_v25): {local_err}\n"
f" pypi error (meshtastic.protobuf): {pypi_err}",
file=sys.stderr,
)
sys.exit(1)
# Fail loudly if bindings predate v25 (no satellite arrays).
assert (
hasattr(NodeDatabase, "DESCRIPTOR")
and "positions" in NodeDatabase.DESCRIPTOR.fields_by_name
), (
"Loaded meshtastic bindings are older than v25 (NodeDatabase.positions missing). "
"Run `bin/regen-py-protos.sh` against the in-tree protobufs/ submodule."
)
# ---------------------------------------------------------------------------
# Bitfield bit positions (mirror src/mesh/NodeDB.h:467-484).
# ---------------------------------------------------------------------------
BIT_IS_KEY_MANUALLY_VERIFIED = 0
BIT_IS_MUTED = 1
BIT_VIA_MQTT = 2
BIT_IS_FAVORITE = 3
BIT_IS_IGNORED = 4
BIT_HAS_USER = 5
BIT_IS_LICENSED = 6
BIT_IS_UNMESSAGABLE = 7
BIT_HAS_IS_UNMESSAGABLE = 8
BITFIELD_LAYOUT = (
# JSON key bit position
("is_key_manually_verified", BIT_IS_KEY_MANUALLY_VERIFIED),
("is_muted", BIT_IS_MUTED),
("via_mqtt", BIT_VIA_MQTT),
("is_favorite", BIT_IS_FAVORITE),
("is_ignored", BIT_IS_IGNORED),
("has_user", BIT_HAS_USER),
("is_licensed", BIT_IS_LICENSED),
("is_unmessagable", BIT_IS_UNMESSAGABLE),
("has_is_unmessagable", BIT_HAS_IS_UNMESSAGABLE),
)
def _pack_bitfield(bf: dict[str, bool]) -> int:
out = 0
for key, shift in BITFIELD_LAYOUT:
if bf.get(key, False):
out |= (1 << shift)
return out
def _validate_node(node: dict[str, Any]) -> None:
"""Friendly errors so hand-editors get clear feedback."""
if "num" not in node or not isinstance(node["num"], str):
raise ValueError(f"node missing/invalid 'num' (must be hex string): {node!r}")
if "long_name" not in node:
raise ValueError(f"node {node['num']}: missing 'long_name'")
if len(node["long_name"]) > 24:
raise ValueError(
f"node {node['num']}: long_name {node['long_name']!r} is "
f"{len(node['long_name'])} chars; max 24 (nanopb max_size:25 minus NUL)"
)
if "short_name" in node:
# short_name max_size:5 (incl. NUL) → 4 bytes of content.
# Char count is irrelevant — emojis with variation selectors (e.g. ❄️ = 6 B)
# would slip past a `len(str) > 4` check. Always measure bytes.
b = node["short_name"].encode("utf-8")
if len(b) > 4:
raise ValueError(
f"node {node['num']}: short_name {node['short_name']!r} is "
f"{len(b)} bytes UTF-8; max 4 (nanopb max_size:5 minus NUL)"
)
pk = node.get("public_key_hex", "")
if pk and len(pk) != 64:
raise ValueError(
f"node {node['num']}: public_key_hex must be 64 hex chars or empty; "
f"got {len(pk)} chars"
)
if pk:
try:
bytes.fromhex(pk)
except ValueError as e:
raise ValueError(f"node {node['num']}: public_key_hex is not valid hex: {e}")
def _resolve_time(
node: dict[str, Any],
field_absolute: str,
field_offset: str,
now_epoch: int,
) -> int:
"""If `field_absolute` is set, use it; else compute `now_epoch - offset`."""
if field_absolute in node and node[field_absolute] is not None:
return int(node[field_absolute])
offset = node.get(field_offset, 0)
return max(0, int(now_epoch) - int(offset))
def _build_node_info_lite(node: dict[str, Any], now_epoch: int) -> NodeInfoLite:
_validate_node(node)
info = NodeInfoLite()
info.num = int(node["num"], 16) if isinstance(node["num"], str) else int(node["num"])
info.long_name = node.get("long_name", "")
info.short_name = node.get("short_name", "")
# Enum lookups will raise ValueError on unknown names — that's exactly what we want.
info.hw_model = HardwareModel.Value(node.get("hw_model", "UNSET"))
info.role = Config.DeviceConfig.Role.Value(node.get("role", "CLIENT"))
pk_hex = node.get("public_key_hex", "")
if pk_hex:
info.public_key = bytes.fromhex(pk_hex)
info.snr = float(node.get("snr", 0.0))
info.channel = int(node.get("channel", 0))
if "hops_away" in node:
# `optional uint32 hops_away = 9;` — in Python protobuf, assigning the
# field implicitly sets HasField("hops_away") to True. No has_hops_away
# setter exists (unlike the C++ nanopb-generated header).
info.hops_away = int(node["hops_away"])
info.next_hop = int(node.get("next_hop", 0))
info.last_heard = _resolve_time(node, "last_heard", "last_heard_offset_sec", now_epoch)
info.bitfield = _pack_bitfield(node.get("bitfield", {}))
return info
def _build_position_entry(num: int, pos: dict[str, Any], now_epoch: int) -> NodePositionEntry:
entry = NodePositionEntry()
entry.num = num
pl = PositionLite()
# Firmware stores lat/long as int32 in 1e-7 degrees.
pl.latitude_i = int(round(float(pos["latitude"]) * 1e7))
pl.longitude_i = int(round(float(pos["longitude"]) * 1e7))
pl.altitude = int(pos.get("altitude", 0))
pl.time = _resolve_time(pos, "time", "time_offset_sec", now_epoch)
pl.location_source = Position.LocSource.Value(pos.get("location_source", "LOC_UNSET"))
entry.position.CopyFrom(pl)
return entry
def _build_telemetry_entry(num: int, tel: dict[str, Any]) -> NodeTelemetryEntry:
entry = NodeTelemetryEntry()
entry.num = num
dm = DeviceMetrics()
if "battery_level" in tel:
dm.battery_level = int(tel["battery_level"])
if "voltage" in tel:
dm.voltage = float(tel["voltage"])
if "channel_utilization" in tel:
dm.channel_utilization = float(tel["channel_utilization"])
if "air_util_tx" in tel:
dm.air_util_tx = float(tel["air_util_tx"])
if "uptime_seconds" in tel:
dm.uptime_seconds = int(tel["uptime_seconds"])
entry.device_metrics.CopyFrom(dm)
return entry
def _build_environment_entry(num: int, env: dict[str, Any]) -> NodeEnvironmentEntry:
entry = NodeEnvironmentEntry()
entry.num = num
em = EnvironmentMetrics()
if "temperature" in env:
em.temperature = float(env["temperature"])
if "relative_humidity" in env:
em.relative_humidity = float(env["relative_humidity"])
if "barometric_pressure" in env:
em.barometric_pressure = float(env["barometric_pressure"])
if "iaq" in env:
em.iaq = int(env["iaq"])
entry.environment_metrics.CopyFrom(em)
return entry
def _build_status_entry(num: int, status: dict[str, Any]) -> NodeStatusEntry:
# `StatusMessage` (mesh.proto:1445) has a single `string status` field.
entry = NodeStatusEntry()
entry.num = num
sm = StatusMessage()
if "status" in status:
sm.status = str(status["status"])
entry.status.CopyFrom(sm)
return entry
def compile_jsonl_to_proto(jsonl_path: pathlib.Path, now_epoch: int) -> bytes:
"""Read a seed JSONL and return the encoded NodeDatabase bytes."""
lines = jsonl_path.read_text(encoding="utf-8").splitlines()
if not lines:
raise ValueError(f"{jsonl_path} is empty")
meta_line = lines[0]
meta_obj = json.loads(meta_line)
meta = meta_obj.get("_meta", {})
version = meta.get("version")
if version != 25:
raise ValueError(
f"{jsonl_path}: meta version is {version!r}; this compiler "
f"requires version=25. Regenerate the seed with the matching tooling."
)
db = NodeDatabase()
db.version = 25
for ln, raw in enumerate(lines[1:], start=2):
raw = raw.strip()
if not raw:
continue
try:
node = json.loads(raw)
except json.JSONDecodeError as e:
raise ValueError(f"{jsonl_path}:{ln} JSON parse error: {e}")
num = int(node["num"], 16) if isinstance(node["num"], str) else int(node["num"])
# Header
info = _build_node_info_lite(node, now_epoch)
db.nodes.append(info)
# Satellites (nullable)
if node.get("position"):
db.positions.append(_build_position_entry(num, node["position"], now_epoch))
if node.get("telemetry"):
db.telemetry.append(_build_telemetry_entry(num, node["telemetry"]))
if node.get("environment"):
db.environment.append(_build_environment_entry(num, node["environment"]))
if node.get("status"):
db.status.append(_build_status_entry(num, node["status"]))
return db.SerializeToString()
def main(argv: list[str]) -> int:
p = argparse.ArgumentParser(
description="Compile a seed JSONL into a binary v25 NodeDatabase proto.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
p.add_argument("--in", dest="in_path", required=True, help="Input seed JSONL.")
p.add_argument("--out", required=True, help="Output binary .proto path.")
p.add_argument(
"--now-epoch",
type=int,
default=None,
help="Pin 'now' to this Unix epoch (for byte-identical CI). Default: time.time().",
)
args = p.parse_args(argv)
in_path = pathlib.Path(args.in_path)
if not in_path.is_file():
print(f"input not found: {in_path}", file=sys.stderr)
return 2
now_epoch = args.now_epoch if args.now_epoch is not None else int(time.time())
try:
encoded = compile_jsonl_to_proto(in_path, now_epoch)
except ValueError as e:
print(f"ERROR: {e}", file=sys.stderr)
return 3
out_path = pathlib.Path(args.out)
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_bytes(encoded)
print(
f"compiled {in_path} -> {out_path} ({len(encoded)} bytes, now_epoch={now_epoch})",
file=sys.stderr,
)
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
+42
View File
@@ -0,0 +1,42 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-D BOARD_HAS_PSRAM",
"-D ARDUINO_USB_CDC_ON_BOOT=0",
"-D ARDUINO_USB_MODE=0",
"-D ARDUINO_RUNNING_CORE=1",
"-D ARDUINO_EVENT_RUNNING_CORE=0"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"psram_type": "qio_opi",
"hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3",
"variant": "ELECROW-ThinkNode-M7"
},
"connectivity": ["wifi", "bluetooth", "lora"],
"debug": {
"default_tool": "esp-builtin",
"onboard_tools": ["esp-builtin"],
"openocd_target": "esp32s3.cfg"
},
"frameworks": ["arduino", "espidf"],
"name": "ELECROW ThinkNode M7",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 524288,
"maximum_size": 8388608,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 921600
},
"url": "https://www.elecrow.com",
"vendor": "ELECROW"
}
+382
View File
@@ -0,0 +1,382 @@
"""Fake NodeDB fixture push — Portduino file copy + hardware XModem upload.
The fixture pipeline is two-stage:
1. `bin/gen-fake-nodedb-seed.py` produces a deterministic JSONL describing N
fake-but-realistic peers. Committed under `test/fixtures/nodedb/`.
2. `bin/seed-json-to-proto.py` compiles JSONL → binary v25 NodeDatabase
protobuf with fresh wall-clock timestamps.
This module exposes `push_fake_nodedb(...)`, the MCP tool that:
- target="portduino": compiles the JSONL into the device's prefs dir on
the local filesystem (`~/.portduino/<config>/prefs/nodes.proto`).
- target="hardware": compiles to a temp file, then streams it over the
XModem protocol (via the meshtastic SerialInterface/BLEInterface +
`meshtastic.xmodempacket` pubsub topic) to `/prefs/nodes.proto` on the
device. Triggers a reboot so the firmware loads the new state on next
boot.
XModem wire details (mirrors firmware impl at src/xmodem.cpp:115-260):
* 128-byte chunks; final chunk padded to 128 B with 0x1A (SUB) bytes.
* CRC16-CCITT (poly 0x1021, init 0x0000).
* SOH/seq=0 carries the destination filename in `buffer.bytes`. ACK if
`FSCom.open(filename, FILE_O_WRITE)` succeeds; NAK otherwise.
* SOH/seq≥1 carries a 128-byte chunk. ACK = advance; NAK = retransmit.
* EOT after the last chunk flushes + closes the file on-device.
Hardware push requires `confirm=True` (mirrors factory_reset / erase_and_flash
in the .github/copilot-instructions.md "never do these without asking" list).
"""
from __future__ import annotations
import dataclasses
import hashlib
import pathlib
import queue
import shutil
import subprocess
import sys
import tempfile
import time
from typing import Any, Literal
from .connection import connect, is_tcp_port
# Resolve repo root so the tool works regardless of mcp-server cwd.
_REPO_ROOT = pathlib.Path(__file__).resolve().parents[3]
_SEED_DIR = _REPO_ROOT / "test" / "fixtures" / "nodedb"
_COMPILE_SCRIPT = _REPO_ROOT / "bin" / "seed-json-to-proto.py"
_DEFAULT_NODES_FILENAME = "/prefs/nodes.proto"
_XMODEM_CHUNK = 128
_XMODEM_SUB = 0x1A
_ACK_TIMEOUT_INIT_S = 5.0
_ACK_TIMEOUT_CHUNK_S = 2.0
_MAX_CHUNK_RETRIES = 5
_VALID_SIZES = (250, 500, 1000, 2000)
class FixtureError(RuntimeError):
"""Raised for any fixture-push failure (compile, transport, ack timeout, …)."""
# ---------------------------------------------------------------------------
# CRC16-CCITT (poly 0x1021, init 0x0000). Matches the firmware's `crc16_ccitt`.
# Hand-rolled to avoid the optional `crcmod` dep.
# ---------------------------------------------------------------------------
def _crc16_ccitt(data: bytes, *, init: int = 0x0000) -> int:
crc = init
for b in data:
crc ^= b << 8
for _ in range(8):
if crc & 0x8000:
crc = ((crc << 1) ^ 0x1021) & 0xFFFF
else:
crc = (crc << 1) & 0xFFFF
return crc
# ---------------------------------------------------------------------------
# Compile step — shells out to bin/seed-json-to-proto.py so the MCP module
# doesn't have to duplicate the proto-encoding logic.
# ---------------------------------------------------------------------------
def _compile_proto(jsonl_path: pathlib.Path, out_path: pathlib.Path) -> None:
if not _COMPILE_SCRIPT.is_file():
raise FixtureError(f"compile script missing at {_COMPILE_SCRIPT}")
cmd = [
sys.executable,
str(_COMPILE_SCRIPT),
"--in",
str(jsonl_path),
"--out",
str(out_path),
]
try:
subprocess.run(cmd, check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as exc:
raise FixtureError(
f"seed-json-to-proto.py failed (exit {exc.returncode}):\n"
f" stdout: {exc.stdout}\n stderr: {exc.stderr}"
) from exc
def _resolve_seed_jsonl(size: int, custom: str | None) -> pathlib.Path:
if custom is not None:
p = pathlib.Path(custom).expanduser().resolve()
if not p.is_file():
raise FixtureError(f"custom_seed_jsonl not found: {p}")
return p
p = _SEED_DIR / f"seed_v25_{size:04d}.jsonl"
if not p.is_file():
raise FixtureError(
f"missing committed seed at {p}. "
f"Run `./bin/regen-fake-nodedbs.sh` to generate it."
)
return p
# ---------------------------------------------------------------------------
# Portduino push — file copy into ~/.portduino/<config>/prefs/
# ---------------------------------------------------------------------------
def _portduino_prefs_dir(config_name: str) -> pathlib.Path:
home = pathlib.Path.home()
return home / ".portduino" / config_name / "prefs"
def _push_portduino(
size: int,
jsonl: pathlib.Path,
portduino_config: str,
backup_existing: bool,
) -> dict[str, Any]:
prefs = _portduino_prefs_dir(portduino_config)
prefs.mkdir(parents=True, exist_ok=True)
target = prefs / "nodes.proto"
backed_up_to: str | None = None
if backup_existing and target.is_file():
ts = int(time.time())
backup = prefs / f"nodes.proto.bak.{ts}"
shutil.move(str(target), str(backup))
backed_up_to = str(backup)
_compile_proto(jsonl, target)
raw = target.read_bytes()
return {
"transport": "portduino",
"path": str(target),
"bytes": len(raw),
"sha256": hashlib.sha256(raw).hexdigest(),
"jsonl_source": str(jsonl),
"backed_up_to": backed_up_to,
}
# ---------------------------------------------------------------------------
# Hardware push — XModem over BLE/serial via the meshtastic Python interface.
# ---------------------------------------------------------------------------
@dataclasses.dataclass
class _AckEvent:
control: int
seq: int
def _wait_for_response(q: "queue.Queue[_AckEvent]", timeout_s: float) -> _AckEvent:
try:
return q.get(timeout=timeout_s)
except queue.Empty as exc:
raise FixtureError(
f"XModem response timeout after {timeout_s:.1f}s — device not responding"
) from exc
def _push_hardware(
size: int,
jsonl: pathlib.Path,
port: str | None,
reboot_after: bool,
) -> dict[str, Any]:
# Lazy imports so the module loads even when the meshtastic deps aren't
# available (e.g. CI in a Python env without the package installed).
try:
from meshtastic.protobuf import mesh_pb2, xmodem_pb2
from pubsub import pub
except ImportError as exc: # pragma: no cover — dep missing
raise FixtureError(
f"hardware push requires the meshtastic + pypubsub packages: {exc}"
) from exc
if is_tcp_port(port):
raise FixtureError(
"hardware push over TCP/portduino is not supported — use "
"target='portduino' to drop the fixture directly into the prefs dir."
)
# Compile the fixture to a temp file with fresh timestamps.
with tempfile.NamedTemporaryFile(suffix=".proto", delete=False) as tf:
proto_path = pathlib.Path(tf.name)
try:
_compile_proto(jsonl, proto_path)
payload = proto_path.read_bytes()
finally:
proto_path.unlink(missing_ok=True)
sha256 = hashlib.sha256(payload).hexdigest()
total_bytes = len(payload)
# Subscribe to XModem responses BEFORE we open the interface, so we don't
# race the first ACK that arrives during the SOH/seq=0 handshake.
#
# NB: the signature MUST declare every kwarg pypubsub will see for this
# topic, or pubsub locks the topic spec to a smaller set (whichever
# subscribe arrives first) and then *rejects* the meshtastic library's
# publish call with `SenderUnknownMsgDataError: unknown ... interface`.
# The meshtastic lib publishes both `packet=` and `interface=`
# (mesh_interface.py:1389-1395), so both must appear here.
response_q: "queue.Queue[_AckEvent]" = queue.Queue()
def _on_xmodem(packet: Any = None, interface: Any = None, **_kw: Any) -> None:
if packet is None:
return
response_q.put(_AckEvent(control=int(packet.control), seq=int(packet.seq)))
pub.subscribe(_on_xmodem, "meshtastic.xmodempacket")
chunks_sent = 0
retried = 0
rebooted = False
XMC = xmodem_pb2.XModem.Control
try:
with connect(port=port) as iface:
# 1) Send the filename (SOH, seq=0).
init_pkt = xmodem_pb2.XModem(
control=XMC.Value("SOH"),
seq=0,
buffer=_DEFAULT_NODES_FILENAME.encode("utf-8"),
)
iface._sendToRadio(mesh_pb2.ToRadio(xmodemPacket=init_pkt))
ack = _wait_for_response(response_q, _ACK_TIMEOUT_INIT_S)
if ack.control != XMC.Value("ACK"):
raise FixtureError(
f"device refused filename {_DEFAULT_NODES_FILENAME!r} "
f"(got control={ack.control}, expected ACK). "
f"Filesystem full or permissions issue?"
)
# 2) Stream the payload in 128 B chunks.
for offset in range(0, total_bytes, _XMODEM_CHUNK):
chunk = payload[offset : offset + _XMODEM_CHUNK]
if len(chunk) < _XMODEM_CHUNK:
# Pad final chunk to 128 B with SUB. The trailing 0x1A bytes
# become part of the file on-device, but nanopb ignores
# bytes past the end of the top-level message.
chunk = chunk + bytes([_XMODEM_SUB] * (_XMODEM_CHUNK - len(chunk)))
seq = ((offset // _XMODEM_CHUNK) + 1) % 256
# Retry loop on NAK / timeout.
attempts = 0
while True:
pkt = xmodem_pb2.XModem(
control=XMC.Value("SOH"),
seq=seq,
buffer=chunk,
crc16=_crc16_ccitt(chunk),
)
iface._sendToRadio(mesh_pb2.ToRadio(xmodemPacket=pkt))
ack = _wait_for_response(response_q, _ACK_TIMEOUT_CHUNK_S)
if ack.control == XMC.Value("ACK"):
chunks_sent += 1
break
if ack.control == XMC.Value("NAK"):
attempts += 1
retried += 1
if attempts >= _MAX_CHUNK_RETRIES:
# Abort: send CAN so the firmware removes the half-
# written file via FSCom.remove(filename).
iface._sendToRadio(
mesh_pb2.ToRadio(
xmodemPacket=xmodem_pb2.XModem(
control=XMC.Value("CAN")
)
)
)
raise FixtureError(
f"chunk seq={seq} NAK'd {attempts} times; "
f"aborted transfer (file removed on-device)."
)
continue # retry the same chunk
raise FixtureError(
f"unexpected XModem control={ack.control} on seq={seq}"
)
# 3) Tell the device we're done.
iface._sendToRadio(
mesh_pb2.ToRadio(
xmodemPacket=xmodem_pb2.XModem(control=XMC.Value("EOT"))
)
)
ack = _wait_for_response(response_q, _ACK_TIMEOUT_CHUNK_S)
if ack.control != XMC.Value("ACK"):
raise FixtureError(f"EOT not ACKed (got control={ack.control})")
# 4) Reboot so loadFromDisk picks up the new file.
if reboot_after:
iface.localNode.reboot(secs=1)
rebooted = True
finally:
try:
pub.unsubscribe(_on_xmodem, "meshtastic.xmodempacket")
except Exception:
pass
return {
"transport": "hardware",
"port": port,
"filename_on_device": _DEFAULT_NODES_FILENAME,
"bytes": total_bytes,
"chunks_sent": chunks_sent,
"retried": retried,
"sha256": sha256,
"jsonl_source": str(jsonl),
"rebooted": rebooted,
}
# ---------------------------------------------------------------------------
# Public entry point — registered as an MCP tool in server.py.
# ---------------------------------------------------------------------------
def push_fake_nodedb(
size: int,
target: Literal["portduino", "hardware"] = "portduino",
*,
port: str | None = None,
portduino_config: str = "default",
backup_existing: bool = True,
confirm: bool = False,
reboot_after: bool = True,
custom_seed_jsonl: str | None = None,
) -> dict[str, Any]:
"""Compile a fresh-timestamp NodeDatabase fixture and push it to a device.
Args:
size: 250, 500, 1000, or 2000 — selects which committed seed JSONL to use.
target: "portduino" (file copy to ~/.portduino/<config>/prefs/) or
"hardware" (XModem upload to /prefs/nodes.proto + reboot).
port: required for target="hardware". Serial path (e.g. /dev/cu.usbmodemXXXX)
or BLE identifier. TCP endpoints are rejected — use target="portduino"
instead.
portduino_config: which Portduino instance dir under ~/.portduino/. Default "default".
backup_existing: portduino only. Move nodes.proto -> nodes.proto.bak.<ts>
if present, so you can roll back.
confirm: required True for target="hardware" (writes flash + reboots).
reboot_after: hardware only. If True, send a 1-second reboot after the
final ACK so loadFromDisk picks up the new file at next boot.
custom_seed_jsonl: override the committed JSONL. Use to push a hand-edited
test scenario.
Returns:
dict with transport, bytes, sha256, etc. — depends on target.
"""
if size not in _VALID_SIZES:
raise FixtureError(
f"size must be one of {_VALID_SIZES}; got {size!r}. "
f"Add a new committed seed if you need a different cardinality."
)
jsonl = _resolve_seed_jsonl(size, custom_seed_jsonl)
if target == "portduino":
return _push_portduino(size, jsonl, portduino_config, backup_existing)
if target == "hardware":
if not confirm:
raise FixtureError(
"hardware push writes flash and triggers a reboot — pass confirm=True."
)
if not port:
raise FixtureError(
"target='hardware' requires a port (e.g. /dev/cu.usbmodemXXXX)."
)
return _push_hardware(size, jsonl, port, reboot_after)
raise FixtureError(f"unknown target {target!r}; expected 'portduino' or 'hardware'")
+43
View File
@@ -15,6 +15,7 @@ from . import (
admin,
boards,
devices,
fixtures,
flash,
hw_tools,
info,
@@ -963,3 +964,45 @@ def recorder_export(
dest_dir=dest_dir,
streams=streams,
)
# ---------- Fixture / test-data push --------------------------------------
@app.tool()
def push_fake_nodedb(
size: int,
target: str = "portduino",
port: str | None = None,
portduino_config: str = "default",
backup_existing: bool = True,
confirm: bool = False,
reboot_after: bool = True,
custom_seed_jsonl: str | None = None,
) -> dict[str, Any]:
"""Push a fake-NodeDB v25 fixture (250/500/1000/2000 nodes) onto a device.
Two transports:
target="portduino" — file copy to ~/.portduino/<portduino_config>/prefs/nodes.proto.
Fast, no device connection needed.
target="hardware" — XModem upload over serial/BLE to /prefs/nodes.proto.
Requires `port` + `confirm=True`. Triggers a reboot
so loadFromDisk picks up the new file at next boot.
Compiles a fresh-timestamp proto from the committed JSONL seed under
test/fixtures/nodedb/seed_v25_<N>.jsonl each invocation, so the loaded
NodeDB always looks "recent" to the connecting phone. Structural data
(names, IDs, positions, telemetries) is deterministic per the seed.
Override the JSONL via `custom_seed_jsonl` to push a hand-edited scenario.
"""
return fixtures.push_fake_nodedb(
size=size,
target=target, # type: ignore[arg-type]
port=port,
portduino_config=portduino_config,
backup_existing=backup_existing,
confirm=confirm,
reboot_after=reboot_after,
custom_seed_jsonl=custom_seed_jsonl,
)
@@ -0,0 +1,364 @@
"""Tests for the fake-NodeDB fixture pipeline (bin/gen-fake-nodedb-seed.py
+ bin/seed-json-to-proto.py + mcp-server fixtures.push_fake_nodedb).
Lives under tests/unit/ because none of these touch real hardware — they
shell out to the bin/ scripts and decode the resulting protobufs in-process.
"""
from __future__ import annotations
import json
import pathlib
import subprocess
import sys
import time
import pytest
REPO_ROOT = pathlib.Path(__file__).resolve().parents[3]
SEED_GEN = REPO_ROOT / "bin" / "gen-fake-nodedb-seed.py"
COMPILE = REPO_ROOT / "bin" / "seed-json-to-proto.py"
FIXTURES_DIR = REPO_ROOT / "test" / "fixtures" / "nodedb"
# Ensure the locally-generated Python protobuf bindings are importable.
# These live under `meshtastic_v25` (not `meshtastic`) so they don't shadow
# the PyPI `meshtastic` package that the rest of the mcp-server depends on.
_BINDINGS_DIR = REPO_ROOT / "bin" / "_generated"
if _BINDINGS_DIR.is_dir() and str(_BINDINGS_DIR) not in sys.path:
sys.path.insert(0, str(_BINDINGS_DIR))
try:
from meshtastic_v25.deviceonly_pb2 import (
NodeDatabase, # type: ignore[import-not-found]
)
except ImportError:
NodeDatabase = None # type: ignore[assignment]
def _require_v25_bindings() -> None:
if NodeDatabase is None:
pytest.skip(
"v25 Python protobuf bindings missing; run `./bin/regen-py-protos.sh`."
)
if "positions" not in NodeDatabase.DESCRIPTOR.fields_by_name:
pytest.skip(
"Loaded NodeDatabase predates v25 — run `./bin/regen-py-protos.sh`."
)
def _run(cmd: list[str]) -> None:
subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
# ---------------------------------------------------------------------------
# Seed generator: deterministic for given --seed (no wall-clock dependence).
# ---------------------------------------------------------------------------
def test_seed_generator_is_deterministic(tmp_path: pathlib.Path) -> None:
a = tmp_path / "a.jsonl"
b = tmp_path / "b.jsonl"
_run(
[
sys.executable,
str(SEED_GEN),
"--count",
"100",
"--seed",
"42",
"--out",
str(a),
]
)
# Sleep so any sneaky wall-clock leak in the generator would surface as
# a byte diff between the two runs.
time.sleep(0.8)
_run(
[
sys.executable,
str(SEED_GEN),
"--count",
"100",
"--seed",
"42",
"--out",
str(b),
]
)
assert a.read_bytes() == b.read_bytes()
def test_seed_generator_meta_line(tmp_path: pathlib.Path) -> None:
out = tmp_path / "seed.jsonl"
_run(
[
sys.executable,
str(SEED_GEN),
"--count",
"50",
"--seed",
"1",
"--out",
str(out),
]
)
lines = out.read_text(encoding="utf-8").splitlines()
assert len(lines) == 51 # 1 meta + 50 nodes
meta = json.loads(lines[0])
assert "_meta" in meta
assert meta["_meta"]["version"] == 25
assert meta["_meta"]["count"] == 50
assert meta["_meta"]["seed"] == 1
def test_seed_only_uses_active_hardware_and_roles(tmp_path: pathlib.Path) -> None:
"""Confirm no deprecated roles + no off-list HW models leak through."""
out = tmp_path / "seed.jsonl"
_run(
[
sys.executable,
str(SEED_GEN),
"--count",
"500",
"--seed",
"7",
"--out",
str(out),
]
)
forbidden_roles = {"ROUTER_CLIENT", "REPEATER"}
forbidden_hw = {
"TLORA_V1",
"TLORA_V2",
"TLORA_V1_1P3",
"TLORA_V2_1_1P6",
"TLORA_V2_1_1P8",
"HELTEC_V1",
"HELTEC_V2_0",
"HELTEC_V2_1",
"TBEAM",
"TBEAM_V0P7",
"NANO_G1",
"NANO_G1_EXPLORER",
"NANO_G2_ULTRA",
"STATION_G1",
"STATION_G2",
"PORTDUINO",
"ANDROID_SIM",
"DIY_V1",
"LORA_RELAY_V1",
"NRF52840_PCA10059",
"NRF52_UNKNOWN",
"DR_DEV",
"GENIEBLOCKS",
"M5STACK",
"RP2040_LORA",
"PPR",
}
for raw in out.read_text(encoding="utf-8").splitlines()[1:]:
node = json.loads(raw)
assert node["role"] not in forbidden_roles, f"deprecated role: {node['role']}"
assert (
node["hw_model"] not in forbidden_hw
), f"non-tier-1 HW: {node['hw_model']}"
# ---------------------------------------------------------------------------
# Compile step + committed seeds.
# ---------------------------------------------------------------------------
@pytest.mark.parametrize("size", [250, 500, 1000, 2000])
def test_committed_seed_compiles_and_decodes(size: int, tmp_path: pathlib.Path) -> None:
_require_v25_bindings()
proto = tmp_path / "out.proto"
jsonl = FIXTURES_DIR / f"seed_v25_{size:04d}.jsonl"
if not jsonl.is_file():
pytest.skip(f"{jsonl} not present — run ./bin/regen-fake-nodedbs.sh")
_run([sys.executable, str(COMPILE), "--in", str(jsonl), "--out", str(proto)])
db = NodeDatabase()
db.ParseFromString(proto.read_bytes())
assert db.version == 25
assert len(db.nodes) == size
nums = {n.num for n in db.nodes}
assert len(nums) == size, "node numbers must be unique"
assert all(n.long_name and n.short_name for n in db.nodes)
assert all(len(n.long_name) <= 24 for n in db.nodes) # max_size:25 - NUL
# Coverage sanity (±10pp tolerance for binomial fluctuation).
def in_range(actual: int, expected_ratio: float, tol_pp: float = 0.10) -> bool:
lo = max(0, int((expected_ratio - tol_pp) * size))
hi = min(size, int((expected_ratio + tol_pp) * size))
return lo <= actual <= hi
assert in_range(len(db.positions), 0.85)
assert in_range(len(db.telemetry), 0.70)
assert in_range(len(db.environment), 0.25)
assert in_range(len(db.status), 0.40)
def test_compile_freshens_timestamps(tmp_path: pathlib.Path) -> None:
"""Same JSONL compiled twice → identical structure, different timestamps."""
_require_v25_bindings()
jsonl = FIXTURES_DIR / "seed_v25_0250.jsonl"
if not jsonl.is_file():
pytest.skip("250-node seed not present — run ./bin/regen-fake-nodedbs.sh")
a = tmp_path / "a.proto"
b = tmp_path / "b.proto"
_run([sys.executable, str(COMPILE), "--in", str(jsonl), "--out", str(a)])
time.sleep(1.2)
_run([sys.executable, str(COMPILE), "--in", str(jsonl), "--out", str(b)])
da = NodeDatabase()
db_ = NodeDatabase()
da.ParseFromString(a.read_bytes())
db_.ParseFromString(b.read_bytes())
# Zero out timestamp fields and confirm everything else is byte-identical.
for d in (da, db_):
for n in d.nodes:
n.last_heard = 0
for p in d.positions:
p.position.time = 0
assert da.SerializeToString() == db_.SerializeToString()
# Re-load fresh copies to confirm timestamps actually moved.
aa = NodeDatabase()
bb = NodeDatabase()
aa.ParseFromString(a.read_bytes())
bb.ParseFromString(b.read_bytes())
aa_max = max(n.last_heard for n in aa.nodes if n.last_heard)
bb_max = max(n.last_heard for n in bb.nodes if n.last_heard)
assert bb_max >= aa_max
assert bb_max - aa_max < 5 # within a few seconds
def test_compile_pinned_now_epoch_is_byte_identical(tmp_path: pathlib.Path) -> None:
"""With --now-epoch pinned, two compiles produce identical bytes."""
_require_v25_bindings()
jsonl = FIXTURES_DIR / "seed_v25_0250.jsonl"
if not jsonl.is_file():
pytest.skip("250-node seed not present")
a = tmp_path / "a.proto"
b = tmp_path / "b.proto"
for o in (a, b):
_run(
[
sys.executable,
str(COMPILE),
"--in",
str(jsonl),
"--now-epoch",
"1700000000",
"--out",
str(o),
]
)
assert a.read_bytes() == b.read_bytes()
def test_compile_timestamps_are_recent(tmp_path: pathlib.Path) -> None:
_require_v25_bindings()
jsonl = FIXTURES_DIR / "seed_v25_0250.jsonl"
if not jsonl.is_file():
pytest.skip("250-node seed not present")
out = tmp_path / "out.proto"
_run([sys.executable, str(COMPILE), "--in", str(jsonl), "--out", str(out)])
db = NodeDatabase()
db.ParseFromString(out.read_bytes())
now = int(time.time())
# No timestamp older than 7 days, none in the future.
for n in db.nodes:
if n.last_heard:
assert now - 7 * 86400 <= n.last_heard <= now
# At least half should be within the last hour
# (matches expovariate(mean=3600s)).
recent = sum(1 for n in db.nodes if n.last_heard and n.last_heard >= now - 3600)
assert recent >= 0.4 * len(db.nodes)
def test_compile_hand_edit_round_trip(tmp_path: pathlib.Path) -> None:
"""Edit one JSONL line, recompile, confirm edit appears in the proto."""
_require_v25_bindings()
src = FIXTURES_DIR / "seed_v25_0250.jsonl"
if not src.is_file():
pytest.skip("250-node seed not present")
dst = tmp_path / "edited.jsonl"
lines = src.read_text(encoding="utf-8").splitlines()
# Find a node that already has telemetry so the index relationship is
# easy to assert on the other side.
edit_idx = None
for i, raw in enumerate(lines[1:], start=1):
node = json.loads(raw)
if node.get("telemetry") is not None:
edit_idx = i
break
assert edit_idx is not None, "expected at least one node with telemetry"
node = json.loads(lines[edit_idx])
target_num = int(node["num"], 16)
node["long_name"] = "Hand Edited Node"
node["telemetry"] = {
"battery_level": 42,
"voltage": 3.71,
"channel_utilization": 0.0,
"air_util_tx": 0.0,
"uptime_seconds": 1,
}
lines[edit_idx] = json.dumps(node, ensure_ascii=False, sort_keys=True)
dst.write_text("\n".join(lines) + "\n", encoding="utf-8")
out = tmp_path / "out.proto"
_run([sys.executable, str(COMPILE), "--in", str(dst), "--out", str(out)])
db = NodeDatabase()
db.ParseFromString(out.read_bytes())
edited = next((n for n in db.nodes if n.num == target_num), None)
assert edited is not None
assert edited.long_name == "Hand Edited Node"
tel = next((t for t in db.telemetry if t.num == target_num), None)
assert tel is not None
assert tel.device_metrics.battery_level == 42
# ---------------------------------------------------------------------------
# Misc smoke checks on the module surface.
# ---------------------------------------------------------------------------
def test_crc16_ccitt_matches_known_vectors() -> None:
"""Sanity-check the hand-rolled CRC16-CCITT matches well-known vectors.
Test vectors from the XModem-CRC spec (init=0, poly=0x1021):
crc16("123456789") = 0x31C3
crc16("") = 0x0000
"""
from meshtastic_mcp.fixtures import _crc16_ccitt
assert _crc16_ccitt(b"") == 0x0000
assert _crc16_ccitt(b"123456789") == 0x31C3
def test_push_fake_nodedb_rejects_invalid_size() -> None:
from meshtastic_mcp.fixtures import FixtureError, push_fake_nodedb
with pytest.raises(FixtureError, match="size must be one of"):
push_fake_nodedb(size=999, target="portduino") # type: ignore[arg-type]
def test_push_fake_nodedb_hardware_requires_confirm() -> None:
from meshtastic_mcp.fixtures import FixtureError, push_fake_nodedb
with pytest.raises(FixtureError, match="confirm=True"):
push_fake_nodedb(size=250, target="hardware", port="/dev/cu.fake")
def test_push_fake_nodedb_hardware_requires_port() -> None:
from meshtastic_mcp.fixtures import FixtureError, push_fake_nodedb
with pytest.raises(FixtureError, match="requires a port"):
push_fake_nodedb(size=250, target="hardware", confirm=True)
def test_push_fake_nodedb_hardware_rejects_tcp_port() -> None:
from meshtastic_mcp.fixtures import FixtureError, push_fake_nodedb
with pytest.raises(FixtureError, match="not supported"):
push_fake_nodedb(
size=250, target="hardware", confirm=True, port="tcp://localhost:4403"
)
+1 -2
View File
@@ -49,6 +49,7 @@ build_flags = -Wno-missing-field-initializers
-DRADIOLIB_EXCLUDE_PAGER=1
-DRADIOLIB_EXCLUDE_FSK4=1
-DRADIOLIB_EXCLUDE_APRS=1
-DRADIOLIB_EXCLUDE_ADSB=1
-DRADIOLIB_EXCLUDE_LORAWAN=1
-DMESHTASTIC_EXCLUDE_DROPZONE=1
-DMESHTASTIC_EXCLUDE_REPLYBOT=1
@@ -138,8 +139,6 @@ lib_deps =
https://github.com/adafruit/Adafruit-GFX-Library/archive/refs/tags/1.12.6.zip
# renovate: datasource=github-tags depName=NeoPixel packageName=adafruit/Adafruit_NeoPixel
https://github.com/adafruit/Adafruit_NeoPixel/archive/refs/tags/1.15.4.zip
# renovate: datasource=github-tags depName=Adafruit SSD1306 packageName=adafruit/Adafruit_SSD1306
https://github.com/adafruit/Adafruit_SSD1306/archive/refs/tags/2.5.16.zip
# renovate: datasource=github-tags depName=Adafruit BMP280 packageName=adafruit/Adafruit_BMP280_Library
https://github.com/adafruit/Adafruit_BMP280_Library/archive/refs/tags/3.0.0.zip
# renovate: datasource=github-tags depName=Adafruit BMP085 packageName=adafruit/Adafruit-BMP085-Library
+1 -1
View File
@@ -151,7 +151,7 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess
if (!this->_enabled)
return false;
if ((this->_server == NULL && this->_ip == INADDR_NONE) || this->_port == 0)
if ((this->_server == NULL && this->_ip == IPAddress(0, 0, 0, 0)) || this->_port == 0)
return false;
// Check priority against priMask values.
+8 -1
View File
@@ -13,6 +13,11 @@ extern MemGet memGet;
#define LED_STATE_ON 1
#endif
// WIFI LED
#ifndef WIFI_STATE_ON
#define WIFI_STATE_ON 1
#endif
// -----------------------------------------------------------------------------
// DEBUG
// -----------------------------------------------------------------------------
@@ -147,7 +152,9 @@ extern "C" void logLegacy(const char *level, const char *fmt, ...);
// Default Bluetooth PIN
#define defaultBLEPin 123456
#if HAS_ETHERNET && !defined(USE_WS5500)
#if HAS_ETHERNET && defined(USE_CH390D)
#include <ESP32_CH390.h>
#elif HAS_ETHERNET && !defined(USE_WS5500)
#include <RAK13800_W5100S.h>
#endif // HAS_ETHERNET
+26 -31
View File
@@ -6,7 +6,6 @@
#include "SPILock.h"
#include "SafeFile.h"
#include "gps/RTC.h"
#include "graphics/draw/MessageRenderer.h"
#include <cstring> // memcpy
#ifndef MESSAGE_TEXT_POOL_SIZE
@@ -181,13 +180,8 @@ const StoredMessage &MessageStore::addFromPacket(const meshtastic_MeshPacket &pa
bool isDM = (sm.dest != 0 && sm.dest != NODENUM_BROADCAST);
if (packet.from == 0) {
sm.type = isDM ? MessageType::DM_TO_US : MessageType::BROADCAST;
sm.ackStatus = AckStatus::NONE;
} else {
sm.type = isDM ? MessageType::DM_TO_US : MessageType::BROADCAST;
sm.ackStatus = AckStatus::ACKED;
}
sm.type = isDM ? MessageType::DM_TO_US : MessageType::BROADCAST;
sm.ackStatus = (packet.from == 0) ? AckStatus::NONE : AckStatus::ACKED;
addLiveMessage(sm);
@@ -372,26 +366,25 @@ void MessageStore::clearAllMessages()
#endif
}
// Internal helper: erase first or last message matching a predicate
template <typename Predicate> static void eraseIf(std::deque<StoredMessage> &deque, Predicate pred, bool fromBack = false)
// Internal helpers for targeted erasure.
template <typename Predicate> static bool eraseFirstMatch(std::deque<StoredMessage> &deque, Predicate pred)
{
if (fromBack) {
// Iterate from the back and erase all matches from the end
for (auto it = deque.rbegin(); it != deque.rend();) {
if (pred(*it)) {
it = std::deque<StoredMessage>::reverse_iterator(deque.erase(std::next(it).base()));
} else {
++it;
}
for (auto it = deque.begin(); it != deque.end(); ++it) {
if (pred(*it)) {
deque.erase(it);
return true;
}
} else {
// Manual forward search to erase all matches
for (auto it = deque.begin(); it != deque.end();) {
if (pred(*it)) {
it = deque.erase(it);
} else {
++it;
}
}
return false;
}
template <typename Predicate> static void eraseAllMatches(std::deque<StoredMessage> &deque, Predicate pred)
{
for (auto it = deque.begin(); it != deque.end();) {
if (pred(*it)) {
it = deque.erase(it);
} else {
++it;
}
}
}
@@ -399,7 +392,9 @@ template <typename Predicate> static void eraseIf(std::deque<StoredMessage> &deq
// Delete oldest message (RAM + persisted queue)
void MessageStore::deleteOldestMessage()
{
eraseIf(liveMessages, [](StoredMessage &) { return true; });
if (!liveMessages.empty()) {
liveMessages.pop_front();
}
saveToFlash();
}
@@ -407,14 +402,14 @@ void MessageStore::deleteOldestMessage()
void MessageStore::deleteOldestMessageInChannel(uint8_t channel)
{
auto pred = [channel](const StoredMessage &m) { return m.type == MessageType::BROADCAST && m.channelIndex == channel; };
eraseIf(liveMessages, pred);
eraseFirstMatch(liveMessages, pred);
saveToFlash();
}
void MessageStore::deleteAllMessagesInChannel(uint8_t channel)
{
auto pred = [channel](const StoredMessage &m) { return m.type == MessageType::BROADCAST && m.channelIndex == channel; };
eraseIf(liveMessages, pred, false /* delete ALL, not just first */);
eraseAllMatches(liveMessages, pred);
saveToFlash();
}
@@ -427,7 +422,7 @@ void MessageStore::deleteAllMessagesWithPeer(uint32_t peer)
uint32_t other = (m.sender == local) ? m.dest : m.sender;
return other == peer;
};
eraseIf(liveMessages, pred, false);
eraseAllMatches(liveMessages, pred);
saveToFlash();
}
@@ -440,7 +435,7 @@ void MessageStore::deleteOldestMessageWithPeer(uint32_t peer)
uint32_t other = (m.sender == nodeDB->getNodeNum()) ? m.dest : m.sender;
return other == peer;
};
eraseIf(liveMessages, pred);
eraseFirstMatch(liveMessages, pred);
saveToFlash();
}
-3
View File
@@ -124,9 +124,6 @@ class MessageStore
// Allocate text into pool (used by sender-side code)
static uint16_t storeText(const char *src, size_t len);
// Used when loading from flash to rebuild the text pool
static uint16_t rebuildTextFromFlash(const char *src, size_t len);
private:
std::deque<StoredMessage> liveMessages; // Single in-RAM message buffer (also used for persistence)
std::string filename; // Flash filename for persistence
+2 -2
View File
@@ -230,9 +230,9 @@ void RedirectablePrint::log_to_ble(const char *logLevel, const char *format, va_
auto thread = concurrency::OSThread::currentThread;
meshtastic_LogRecord logRecord = meshtastic_LogRecord_init_zero;
logRecord.level = getLogLevel(logLevel);
vsprintf(logRecord.message, format, arg);
vsnprintf(logRecord.message, sizeof(logRecord.message), format, arg);
if (thread)
strcpy(logRecord.source, thread->ThreadName.c_str());
strlcpy(logRecord.source, thread->ThreadName.c_str(), sizeof(logRecord.source));
logRecord.time = getValidTime(RTCQuality::RTCQualityDevice, true);
auto buffer = std::unique_ptr<uint8_t[]>(new uint8_t[meshtastic_LogRecord_size]);
-133
View File
@@ -65,7 +65,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "mesh/Default.h"
#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "modules/ExternalNotificationModule.h"
#include "modules/TextMessageModule.h"
#include "modules/WaypointModule.h"
#include "sleep.h"
#include "target_specific.h"
@@ -1643,138 +1642,6 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
return 0;
}
// Handles when message is received; will jump to text message frame.
int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
{
if (showingNormalScreen) {
if (packet->from == 0) {
// Outgoing message (likely sent from phone)
devicestate.has_rx_text_message = false;
memset(&devicestate.rx_text_message, 0, sizeof(devicestate.rx_text_message));
hiddenFrames.textMessage = true;
hasUnreadMessage = false; // Clear unread state when user replies
setFrames(FOCUS_PRESERVE); // Stay on same frame, silently update frame list
} else {
// Incoming message
devicestate.has_rx_text_message = true; // Needed to include the message frame
hasUnreadMessage = true; // Enables mail icon in the header
setFrames(FOCUS_PRESERVE); // Refresh frame list without switching view (no-op during text_input)
// Only wake/force display if the configuration allows it
if (shouldWakeOnReceivedMessage()) {
setOn(true); // Wake up the screen first
forceDisplay(); // Forces screen redraw
}
// === Prepare banner/popup content ===
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(packet->from);
const meshtastic_Channel channel =
channels.getByIndex(packet->channel ? packet->channel : channels.getPrimaryIndex());
const char *longName = nodeInfoLiteHasUser(node) ? node->long_name : nullptr;
const char *msgRaw = reinterpret_cast<const char *>(packet->decoded.payload.bytes);
char banner[256];
bool isAlert = false;
if (moduleConfig.external_notification.alert_bell || moduleConfig.external_notification.alert_bell_vibra ||
moduleConfig.external_notification.alert_bell_buzzer)
// Check for bell character to determine if this message is an alert
for (size_t i = 0; i < packet->decoded.payload.size && i < 100; i++) {
if (msgRaw[i] == ASCII_BELL) {
isAlert = true;
break;
}
}
// Unlike generic messages, alerts (when enabled via the ext notif module) ignore any
// 'mute' preferences set to any specific node or channel.
// If on-screen keyboard is active, show a transient popup over keyboard instead of interrupting it
if (NotificationRenderer::current_notification_type == notificationTypeEnum::text_input) {
// Wake and force redraw so popup is visible immediately
if (shouldWakeOnReceivedMessage()) {
setOn(true);
forceDisplay();
}
// Build popup: title = message source name, content = message text (sanitized)
// Title
char titleBuf[64] = {0};
if (longName && longName[0]) {
// Sanitize sender name
std::string t = sanitizeString(longName);
strncpy(titleBuf, t.c_str(), sizeof(titleBuf) - 1);
} else {
strncpy(titleBuf, "Message", sizeof(titleBuf) - 1);
}
// Content: payload bytes may not be null-terminated, remove ASCII_BELL and sanitize
char content[256] = {0};
{
std::string raw;
raw.reserve(packet->decoded.payload.size);
for (size_t i = 0; i < packet->decoded.payload.size; ++i) {
char c = msgRaw[i];
if (c == ASCII_BELL)
continue; // strip bell
raw.push_back(c);
}
std::string sanitized = sanitizeString(raw);
strncpy(content, sanitized.c_str(), sizeof(content) - 1);
}
NotificationRenderer::showKeyboardMessagePopupWithTitle(titleBuf, content, 3000);
// Maintain existing buzzer behavior on M5 if applicable
#if defined(M5STACK_UNITC6L)
if (config.device.buzzer_mode != meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY ||
(isAlert && moduleConfig.external_notification.alert_bell_buzzer) ||
(!isBroadcast(packet->to) && isToUs(packet))) {
playLongBeep();
}
#endif
} else {
// No keyboard active: use regular banner flow, respecting mute settings
if (isAlert) {
if (longName && longName[0]) {
snprintf(banner, sizeof(banner), "Alert Received from\n%s", longName);
} else {
strcpy(banner, "Alert Received");
}
screen->showSimpleBanner(banner, 3000);
} else if (!channel.settings.has_module_settings || !channel.settings.module_settings.is_muted) {
if (longName && longName[0]) {
if (currentResolution == ScreenResolution::UltraLow) {
strcpy(banner, "New Message");
} else {
snprintf(banner, sizeof(banner), "New Message from\n%s", longName);
}
} else {
strcpy(banner, "New Message");
}
#if defined(M5STACK_UNITC6L)
screen->setOn(true);
screen->showSimpleBanner(banner, 1500);
if (config.device.buzzer_mode != meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY ||
(isAlert && moduleConfig.external_notification.alert_bell_buzzer) ||
(!isBroadcast(packet->to) && isToUs(packet))) {
// Beep if not in DIRECT_MSG_ONLY mode or if in DIRECT_MSG_ONLY mode and either
// - packet contains an alert and alert bell buzzer is enabled
// - packet is a non-broadcast that is addressed to this node
playLongBeep();
}
#else
screen->showSimpleBanner(banner, 3000);
#endif
}
}
}
}
return 0;
}
// Triggered by MeshModules
int Screen::handleUIFrameEvent(const UIFrameEvent *event)
{
-1
View File
@@ -609,7 +609,6 @@ class Screen : public concurrency::OSThread
// Handle observer events
int handleStatusUpdate(const meshtastic::Status *arg);
int handleTextMessage(const meshtastic_MeshPacket *packet);
int handleUIFrameEvent(const UIFrameEvent *arg);
int handleInputEvent(const InputEvent *arg);
int handleAdminMessage(AdminModule_ObserverData *arg);
+74 -23
View File
@@ -57,6 +57,70 @@ BannerOverlayOptions createStaticBannerOptions(const char *message, const MenuOp
return bannerOptions;
}
const StoredMessage *getNewestMessageForActiveThread()
{
const auto &messages = messageStore.getMessages();
if (messages.empty()) {
return nullptr;
}
const auto mode = graphics::MessageRenderer::getThreadMode();
const int channel = graphics::MessageRenderer::getThreadChannel();
const uint32_t peer = graphics::MessageRenderer::getThreadPeer();
const uint32_t localNode = nodeDB->getNodeNum();
if (mode == graphics::MessageRenderer::ThreadMode::ALL) {
return &messages.back();
}
for (auto it = messages.rbegin(); it != messages.rend(); ++it) {
const StoredMessage &m = *it;
if (mode == graphics::MessageRenderer::ThreadMode::CHANNEL) {
if (m.type == MessageType::BROADCAST && static_cast<int>(m.channelIndex) == channel) {
return &m;
}
continue;
}
if (mode == graphics::MessageRenderer::ThreadMode::DIRECT) {
if (m.type != MessageType::DM_TO_US) {
continue;
}
const uint32_t other = (m.sender == localNode) ? m.dest : m.sender;
if (other == peer) {
return &m;
}
}
}
return nullptr;
}
void launchReplyForMessage(const StoredMessage &message, bool freetext)
{
if (message.type == MessageType::BROADCAST || message.dest == NODENUM_BROADCAST) {
if (freetext) {
cannedMessageModule->LaunchFreetextWithDestination(NODENUM_BROADCAST, message.channelIndex);
} else {
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST, message.channelIndex);
}
return;
}
const uint32_t localNode = nodeDB->getNodeNum();
const uint32_t peer = (message.sender == localNode) ? message.dest : message.sender;
if (peer == 0 || peer == NODENUM_BROADCAST) {
return;
}
if (freetext) {
cannedMessageModule->LaunchFreetextWithDestination(peer);
} else {
cannedMessageModule->LaunchWithDestination(peer);
}
}
} // namespace
menuHandler::screenMenus menuHandler::menuQueue = MenuNone;
@@ -594,9 +658,12 @@ void menuHandler::messageResponseMenu()
#ifdef HAS_I2S
} else if (selected == Aloud) {
const meshtastic_MeshPacket &mp = devicestate.rx_text_message;
const char *msg = reinterpret_cast<const char *>(mp.decoded.payload.bytes);
audioThread->readAloud(msg);
if (const StoredMessage *latest = getNewestMessageForActiveThread()) {
const char *msg = MessageStore::getText(*latest);
if (msg && msg[0]) {
audioThread->readAloud(msg);
}
}
#endif
}
};
@@ -656,20 +723,12 @@ void menuHandler::replyMenu()
// Preset reply
if (selected == ReplyPreset) {
if (mode == graphics::MessageRenderer::ThreadMode::CHANNEL) {
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST, ch);
} else if (mode == graphics::MessageRenderer::ThreadMode::DIRECT) {
cannedMessageModule->LaunchWithDestination(peer);
} else {
// Fallback for last received message
if (devicestate.rx_text_message.to == NODENUM_BROADCAST) {
cannedMessageModule->LaunchWithDestination(NODENUM_BROADCAST, devicestate.rx_text_message.channel);
} else {
cannedMessageModule->LaunchWithDestination(devicestate.rx_text_message.from);
}
} else if (const StoredMessage *latest = getNewestMessageForActiveThread()) {
launchReplyForMessage(*latest, false);
}
return;
@@ -677,20 +736,12 @@ void menuHandler::replyMenu()
// Freetext reply
if (selected == ReplyFreetext) {
if (mode == graphics::MessageRenderer::ThreadMode::CHANNEL) {
cannedMessageModule->LaunchFreetextWithDestination(NODENUM_BROADCAST, ch);
} else if (mode == graphics::MessageRenderer::ThreadMode::DIRECT) {
cannedMessageModule->LaunchFreetextWithDestination(peer);
} else {
// Fallback for last received message
if (devicestate.rx_text_message.to == NODENUM_BROADCAST) {
cannedMessageModule->LaunchFreetextWithDestination(NODENUM_BROADCAST, devicestate.rx_text_message.channel);
} else {
cannedMessageModule->LaunchFreetextWithDestination(devicestate.rx_text_message.from);
}
} else if (const StoredMessage *latest = getNewestMessageForActiveThread()) {
launchReplyForMessage(*latest, true);
}
return;
@@ -5,9 +5,8 @@
Shows the latest incoming text message, as well as sender.
Both broadcast and direct messages will be shown here, from all channels.
This module doesn't doesn't use the devicestate.rx_text_message,' as this is overwritten to contain outgoing messages
This module doesn't collect its own text message. Instead, the WindowManager stores the most recent incoming text message.
This is available to any interested modules (SingeMessageApplet, NotificationApplet etc.) via InkHUD::latestMessage
This is available to any interested modules (SingleMessageApplet, NotificationApplet etc.) via InkHUD::latestMessage
We do still receive notifications from the text message module though,
to know when a new message has arrived, and trigger the update.
@@ -46,4 +45,4 @@ class AllMessageApplet : public Applet
} // namespace NicheGraphics::InkHUD
#endif
#endif
@@ -3,11 +3,10 @@
/*
Shows the latest incoming *Direct Message* (DM), as well as sender.
This compliments the threaded message applets
This complements the threaded message applets
This module doesn't doesn't use the devicestate.rx_text_message,' as this is overwritten to contain outgoing messages
This module doesn't collect its own text message. Instead, the WindowManager stores the most recent incoming text message.
This is available to any interested modules (SingeMessageApplet, NotificationApplet etc.) via InkHUD::latestMessage
This is available to any interested modules (SingleMessageApplet, NotificationApplet etc.) via InkHUD::latestMessage
We do still receive notifications from the text message module though,
to know when a new message has arrived, and trigger the update.
@@ -46,4 +45,4 @@ class DMApplet : public Applet
} // namespace NicheGraphics::InkHUD
#endif
#endif
+1 -1
View File
@@ -525,7 +525,7 @@ int InkHUD::Events::beforeReboot(void *unused)
// Callback when a new text message is received
// Caches the most recently received message, for use by applets
// Rx does not trigger a save to flash, however the data *will* be saved alongside other during shutdown, etc.
// Note: this is different from devicestate.rx_text_message, which may contain an *outgoing* message
// Note: this is intentionally separate from device-state message fields.
int InkHUD::Events::onReceiveTextMessage(const meshtastic_MeshPacket *packet)
{
// Short circuit: don't store outgoing messages
+1 -2
View File
@@ -121,8 +121,7 @@ class Persistence
// Most recently received text message
// Value is updated by InkHUD::WindowManager, as a courtesy to applets
// Note: different from devicestate.rx_text_message,
// which may contain an *outgoing message* to broadcast
// InkHUD keeps its own latest-message cache for applets.
struct LatestMessage {
MessageStore::Message broadcast; // Most recent message received broadcast
MessageStore::Message dm; // Most recent received DM
+1 -1
View File
@@ -464,7 +464,7 @@ Most recently received text message
Collected here, so various user applets don't all have to store their own copy of this info.
We are unable to use `devicestate.rx_text_message` for this purpose, because:
We keep this separate latest-message cache for this purpose, because:
- it is cleared by an outgoing text message
- we want to store both a recent broadcast and a recent DM
+6
View File
@@ -333,6 +333,12 @@ void InputBroker::Init()
BaseType_t higherWake = 0;
concurrency::mainDelay.interruptFromISR(&higherWake);
};
#if defined(ELECROW_ThinkNode_M7)
userConfigNoScreen.longLongPressTime = 15 * 1000;
userConfigNoScreen.longLongPress = INPUT_BROKER_FACTORY_RST;
#else
userConfigNoScreen.longLongPress = INPUT_BROKER_SHUTDOWN;
#endif
userConfigNoScreen.singlePress = INPUT_BROKER_USER_PRESS;
userConfigNoScreen.longPress = INPUT_BROKER_NONE;
userConfigNoScreen.longPressTime = 500;
+1
View File
@@ -25,6 +25,7 @@ enum input_broker_event {
INPUT_BROKER_USER_PRESS,
INPUT_BROKER_ALT_PRESS,
INPUT_BROKER_ALT_LONG,
INPUT_BROKER_FACTORY_RST = 0x9a,
INPUT_BROKER_SHUTDOWN = 0x9b,
INPUT_BROKER_GPS_TOGGLE = 0x9e,
INPUT_BROKER_SEND_PING = 0xaf,
+4 -4
View File
@@ -59,12 +59,12 @@ NimbleBluetooth *nimbleBluetooth = nullptr;
NRF52Bluetooth *nrf52Bluetooth = nullptr;
#endif
#if HAS_WIFI || defined(USE_WS5500)
#if HAS_WIFI || defined(USE_WS5500) || defined(USE_CH390D)
#include "mesh/api/WiFiServerAPI.h"
#include "mesh/wifi/WiFiAPClient.h"
#endif
#if HAS_ETHERNET && !defined(USE_WS5500)
#if HAS_ETHERNET && !defined(USE_WS5500) && !defined(USE_CH390D)
#include "mesh/api/ethServerAPI.h"
#include "mesh/eth/ethClient.h"
#endif
@@ -245,7 +245,7 @@ const char *getDeviceName()
uint32_t timeLastPowered = 0;
static OSThread *powerFSMthread;
OSThread *ambientLightingThread;
AmbientLightingThread *ambientLightingThread;
RadioLibHal *RadioLibHAL = NULL;
@@ -335,7 +335,7 @@ void setup()
#ifdef WIFI_LED
pinMode(WIFI_LED, OUTPUT);
digitalWrite(WIFI_LED, LOW);
digitalWrite(WIFI_LED, HIGH ^ WIFI_STATE_ON);
#endif
#ifdef BLE_LED
+1 -1
View File
@@ -32,7 +32,7 @@ template class LR20x0Interface<LR2021>;
template class SX126xInterface<STM32WLx>;
#endif
#if HAS_ETHERNET && !defined(USE_WS5500)
#if HAS_ETHERNET && !defined(USE_WS5500) && !defined(USE_CH390D)
#include "api/ethServerAPI.h"
template class ServerAPI<EthernetClient>;
template class APIServerPort<ethServerAPI, EthernetServer>;
+158 -57
View File
@@ -25,6 +25,7 @@
#include "mesh/generated/meshtastic/deviceonly_legacy.pb.h"
#include "meshUtils.h"
#include "modules/NeighborInfoModule.h"
#include "xmodem.h"
#include <ErriezCRC32.h>
#include <algorithm>
#include <pb_decode.h>
@@ -81,6 +82,14 @@ static unsigned char userprefs_admin_key_1[] = USERPREFS_USE_ADMIN_KEY_1;
static unsigned char userprefs_admin_key_2[] = USERPREFS_USE_ADMIN_KEY_2;
#endif
// Weak empty variant initialization function.
// May be redefined by variant files.
void variantDefaultConfig() __attribute__((weak));
void variantDefaultConfig() {}
void variantDefaultModuleConfig() __attribute__((weak));
void variantDefaultModuleConfig() {}
#ifdef HELTEC_MESH_NODE_T114
uint32_t read8(uint8_t bits, uint8_t dummy, uint8_t cs, uint8_t sck, uint8_t mosi, uint8_t dc, uint8_t rst)
@@ -152,6 +161,25 @@ uint32_t get_st7789_id(uint8_t cs, uint8_t sck, uint8_t mosi, uint8_t dc, uint8_
#endif
// When armed by loadFromDisk, the decode callback writes satellite entries
// straight into these maps instead of the temp vectors. Nullptr = legacy
// push_back-to-vector path for backup/restore and other decoders.
namespace
{
#if !MESHTASTIC_EXCLUDE_POSITIONDB
std::map<NodeNum, meshtastic_PositionLite> *s_decodePositionsTarget = nullptr;
#endif
#if !MESHTASTIC_EXCLUDE_TELEMETRYDB
std::map<NodeNum, meshtastic_DeviceMetrics> *s_decodeTelemetryTarget = nullptr;
#endif
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTDB
std::map<NodeNum, meshtastic_EnvironmentMetrics> *s_decodeEnvironmentTarget = nullptr;
#endif
#if !MESHTASTIC_EXCLUDE_STATUSDB
std::map<NodeNum, meshtastic_StatusMessage> *s_decodeStatusTarget = nullptr;
#endif
} // namespace
bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field)
{
const auto *iter = reinterpret_cast<const pb_field_iter_t *>(field);
@@ -166,10 +194,10 @@ bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostre
return false;
}
}
if (istream) {
meshtastic_NodeInfoLite node;
if (istream && istream->bytes_left) {
meshtastic_NodeInfoLite node = meshtastic_NodeInfoLite_init_zero;
auto *vec = static_cast<std::vector<meshtastic_NodeInfoLite> *>(iter->pData);
if (istream->bytes_left && pb_decode(istream, meshtastic_NodeInfoLite_fields, &node))
if (pb_decode(istream, meshtastic_NodeInfoLite_fields, &node))
vec->push_back(node);
}
return true;
@@ -184,11 +212,19 @@ bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostre
return false;
}
}
if (istream) {
meshtastic_NodePositionEntry entry;
auto *vec = static_cast<std::vector<meshtastic_NodePositionEntry> *>(iter->pData);
if (istream->bytes_left && pb_decode(istream, meshtastic_NodePositionEntry_fields, &entry))
if (istream && istream->bytes_left) {
meshtastic_NodePositionEntry entry = meshtastic_NodePositionEntry_init_zero;
if (pb_decode(istream, meshtastic_NodePositionEntry_fields, &entry)) {
#if !MESHTASTIC_EXCLUDE_POSITIONDB
if (s_decodePositionsTarget) {
if (entry.has_position)
(*s_decodePositionsTarget)[entry.num] = entry.position;
return true;
}
#endif
auto *vec = static_cast<std::vector<meshtastic_NodePositionEntry> *>(iter->pData);
vec->push_back(entry);
}
}
return true;
}
@@ -202,11 +238,19 @@ bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostre
return false;
}
}
if (istream) {
meshtastic_NodeTelemetryEntry entry;
auto *vec = static_cast<std::vector<meshtastic_NodeTelemetryEntry> *>(iter->pData);
if (istream->bytes_left && pb_decode(istream, meshtastic_NodeTelemetryEntry_fields, &entry))
if (istream && istream->bytes_left) {
meshtastic_NodeTelemetryEntry entry = meshtastic_NodeTelemetryEntry_init_zero;
if (pb_decode(istream, meshtastic_NodeTelemetryEntry_fields, &entry)) {
#if !MESHTASTIC_EXCLUDE_TELEMETRYDB
if (s_decodeTelemetryTarget) {
if (entry.has_device_metrics)
(*s_decodeTelemetryTarget)[entry.num] = entry.device_metrics;
return true;
}
#endif
auto *vec = static_cast<std::vector<meshtastic_NodeTelemetryEntry> *>(iter->pData);
vec->push_back(entry);
}
}
return true;
}
@@ -220,11 +264,19 @@ bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostre
return false;
}
}
if (istream) {
meshtastic_NodeStatusEntry entry;
auto *vec = static_cast<std::vector<meshtastic_NodeStatusEntry> *>(iter->pData);
if (istream->bytes_left && pb_decode(istream, meshtastic_NodeStatusEntry_fields, &entry))
if (istream && istream->bytes_left) {
meshtastic_NodeStatusEntry entry = meshtastic_NodeStatusEntry_init_zero;
if (pb_decode(istream, meshtastic_NodeStatusEntry_fields, &entry)) {
#if !MESHTASTIC_EXCLUDE_STATUSDB
if (s_decodeStatusTarget) {
if (entry.has_status)
(*s_decodeStatusTarget)[entry.num] = entry.status;
return true;
}
#endif
auto *vec = static_cast<std::vector<meshtastic_NodeStatusEntry> *>(iter->pData);
vec->push_back(entry);
}
}
return true;
}
@@ -238,11 +290,19 @@ bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostre
return false;
}
}
if (istream) {
meshtastic_NodeEnvironmentEntry entry;
auto *vec = static_cast<std::vector<meshtastic_NodeEnvironmentEntry> *>(iter->pData);
if (istream->bytes_left && pb_decode(istream, meshtastic_NodeEnvironmentEntry_fields, &entry))
if (istream && istream->bytes_left) {
meshtastic_NodeEnvironmentEntry entry = meshtastic_NodeEnvironmentEntry_init_zero;
if (pb_decode(istream, meshtastic_NodeEnvironmentEntry_fields, &entry)) {
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTDB
if (s_decodeEnvironmentTarget) {
if (entry.has_environment_metrics)
(*s_decodeEnvironmentTarget)[entry.num] = entry.environment_metrics;
return true;
}
#endif
auto *vec = static_cast<std::vector<meshtastic_NodeEnvironmentEntry> *>(iter->pData);
vec->push_back(entry);
}
}
return true;
}
@@ -251,6 +311,42 @@ bool meshtastic_NodeDatabase_callback(pb_istream_t *istream, pb_ostream_t *ostre
}
}
void NodeDB::armNodeDatabaseDecodeTargets()
{
#if !MESHTASTIC_EXCLUDE_POSITIONDB
nodePositions.clear();
s_decodePositionsTarget = &nodePositions;
#endif
#if !MESHTASTIC_EXCLUDE_TELEMETRYDB
nodeTelemetry.clear();
s_decodeTelemetryTarget = &nodeTelemetry;
#endif
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTDB
nodeEnvironment.clear();
s_decodeEnvironmentTarget = &nodeEnvironment;
#endif
#if !MESHTASTIC_EXCLUDE_STATUSDB
nodeStatus.clear();
s_decodeStatusTarget = &nodeStatus;
#endif
}
void NodeDB::disarmNodeDatabaseDecodeTargets()
{
#if !MESHTASTIC_EXCLUDE_POSITIONDB
s_decodePositionsTarget = nullptr;
#endif
#if !MESHTASTIC_EXCLUDE_TELEMETRYDB
s_decodeTelemetryTarget = nullptr;
#endif
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTDB
s_decodeEnvironmentTarget = nullptr;
#endif
#if !MESHTASTIC_EXCLUDE_STATUSDB
s_decodeStatusTarget = nullptr;
#endif
}
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
* might have changed is incremented. Allows others to detect they might now be on a new channel.
*/
@@ -904,6 +1000,8 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
#endif
initConfigIntervals();
variantDefaultConfig();
variantDefaultModuleConfig();
}
void NodeDB::initConfigIntervals()
@@ -1161,7 +1259,6 @@ void NodeDB::resetNodes(bool keepFavorites)
std::fill(nodeDatabase.nodes.begin() + 1, nodeDatabase.nodes.end(), meshtastic_NodeInfoLite());
}
(void)ourNum;
devicestate.has_rx_text_message = false;
devicestate.has_rx_waypoint = false;
saveNodeDatabaseToDisk();
saveDeviceStateToDisk();
@@ -1368,7 +1465,6 @@ void NodeDB::installDefaultDeviceState()
devicestate.version = DEVICESTATE_CUR_VER;
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
devicestate.has_rx_waypoint = false;
devicestate.has_rx_text_message = false;
generatePacketId(); // FIXME - ugly way to init current_packet_id;
@@ -1510,6 +1606,19 @@ void NodeDB::loadFromDisk()
}
#endif
// Arm the direct-into-map decode so satellite entries skip the temp vectors.
{
concurrency::LockGuard guard(&satelliteMutex);
armNodeDatabaseDecodeTargets();
}
struct Disarm {
NodeDB &self;
~Disarm() { self.disarmNodeDatabaseDecodeTargets(); }
} disarm{*this};
// Avoid push_back's power-of-2 capacity growth wasting RAM at small N.
nodeDatabase.nodes.reserve(MAX_NUM_NODES);
auto state = loadProto(nodeDatabaseFileName, getMaxNodesAllocatedSize(), sizeof(meshtastic_NodeDatabase),
&meshtastic_NodeDatabase_msg, &nodeDatabase);
if (nodeDatabase.version < DEVICESTATE_MIN_VER) {
@@ -1523,50 +1632,33 @@ void NodeDB::loadFromDisk()
} else {
meshNodes = &nodeDatabase.nodes;
numMeshNodes = nodeDatabase.nodes.size();
// Hydrate the satellite maps; the on-disk vectors stay empty in steady
// state and are repopulated only at save time.
concurrency::LockGuard guard(&satelliteMutex);
// Counts computed outside LOG_INFO() so cppcheck doesn't choke on #if in macro args.
const unsigned posCount =
#if !MESHTASTIC_EXCLUDE_POSITIONDB
nodePositions.clear();
nodePositions.reserve(nodeDatabase.positions.size());
for (const auto &entry : nodeDatabase.positions) {
if (entry.has_position)
nodePositions[entry.num] = entry.position;
}
nodeDatabase.positions.clear();
nodeDatabase.positions.shrink_to_fit();
(unsigned)nodePositions.size();
#else
0u;
#endif
const unsigned telCount =
#if !MESHTASTIC_EXCLUDE_TELEMETRYDB
nodeTelemetry.clear();
nodeTelemetry.reserve(nodeDatabase.telemetry.size());
for (const auto &entry : nodeDatabase.telemetry) {
if (entry.has_device_metrics)
nodeTelemetry[entry.num] = entry.device_metrics;
}
nodeDatabase.telemetry.clear();
nodeDatabase.telemetry.shrink_to_fit();
(unsigned)nodeTelemetry.size();
#else
0u;
#endif
const unsigned envCount =
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTDB
nodeEnvironment.clear();
nodeEnvironment.reserve(nodeDatabase.environment.size());
for (const auto &entry : nodeDatabase.environment) {
if (entry.has_environment_metrics)
nodeEnvironment[entry.num] = entry.environment_metrics;
}
nodeDatabase.environment.clear();
nodeDatabase.environment.shrink_to_fit();
(unsigned)nodeEnvironment.size();
#else
0u;
#endif
const unsigned statusCount =
#if !MESHTASTIC_EXCLUDE_STATUSDB
nodeStatus.clear();
nodeStatus.reserve(nodeDatabase.status.size());
for (const auto &entry : nodeDatabase.status) {
if (entry.has_status)
nodeStatus[entry.num] = entry.status;
}
nodeDatabase.status.clear();
nodeDatabase.status.shrink_to_fit();
(unsigned)nodeStatus.size();
#else
0u;
#endif
LOG_INFO("Loaded saved nodedatabase version %d, with nodes count: %d", nodeDatabase.version, nodeDatabase.nodes.size());
LOG_INFO("Loaded saved nodedatabase v%d: %d nodes, %u pos, %u tel, %u env, %u status", nodeDatabase.version,
nodeDatabase.nodes.size(), posCount, telCount, envCount, statusCount);
}
if (numMeshNodes > MAX_NUM_NODES) {
@@ -1844,6 +1936,15 @@ bool NodeDB::saveNodeDatabaseToDisk()
return false;
}
// Defer (don't fail) while xmodem holds the prefs file handle. Returning false
// would propagate through saveToDisk() and trigger fsFormat() mid-transfer.
#ifdef FSCom
if (xModem.isBusy()) {
LOG_DEBUG("Deferring NodeDB save: xmodem transfer in progress");
return true;
}
#endif
#ifdef FSCom
spiLock->lock();
FSCom.mkdir("/prefs");
+12 -7
View File
@@ -4,9 +4,9 @@
#include <Arduino.h>
#include <algorithm>
#include <assert.h>
#include <map>
#include <pb_encode.h>
#include <string>
#include <unordered_map>
#include <vector>
#include "MeshTypes.h"
@@ -170,19 +170,19 @@ class NodeDB
Observable<const meshtastic::NodeStatus *> newStatus;
pb_size_t numMeshNodes;
// Satellite per-NodeNum maps for data we used to inline into NodeInfoLite,
// gated by MESHTASTIC_EXCLUDE_*DB so STM32WL can omit them.
// Satellite per-NodeNum maps. std::map avoids unordered_map's bucket-array
// preallocation; O(log N) lookup is fine at these sizes.
#if !MESHTASTIC_EXCLUDE_POSITIONDB
std::unordered_map<NodeNum, meshtastic_PositionLite> nodePositions;
std::map<NodeNum, meshtastic_PositionLite> nodePositions;
#endif
#if !MESHTASTIC_EXCLUDE_TELEMETRYDB
std::unordered_map<NodeNum, meshtastic_DeviceMetrics> nodeTelemetry;
std::map<NodeNum, meshtastic_DeviceMetrics> nodeTelemetry;
#endif
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTDB
std::unordered_map<NodeNum, meshtastic_EnvironmentMetrics> nodeEnvironment;
std::map<NodeNum, meshtastic_EnvironmentMetrics> nodeEnvironment;
#endif
#if !MESHTASTIC_EXCLUDE_STATUSDB
std::unordered_map<NodeNum, meshtastic_StatusMessage> nodeStatus;
std::map<NodeNum, meshtastic_StatusMessage> nodeStatus;
#endif
bool keyIsLowEntropy = false;
@@ -429,6 +429,11 @@ class NodeDB
// the legacy descriptor and copies entries into the v25 layout. Caller
// is responsible for save / install-default on the result.
bool migrateLegacyNodeDatabase();
// Route satellite-store decode entries straight into our maps instead of
// temp vectors. Must be paired — disarm before any other NodeDatabase decode.
void armNodeDatabaseDecodeTargets();
void disarmNodeDatabaseDecodeTargets();
};
extern NodeDB *nodeDB;
+2 -2
View File
@@ -9,8 +9,8 @@
#include "Throttle.h"
#define PACKETHISTORY_MAX \
max((u_int32_t)(MAX_NUM_NODES * 2.0), \
(u_int32_t)100) // x2..3 Should suffice. Empirical setup. 16B per record malloc'ed, but no less than 100
max((uint32_t)(MAX_NUM_NODES * 2.0), \
(uint32_t)100) // x2..3 Should suffice. Empirical setup. 16B per record malloc'ed, but no less than 100
#define RECENT_WARN_AGE (10 * 60 * 1000L) // Warn if the packet that gets removed was more recent than 10 min
+158 -189
View File
@@ -62,7 +62,7 @@ void PhoneAPI::handleStartConfig()
onConfigStart();
// even if we were already connected - restart our state machine
if (config_nonce == SPECIAL_NONCE_ONLY_NODES || config_nonce == SPECIAL_NONCE_GRADIENT_ONLY_NODES) {
if (config_nonce == SPECIAL_NONCE_ONLY_NODES) {
// If client only wants node info, jump directly to sending nodes
state = STATE_SEND_OWN_NODEINFO;
LOG_INFO("Client only wants node info, skipping other config");
@@ -138,6 +138,7 @@ void PhoneAPI::close()
replayTelemetryIndex = 0;
replayEnvironmentIndex = 0;
replayStatusIndex = 0;
replayPhase = REPLAY_PHASE_IDLE;
}
packetForPhone = NULL;
filesManifest.clear();
@@ -320,7 +321,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
nodeInfoForPhone.num = 0;
}
}
if (config_nonce == SPECIAL_NONCE_ONLY_NODES || config_nonce == SPECIAL_NONCE_GRADIENT_ONLY_NODES) {
if (config_nonce == SPECIAL_NONCE_ONLY_NODES) {
// If client only wants node info, jump directly to sending nodes
state = STATE_SEND_OTHER_NODEINFOS;
onNowHasData(0);
@@ -535,135 +536,16 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// Just in case we stored a different user.id in the past, but should never happen going forward
sprintf(infoToSend.user.id, "!%08x", infoToSend.num);
// Logging this really slows down sending nodes on initial connection because the serial console is so slow, so only
// uncomment if you really need to:
// LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s", nodeInfoForPhone.num, nodeInfoForPhone.last_heard,
// nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name);
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag;
fromRadioScratch.node_info = infoToSend;
prefetchNodeInfos();
} else {
LOG_DEBUG("Done sending %d of %d nodeinfos millis=%u", readIndex, nodeDB->getNumMeshNodes(), millis());
concurrency::LockGuard guard(&nodeInfoMutex);
nodeInfoMutex.lock();
nodeInfoQueue.clear();
// Replay states no-op for legacy clients / excluded DBs.
state = STATE_REPLAY_POSITIONS;
return getFromRadio(buf);
}
break;
}
case STATE_REPLAY_POSITIONS: {
if (replayPositionOrder.empty() && replayPositionIndex == 0)
beginReplayPositions();
prefetchReplayPositions();
meshtastic_MeshPacket pkt = {};
bool havePkt = false;
{
concurrency::LockGuard guard(&nodeInfoMutex);
if (!replayQueue.empty()) {
pkt = replayQueue.front();
replayQueue.pop_front();
havePkt = true;
}
}
if (havePkt) {
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_packet_tag;
fromRadioScratch.packet = pkt;
} else {
LOG_DEBUG("Done replaying positions count=%u millis=%u", (unsigned)replayPositionIndex, millis());
state = STATE_REPLAY_TELEMETRY;
return getFromRadio(buf);
}
break;
}
case STATE_REPLAY_TELEMETRY: {
if (replayTelemetryOrder.empty() && replayTelemetryIndex == 0)
beginReplayTelemetry();
prefetchReplayTelemetry();
meshtastic_MeshPacket pkt = {};
bool havePkt = false;
{
concurrency::LockGuard guard(&nodeInfoMutex);
if (!replayQueue.empty()) {
pkt = replayQueue.front();
replayQueue.pop_front();
havePkt = true;
}
}
if (havePkt) {
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_packet_tag;
fromRadioScratch.packet = pkt;
} else {
LOG_DEBUG("Done replaying telemetry count=%u millis=%u", (unsigned)replayTelemetryIndex, millis());
state = STATE_REPLAY_ENVIRONMENT;
return getFromRadio(buf);
}
break;
}
case STATE_REPLAY_ENVIRONMENT: {
if (replayEnvironmentOrder.empty() && replayEnvironmentIndex == 0)
beginReplayEnvironment();
prefetchReplayEnvironment();
meshtastic_MeshPacket pkt = {};
bool havePkt = false;
{
concurrency::LockGuard guard(&nodeInfoMutex);
if (!replayQueue.empty()) {
pkt = replayQueue.front();
replayQueue.pop_front();
havePkt = true;
}
}
if (havePkt) {
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_packet_tag;
fromRadioScratch.packet = pkt;
} else {
LOG_DEBUG("Done replaying environment count=%u millis=%u", (unsigned)replayEnvironmentIndex, millis());
state = STATE_REPLAY_STATUS;
return getFromRadio(buf);
}
break;
}
case STATE_REPLAY_STATUS: {
if (replayStatusOrder.empty() && replayStatusIndex == 0)
beginReplayStatus();
prefetchReplayStatus();
meshtastic_MeshPacket pkt = {};
bool havePkt = false;
{
concurrency::LockGuard guard(&nodeInfoMutex);
if (!replayQueue.empty()) {
pkt = replayQueue.front();
replayQueue.pop_front();
havePkt = true;
}
}
if (havePkt) {
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_packet_tag;
fromRadioScratch.packet = pkt;
} else {
LOG_DEBUG("Done replaying status count=%u millis=%u", (unsigned)replayStatusIndex, millis());
replayPositionOrder.clear();
replayPositionOrder.shrink_to_fit();
replayTelemetryOrder.clear();
replayTelemetryOrder.shrink_to_fit();
replayEnvironmentOrder.clear();
replayEnvironmentOrder.shrink_to_fit();
replayStatusOrder.clear();
replayStatusOrder.shrink_to_fit();
nodeInfoMutex.unlock();
// Satellite-DB replay (positions/telemetry/environment/status) now happens
// *after* config_complete_id, interleaved with live traffic in STATE_SEND_PACKETS.
state = STATE_SEND_FILEMANIFEST;
return getFromRadio(buf);
}
@@ -673,8 +555,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
case STATE_SEND_FILEMANIFEST: {
LOG_DEBUG("FromRadio=STATE_SEND_FILEMANIFEST");
// ONLY_NODES variants skip the manifest.
if (config_state == filesManifest.size() || config_nonce == SPECIAL_NONCE_ONLY_NODES ||
config_nonce == SPECIAL_NONCE_GRADIENT_ONLY_NODES) {
if (config_state == filesManifest.size() || config_nonce == SPECIAL_NONCE_ONLY_NODES) {
config_state = 0;
filesManifest.clear();
// Skip to complete packet
@@ -719,6 +600,16 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_packet_tag;
fromRadioScratch.packet = *packetForPhone;
releasePhonePacket();
} else if (replayPending()) {
// No live packet pending — feed the phone one cached satellite-DB packet.
// popReplayPacket advances through positions->telemetry->environment->status,
// and flips replayPhase back to IDLE when everything has been drained.
meshtastic_MeshPacket replayPkt;
if (popReplayPacket(replayPkt)) {
printPacket("replay packet to phone", &replayPkt);
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_packet_tag;
fromRadioScratch.packet = replayPkt;
}
}
break;
@@ -743,10 +634,19 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
void PhoneAPI::sendConfigComplete()
{
LOG_INFO("Config Send Complete millis=%u", millis());
const bool shouldReplaySatellites = (config_nonce != SPECIAL_NONCE_ONLY_CONFIG);
// The phone sees config_complete_id first (treats sync as done), then the cached
// satellite-DB packets (positions / telemetry / environment / status) trickle in
// afterward as ordinary mesh packets (except SPECIAL_NONCE_ONLY_CONFIG, which
// skips node/satellite sync entirely). Any client that handles live POSITION_APP /
// TELEMETRY_APP / NODE_STATUS_APP packets handles these identically. STM32WL and
// other builds that compile the satellite DBs out produce no replay packets and
// the phase advances to IDLE in microseconds.
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
fromRadioScratch.config_complete_id = config_nonce;
config_nonce = 0;
state = STATE_SEND_PACKETS;
replayPhase = shouldReplaySatellites ? REPLAY_PHASE_POSITIONS : REPLAY_PHASE_IDLE;
if (api_type == TYPE_BLE) {
service->api_state = service->STATE_BLE;
} else if (api_type == TYPE_WIFI) {
@@ -787,7 +687,8 @@ void PhoneAPI::prefetchNodeInfos()
{
bool added = false;
bool wasEmpty = false;
const bool gradient = clientWantsGradientSync();
// Other-node NodeInfos always go out thin (no bundled position/device_metrics).
// The post-config_complete_id replay drain delivers those as ordinary mesh packets.
// Keep the queue topped up so BLE reads stay responsive even if DB fetches take a moment.
{
concurrency::LockGuard guard(&nodeInfoMutex);
@@ -797,8 +698,7 @@ void PhoneAPI::prefetchNodeInfos()
if (!nextNode)
break;
auto info =
gradient ? TypeConversions::ConvertToNodeInfoThin(nextNode) : TypeConversions::ConvertToNodeInfo(nextNode);
auto info = TypeConversions::ConvertToNodeInfoThin(nextNode);
bool isUs = info.num == nodeDB->getNodeNum();
info.hops_away = isUs ? 0 : info.hops_away;
info.last_heard = isUs ? getValidTime(RTCQualityFromNet) : info.last_heard;
@@ -820,11 +720,20 @@ void PhoneAPI::prefetchNodeInfos()
meshtastic_MeshPacket PhoneAPI::makeReplayPositionPacket(NodeNum num, const meshtastic_PositionLite &pos)
{
// Shape this exactly like a fresh live broadcast Position from the peer so the
// phone runs it through its normal "live position broadcast" handler path.
// to=ourNum would read as a DM-from-peer and never lands in node detail UI.
meshtastic_MeshPacket pkt = meshtastic_MeshPacket_init_default;
pkt.from = num;
pkt.to = nodeDB->getNodeNum();
pkt.to = NODENUM_BROADCAST;
pkt.id = generatePacketId();
pkt.rx_time = pos.time;
pkt.channel = 0;
pkt.hop_limit = Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit);
pkt.hop_start = pkt.hop_limit;
pkt.priority = meshtastic_MeshPacket_Priority_BACKGROUND;
// Mark as if heard over the air, not internally generated
pkt.transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA;
pkt.which_payload_variant = meshtastic_MeshPacket_decoded_tag;
pkt.decoded.portnum = meshtastic_PortNum_POSITION_APP;
meshtastic_Position fullPos = TypeConversions::ConvertToPosition(pos);
@@ -838,11 +747,18 @@ meshtastic_MeshPacket PhoneAPI::makeReplayTelemetryPacket(NodeNum num, const mes
{
meshtastic_MeshPacket pkt = meshtastic_MeshPacket_init_default;
pkt.from = num;
pkt.to = nodeDB->getNodeNum();
pkt.to = NODENUM_BROADCAST;
pkt.id = generatePacketId();
// No native timestamp on telemetry packets here; use last_heard.
const meshtastic_NodeInfoLite *header = nodeDB->getMeshNode(num);
pkt.rx_time = header ? header->last_heard : 0;
pkt.channel = 0;
pkt.hop_limit = Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit);
pkt.hop_start = pkt.hop_limit;
pkt.priority = meshtastic_MeshPacket_Priority_BACKGROUND;
// Mark as if heard over the air, not internally generated — iOS client filters
// TRANSPORT_INTERNAL packets out of broadcast peer state updates.
pkt.transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA;
pkt.which_payload_variant = meshtastic_MeshPacket_decoded_tag;
pkt.decoded.portnum = meshtastic_PortNum_TELEMETRY_APP;
meshtastic_Telemetry fullTel = meshtastic_Telemetry_init_default;
@@ -858,16 +774,12 @@ meshtastic_MeshPacket PhoneAPI::makeReplayTelemetryPacket(NodeNum num, const mes
void PhoneAPI::beginReplayPositions()
{
#if MESHTASTIC_EXCLUDE_POSITIONDB
// Build excluded entirely - leave the order list empty so the state arm
// Build excluded entirely - leave the order list empty so the phase
// immediately drains and advances.
replayPositionOrder.clear();
replayPositionIndex = 0;
#else
if (!clientWantsGradientSync()) {
replayPositionOrder.clear();
replayPositionIndex = 0;
return;
}
// Caller (popReplayPacket) only invokes us when replayPhase is armed.
// Snapshot the keyset at phase start so concurrent inserts/erases on the
// map don't invalidate iteration. Skip our own node - the phone already
// got our position bundled in STATE_SEND_OWN_NODEINFO.
@@ -882,8 +794,6 @@ void PhoneAPI::prefetchReplayPositions()
#if MESHTASTIC_EXCLUDE_POSITIONDB
return;
#else
if (!clientWantsGradientSync())
return;
bool added = false;
bool wasEmpty = false;
{
@@ -909,11 +819,6 @@ void PhoneAPI::beginReplayTelemetry()
replayTelemetryOrder.clear();
replayTelemetryIndex = 0;
#else
if (!clientWantsGradientSync()) {
replayTelemetryOrder.clear();
replayTelemetryIndex = 0;
return;
}
replayTelemetryOrder = nodeDB->snapshotTelemetryNodeNums(nodeDB->getNodeNum());
replayTelemetryIndex = 0;
LOG_INFO("Begin telemetry replay: %u entries millis=%u", (unsigned)replayTelemetryOrder.size(), millis());
@@ -925,8 +830,6 @@ void PhoneAPI::prefetchReplayTelemetry()
#if MESHTASTIC_EXCLUDE_TELEMETRYDB
return;
#else
if (!clientWantsGradientSync())
return;
bool added = false;
bool wasEmpty = false;
{
@@ -950,10 +853,17 @@ meshtastic_MeshPacket PhoneAPI::makeReplayEnvironmentPacket(uint32_t num, const
{
meshtastic_MeshPacket pkt = meshtastic_MeshPacket_init_default;
pkt.from = num;
pkt.to = nodeDB->getNodeNum();
pkt.to = NODENUM_BROADCAST;
pkt.id = generatePacketId();
const meshtastic_NodeInfoLite *header = nodeDB->getMeshNode(num);
pkt.rx_time = header ? header->last_heard : 0;
pkt.channel = 0;
pkt.hop_limit = Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit);
pkt.hop_start = pkt.hop_limit;
pkt.priority = meshtastic_MeshPacket_Priority_BACKGROUND;
// Mark as if heard over the air, not internally generated — iOS client filters
// TRANSPORT_INTERNAL packets out of broadcast peer state updates.
pkt.transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA;
pkt.which_payload_variant = meshtastic_MeshPacket_decoded_tag;
pkt.decoded.portnum = meshtastic_PortNum_TELEMETRY_APP;
meshtastic_Telemetry fullTel = meshtastic_Telemetry_init_default;
@@ -972,11 +882,6 @@ void PhoneAPI::beginReplayEnvironment()
replayEnvironmentOrder.clear();
replayEnvironmentIndex = 0;
#else
if (!clientWantsGradientSync()) {
replayEnvironmentOrder.clear();
replayEnvironmentIndex = 0;
return;
}
replayEnvironmentOrder = nodeDB->snapshotEnvironmentNodeNums(nodeDB->getNodeNum());
replayEnvironmentIndex = 0;
LOG_INFO("Begin environment replay: %u entries millis=%u", (unsigned)replayEnvironmentOrder.size(), millis());
@@ -988,8 +893,6 @@ void PhoneAPI::prefetchReplayEnvironment()
#if MESHTASTIC_EXCLUDE_ENVIRONMENTDB
return;
#else
if (!clientWantsGradientSync())
return;
bool added = false;
bool wasEmpty = false;
{
@@ -1013,11 +916,17 @@ meshtastic_MeshPacket PhoneAPI::makeReplayStatusPacket(uint32_t num, const mesht
{
meshtastic_MeshPacket pkt = meshtastic_MeshPacket_init_default;
pkt.from = num;
pkt.to = nodeDB->getNodeNum();
pkt.to = NODENUM_BROADCAST;
pkt.id = generatePacketId();
// StatusMessage has no native timestamp; use last_heard.
const meshtastic_NodeInfoLite *header = nodeDB->getMeshNode(num);
pkt.rx_time = header ? header->last_heard : 0;
pkt.channel = 0;
pkt.hop_limit = Default::getConfiguredOrDefaultHopLimit(config.lora.hop_limit);
pkt.hop_start = pkt.hop_limit;
pkt.priority = meshtastic_MeshPacket_Priority_BACKGROUND;
// Mark as if heard over the air, not internally generated — client filters
pkt.transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_LORA;
pkt.which_payload_variant = meshtastic_MeshPacket_decoded_tag;
pkt.decoded.portnum = meshtastic_PortNum_NODE_STATUS_APP;
size_t len =
@@ -1032,11 +941,6 @@ void PhoneAPI::beginReplayStatus()
replayStatusOrder.clear();
replayStatusIndex = 0;
#else
if (!clientWantsGradientSync()) {
replayStatusOrder.clear();
replayStatusIndex = 0;
return;
}
replayStatusOrder = nodeDB->snapshotStatusNodeNums(nodeDB->getNodeNum());
replayStatusIndex = 0;
LOG_INFO("Begin status replay: %u entries millis=%u", (unsigned)replayStatusOrder.size(), millis());
@@ -1048,8 +952,6 @@ void PhoneAPI::prefetchReplayStatus()
#if MESHTASTIC_EXCLUDE_STATUSDB
return;
#else
if (!clientWantsGradientSync())
return;
bool added = false;
bool wasEmpty = false;
{
@@ -1069,6 +971,94 @@ void PhoneAPI::prefetchReplayStatus()
#endif
}
// Pop one cached satellite-DB packet from the active replay phase.
// Phases drain in order: positions -> telemetry -> environment -> status.
// When the current phase's cursor is exhausted (queue empty AND no more entries
// to snapshot), advance to the next phase. When all four phases are done,
// flip replayPhase back to IDLE and release the snapshot vectors.
//
// Returns true if a packet was placed in `out`; false if everything is drained.
bool PhoneAPI::popReplayPacket(meshtastic_MeshPacket &out)
{
while (replayPhase != REPLAY_PHASE_IDLE) {
// Prime the active phase: seed the snapshot vector on first entry,
// top up replayQueue from the snapshot up to kReplayPrefetchDepth.
switch (replayPhase) {
case REPLAY_PHASE_POSITIONS:
if (replayPositionOrder.empty() && replayPositionIndex == 0)
beginReplayPositions();
prefetchReplayPositions();
break;
case REPLAY_PHASE_TELEMETRY:
if (replayTelemetryOrder.empty() && replayTelemetryIndex == 0)
beginReplayTelemetry();
prefetchReplayTelemetry();
break;
case REPLAY_PHASE_ENVIRONMENT:
if (replayEnvironmentOrder.empty() && replayEnvironmentIndex == 0)
beginReplayEnvironment();
prefetchReplayEnvironment();
break;
case REPLAY_PHASE_STATUS:
if (replayStatusOrder.empty() && replayStatusIndex == 0)
beginReplayStatus();
prefetchReplayStatus();
break;
default:
break;
}
{
concurrency::LockGuard guard(&nodeInfoMutex);
if (!replayQueue.empty()) {
out = replayQueue.front();
replayQueue.pop_front();
return true;
}
}
// Queue empty AND no more entries to feed it — phase is exhausted.
advanceReplayPhase();
}
return false;
}
void PhoneAPI::advanceReplayPhase()
{
switch (replayPhase) {
case REPLAY_PHASE_POSITIONS:
LOG_DEBUG("Replay drain: positions done (count=%u) millis=%u", (unsigned)replayPositionIndex, millis());
replayPhase = REPLAY_PHASE_TELEMETRY;
break;
case REPLAY_PHASE_TELEMETRY:
LOG_DEBUG("Replay drain: telemetry done (count=%u) millis=%u", (unsigned)replayTelemetryIndex, millis());
replayPhase = REPLAY_PHASE_ENVIRONMENT;
break;
case REPLAY_PHASE_ENVIRONMENT:
LOG_DEBUG("Replay drain: environment done (count=%u) millis=%u", (unsigned)replayEnvironmentIndex, millis());
replayPhase = REPLAY_PHASE_STATUS;
break;
case REPLAY_PHASE_STATUS:
LOG_INFO("Replay drain complete (status count=%u) millis=%u", (unsigned)replayStatusIndex, millis());
replayPositionOrder.clear();
replayPositionOrder.shrink_to_fit();
replayTelemetryOrder.clear();
replayTelemetryOrder.shrink_to_fit();
replayEnvironmentOrder.clear();
replayEnvironmentOrder.shrink_to_fit();
replayStatusOrder.clear();
replayStatusOrder.shrink_to_fit();
replayPositionIndex = 0;
replayTelemetryIndex = 0;
replayEnvironmentIndex = 0;
replayStatusIndex = 0;
replayPhase = REPLAY_PHASE_IDLE;
break;
default:
break;
}
}
void PhoneAPI::releaseMqttClientProxyPhonePacket()
{
if (mqttClientProxyMessageForPhone) {
@@ -1115,31 +1105,6 @@ bool PhoneAPI::available()
PREFETCH_NODEINFO:
prefetchNodeInfos();
return true;
case STATE_REPLAY_POSITIONS: {
// Prime the iterator if we haven't yet, then top up the queue.
if (replayPositionOrder.empty() && replayPositionIndex == 0)
beginReplayPositions();
prefetchReplayPositions();
return true; // Always advance state machine; arm itself transitions when drained
}
case STATE_REPLAY_TELEMETRY: {
if (replayTelemetryOrder.empty() && replayTelemetryIndex == 0)
beginReplayTelemetry();
prefetchReplayTelemetry();
return true;
}
case STATE_REPLAY_ENVIRONMENT: {
if (replayEnvironmentOrder.empty() && replayEnvironmentIndex == 0)
beginReplayEnvironment();
prefetchReplayEnvironment();
return true;
}
case STATE_REPLAY_STATUS: {
if (replayStatusOrder.empty() && replayStatusIndex == 0)
beginReplayStatus();
prefetchReplayStatus();
return true;
}
case STATE_SEND_PACKETS: {
if (!queueStatusPacketForPhone)
queueStatusPacketForPhone = service->getQueueStatusForPhone();
@@ -1171,7 +1136,11 @@ bool PhoneAPI::available()
if (!packetForPhone)
packetForPhone = service->getForPhone();
hasPacket = !!packetForPhone;
return hasPacket;
if (hasPacket)
return true;
// Trailing replay drain — feeds cached satellite-DB packets alongside
// (lower priority than) live traffic.
return replayPending();
}
default:
LOG_ERROR("PhoneAPI::available unexpected state %d", state);
+22 -15
View File
@@ -26,9 +26,6 @@
#define SPECIAL_NONCE_ONLY_CONFIG 69420
#define SPECIAL_NONCE_ONLY_NODES 69421 // ( ͡° ͜ʖ ͡°)
// Gradient sync: phone sends one of these to opt into thin-header + replay.
#define SPECIAL_NONCE_GRADIENT_SYNC 69422
#define SPECIAL_NONCE_GRADIENT_ONLY_NODES 69423
/**
* Provides our protobuf based API which phone/PC clients can use to talk to our device
@@ -52,15 +49,22 @@ class PhoneAPI
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
STATE_SEND_MODULECONFIG, // Send Module specific config
STATE_SEND_OTHER_NODEINFOS, // states progress in this order as the device sends to to the client
// Drain satellite DBs as synthetic POSITION_APP / TELEMETRY_APP /
// NODE_STATUS_APP packets when the phone opted into gradient sync.
STATE_REPLAY_POSITIONS,
STATE_REPLAY_TELEMETRY,
STATE_REPLAY_ENVIRONMENT,
STATE_REPLAY_STATUS,
STATE_SEND_FILEMANIFEST, // Send file manifest
STATE_SEND_FILEMANIFEST, // Send file manifest
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
STATE_SEND_PACKETS // live mesh packets + any cached satellite-DB replay that trails sync completion
};
// Satellite-DB replay (positions / telemetry / environment / status) used to live
// as four top-level states between STATE_SEND_OTHER_NODEINFOS and STATE_SEND_FILEMANIFEST.
// It now drains *after* config_complete_id has been emitted: the phone considers the
// initial sync done as soon as headers + manifest are delivered, and the cached
// position/telemetry/etc. trickle in alongside live mesh traffic inside STATE_SEND_PACKETS.
enum ReplayPhase : uint8_t {
REPLAY_PHASE_IDLE = 0, // not replaying (legacy clients, no-op DBs, or replay finished)
REPLAY_PHASE_POSITIONS,
REPLAY_PHASE_TELEMETRY,
REPLAY_PHASE_ENVIRONMENT,
REPLAY_PHASE_STATUS,
};
State state = STATE_SEND_NOTHING;
@@ -114,6 +118,7 @@ class PhoneAPI
size_t replayTelemetryIndex = 0;
size_t replayEnvironmentIndex = 0;
size_t replayStatusIndex = 0;
ReplayPhase replayPhase = REPLAY_PHASE_IDLE; // armed by sendConfigComplete() for full/default sync
meshtastic_ToRadio toRadioScratch = {
0}; // this is a static scratch object, any data must be copied elsewhere before returning
@@ -164,10 +169,6 @@ class PhoneAPI
bool isConnected() { return state != STATE_SEND_NOTHING; }
bool isSendingPackets() { return state == STATE_SEND_PACKETS; }
bool clientWantsGradientSync() const
{
return config_nonce == SPECIAL_NONCE_GRADIENT_SYNC || config_nonce == SPECIAL_NONCE_GRADIENT_ONLY_NODES;
}
protected:
/// Our fromradio packet while it is being assembled
@@ -229,6 +230,12 @@ class PhoneAPI
meshtastic_MeshPacket makeReplayEnvironmentPacket(uint32_t num, const meshtastic_EnvironmentMetrics &env);
meshtastic_MeshPacket makeReplayStatusPacket(uint32_t num, const meshtastic_StatusMessage &status);
// Post-sync replay drain: pop one cached packet from the active phase, advancing
// through positions -> telemetry -> environment -> status until everything is drained.
bool popReplayPacket(meshtastic_MeshPacket &out);
void advanceReplayPhase();
bool replayPending() const { return replayPhase != REPLAY_PHASE_IDLE; }
void releaseMqttClientProxyPhonePacket();
void releaseClientNotification();
+7
View File
@@ -37,6 +37,7 @@ meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfo
info.position.altitude = position->altitude;
info.position.location_source = position->location_source;
info.position.time = position->time;
info.position.precision_bits = position->precision_bits;
}
if (nodeInfoLiteHasUser(lite)) {
info.has_user = true;
@@ -71,6 +72,7 @@ meshtastic_PositionLite TypeConversions::ConvertToPositionLite(meshtastic_Positi
lite.altitude = position.altitude;
lite.location_source = position.location_source;
lite.time = position.time;
lite.precision_bits = position.precision_bits;
return lite;
}
@@ -89,6 +91,11 @@ meshtastic_Position TypeConversions::ConvertToPosition(meshtastic_PositionLite l
position.altitude = lite.altitude;
position.location_source = lite.location_source;
position.time = lite.time;
// Preserve the peer's broadcast precision; falls back to 0 for entries cached
// before the precision_bits field existed in PositionLite (pre-migration data).
// iOS treats 0 as "unspecified precision" and won't render the pin — so for
// unset values, declare full precision so the stored lat/lon renders as a point.
position.precision_bits = lite.precision_bits == 0 ? 32 : lite.precision_bits;
return position;
}
+1 -1
View File
@@ -1,7 +1,7 @@
#include "configuration.h"
#include <Arduino.h>
#if HAS_ETHERNET && !defined(USE_WS5500)
#if HAS_ETHERNET && !defined(USE_WS5500) && !defined(USE_CH390D)
#include "ethServerAPI.h"
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include "ServerAPI.h"
#ifndef USE_WS5500
#if !defined(USE_WS5500) && !defined(USE_CH390D)
#include <RAK13800_W5100S.h>
/**
+1 -1
View File
@@ -9,7 +9,7 @@
#include <RAK13800_W5100S.h>
#include <SPI.h>
#if HAS_NETWORKING
#if HAS_NETWORKING && !defined(USE_WS5500) && !defined(USE_CH390D)
#ifndef DISABLE_NTP
#include <NTPClient.h>
@@ -15,6 +15,9 @@ PB_BIND(meshtastic_AdminMessage_InputEvent, meshtastic_AdminMessage_InputEvent,
PB_BIND(meshtastic_AdminMessage_OTAEvent, meshtastic_AdminMessage_OTAEvent, AUTO)
PB_BIND(meshtastic_LockdownAuth, meshtastic_LockdownAuth, AUTO)
PB_BIND(meshtastic_HamParameters, meshtastic_HamParameters, AUTO)
+66 -1
View File
@@ -130,6 +130,41 @@ typedef struct _meshtastic_AdminMessage_OTAEvent {
meshtastic_AdminMessage_OTAEvent_ota_hash_t ota_hash;
} meshtastic_AdminMessage_OTAEvent;
typedef PB_BYTES_ARRAY_T(32) meshtastic_LockdownAuth_passphrase_t;
/* Lockdown passphrase delivery payload.
One message handles three operations distinguished by content:
- Provision (first-time): passphrase set, lock_now=false. Firmware
generates DEK, wraps with passphrase-derived KEK, persists.
- Unlock: passphrase set, lock_now=false. Firmware verifies
passphrase against stored DEK, unlocks storage, authorizes the
connection that delivered this packet.
- Lock now: lock_now=true, passphrase ignored. Firmware revokes
all client auth and reboots into the locked state.
Firmware decides between provision and unlock based on its own state
(whether a DEK file already exists). Clients do not need to track
which case applies. */
typedef struct _meshtastic_LockdownAuth {
/* Passphrase bytes (1-32). Empty when lock_now is true.
Capped to 32 to match the proto cap on related security fields. */
meshtastic_LockdownAuth_passphrase_t passphrase;
/* Optional override of the boot-count token TTL granted on success.
0 = use firmware default (TOKEN_DEFAULT_BOOTS).
On reboot the firmware decrements this; when it reaches 0 the
device boots fully locked and requires a fresh passphrase. */
uint32_t boots_remaining;
/* Optional wall-clock expiry for the unlock token, as absolute
Unix-epoch seconds. 0 = no time limit (only the boot-count TTL
applies). On boot, if the device RTC is set and now > this value,
the token is treated as expired. */
uint32_t valid_until_epoch;
/* If true, ignore passphrase fields, immediately revoke all
connection-level admin authorization, and reboot the device into
the locked state. Always honoured regardless of current lock state. */
bool lock_now;
} meshtastic_LockdownAuth;
/* Parameters for setting up Meshtastic for ameteur radio usage */
typedef struct _meshtastic_HamParameters {
/* Amateur radio call sign, eg. KD2ABC */
@@ -384,6 +419,15 @@ typedef struct _meshtastic_AdminMessage {
meshtastic_AdminMessage_OTAEvent ota_request;
/* Parameters and sensor configuration */
meshtastic_SensorConfig sensor_config;
/* Lockdown passphrase delivery / unlock / lock-now command for hardened
firmware builds (see MESHTASTIC_LOCKDOWN). Used to provision the
passphrase on first boot, unlock encrypted storage on subsequent
reboots, re-verify on already-unlocked devices to authorize a new
client connection, or immediately re-lock the device.
Replaces the earlier scheme that repurposed SecurityConfig.private_key
to carry passphrase bytes; that hack is retired. */
meshtastic_LockdownAuth lockdown_auth;
};
/* The node generates this key and sends it with any get_x_response packets.
The client MUST include the same key with any set_x commands. Key expires after 300 seconds.
@@ -429,6 +473,7 @@ extern "C" {
#define meshtastic_KeyVerificationAdmin_message_type_ENUMTYPE meshtastic_KeyVerificationAdmin_MessageType
@@ -441,6 +486,7 @@ extern "C" {
#define meshtastic_AdminMessage_init_default {0, {0}, {0, {0}}}
#define meshtastic_AdminMessage_InputEvent_init_default {0, 0, 0, 0}
#define meshtastic_AdminMessage_OTAEvent_init_default {_meshtastic_OTAMode_MIN, {0, {0}}}
#define meshtastic_LockdownAuth_init_default {{0, {0}}, 0, 0, 0}
#define meshtastic_HamParameters_init_default {"", 0, 0, ""}
#define meshtastic_NodeRemoteHardwarePinsResponse_init_default {0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
#define meshtastic_SharedContact_init_default {0, false, meshtastic_User_init_default, 0, 0}
@@ -453,6 +499,7 @@ extern "C" {
#define meshtastic_AdminMessage_init_zero {0, {0}, {0, {0}}}
#define meshtastic_AdminMessage_InputEvent_init_zero {0, 0, 0, 0}
#define meshtastic_AdminMessage_OTAEvent_init_zero {_meshtastic_OTAMode_MIN, {0, {0}}}
#define meshtastic_LockdownAuth_init_zero {{0, {0}}, 0, 0, 0}
#define meshtastic_HamParameters_init_zero {"", 0, 0, ""}
#define meshtastic_NodeRemoteHardwarePinsResponse_init_zero {0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
#define meshtastic_SharedContact_init_zero {0, false, meshtastic_User_init_zero, 0, 0}
@@ -470,6 +517,10 @@ extern "C" {
#define meshtastic_AdminMessage_InputEvent_touch_y_tag 4
#define meshtastic_AdminMessage_OTAEvent_reboot_ota_mode_tag 1
#define meshtastic_AdminMessage_OTAEvent_ota_hash_tag 2
#define meshtastic_LockdownAuth_passphrase_tag 1
#define meshtastic_LockdownAuth_boots_remaining_tag 2
#define meshtastic_LockdownAuth_valid_until_epoch_tag 3
#define meshtastic_LockdownAuth_lock_now_tag 4
#define meshtastic_HamParameters_call_sign_tag 1
#define meshtastic_HamParameters_tx_power_tag 2
#define meshtastic_HamParameters_frequency_tag 3
@@ -560,6 +611,7 @@ extern "C" {
#define meshtastic_AdminMessage_nodedb_reset_tag 100
#define meshtastic_AdminMessage_ota_request_tag 102
#define meshtastic_AdminMessage_sensor_config_tag 103
#define meshtastic_AdminMessage_lockdown_auth_tag 104
#define meshtastic_AdminMessage_session_passkey_tag 101
/* Struct field encoding specification for nanopb */
@@ -621,7 +673,8 @@ X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_config,factory
X(a, STATIC, ONEOF, BOOL, (payload_variant,nodedb_reset,nodedb_reset), 100) \
X(a, STATIC, SINGULAR, BYTES, session_passkey, 101) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,ota_request,ota_request), 102) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,sensor_config,sensor_config), 103)
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,sensor_config,sensor_config), 103) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,lockdown_auth,lockdown_auth), 104)
#define meshtastic_AdminMessage_CALLBACK NULL
#define meshtastic_AdminMessage_DEFAULT NULL
#define meshtastic_AdminMessage_payload_variant_get_channel_response_MSGTYPE meshtastic_Channel
@@ -644,6 +697,7 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,sensor_config,sensor_config)
#define meshtastic_AdminMessage_payload_variant_key_verification_MSGTYPE meshtastic_KeyVerificationAdmin
#define meshtastic_AdminMessage_payload_variant_ota_request_MSGTYPE meshtastic_AdminMessage_OTAEvent
#define meshtastic_AdminMessage_payload_variant_sensor_config_MSGTYPE meshtastic_SensorConfig
#define meshtastic_AdminMessage_payload_variant_lockdown_auth_MSGTYPE meshtastic_LockdownAuth
#define meshtastic_AdminMessage_InputEvent_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, event_code, 1) \
@@ -659,6 +713,14 @@ X(a, STATIC, SINGULAR, BYTES, ota_hash, 2)
#define meshtastic_AdminMessage_OTAEvent_CALLBACK NULL
#define meshtastic_AdminMessage_OTAEvent_DEFAULT NULL
#define meshtastic_LockdownAuth_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, BYTES, passphrase, 1) \
X(a, STATIC, SINGULAR, UINT32, boots_remaining, 2) \
X(a, STATIC, SINGULAR, UINT32, valid_until_epoch, 3) \
X(a, STATIC, SINGULAR, BOOL, lock_now, 4)
#define meshtastic_LockdownAuth_CALLBACK NULL
#define meshtastic_LockdownAuth_DEFAULT NULL
#define meshtastic_HamParameters_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, call_sign, 1) \
X(a, STATIC, SINGULAR, INT32, tx_power, 2) \
@@ -737,6 +799,7 @@ X(a, STATIC, OPTIONAL, UINT32, set_accuracy, 1)
extern const pb_msgdesc_t meshtastic_AdminMessage_msg;
extern const pb_msgdesc_t meshtastic_AdminMessage_InputEvent_msg;
extern const pb_msgdesc_t meshtastic_AdminMessage_OTAEvent_msg;
extern const pb_msgdesc_t meshtastic_LockdownAuth_msg;
extern const pb_msgdesc_t meshtastic_HamParameters_msg;
extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg;
extern const pb_msgdesc_t meshtastic_SharedContact_msg;
@@ -751,6 +814,7 @@ extern const pb_msgdesc_t meshtastic_SHTXX_config_msg;
#define meshtastic_AdminMessage_fields &meshtastic_AdminMessage_msg
#define meshtastic_AdminMessage_InputEvent_fields &meshtastic_AdminMessage_InputEvent_msg
#define meshtastic_AdminMessage_OTAEvent_fields &meshtastic_AdminMessage_OTAEvent_msg
#define meshtastic_LockdownAuth_fields &meshtastic_LockdownAuth_msg
#define meshtastic_HamParameters_fields &meshtastic_HamParameters_msg
#define meshtastic_NodeRemoteHardwarePinsResponse_fields &meshtastic_NodeRemoteHardwarePinsResponse_msg
#define meshtastic_SharedContact_fields &meshtastic_SharedContact_msg
@@ -768,6 +832,7 @@ extern const pb_msgdesc_t meshtastic_SHTXX_config_msg;
#define meshtastic_AdminMessage_size 511
#define meshtastic_HamParameters_size 31
#define meshtastic_KeyVerificationAdmin_size 25
#define meshtastic_LockdownAuth_size 48
#define meshtastic_NodeRemoteHardwarePinsResponse_size 496
#define meshtastic_SCD30_config_size 27
#define meshtastic_SCD4X_config_size 29
@@ -33,6 +33,8 @@ typedef struct _meshtastic_PositionLite {
uint32_t time;
/* TODO: REPLACE */
meshtastic_Position_LocSource location_source;
/* Indicates the bits of precision set by the sending node */
uint32_t precision_bits;
} meshtastic_PositionLite;
typedef PB_BYTES_ARRAY_T(32) meshtastic_UserLite_public_key_t;
@@ -211,7 +213,7 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, 0}
#define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0}
#define meshtastic_NodeInfoLite_init_default {0, 0, 0, 0, false, 0, 0, 0, "", "", _meshtastic_HardwareModel_MIN, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
@@ -222,7 +224,7 @@ extern "C" {
#define meshtastic_NodeDatabase_init_default {0, {0}, {0}, {0}, {0}, {0}}
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
#define meshtastic_BackupPreferences_init_default {0, 0, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_ChannelFile_init_default, false, meshtastic_User_init_default}
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, 0}
#define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0}
#define meshtastic_NodeInfoLite_init_zero {0, 0, 0, 0, false, 0, 0, 0, "", "", _meshtastic_HardwareModel_MIN, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
@@ -240,6 +242,7 @@ extern "C" {
#define meshtastic_PositionLite_altitude_tag 3
#define meshtastic_PositionLite_time_tag 4
#define meshtastic_PositionLite_location_source_tag 5
#define meshtastic_PositionLite_precision_bits_tag 6
#define meshtastic_UserLite_macaddr_tag 1
#define meshtastic_UserLite_long_name_tag 2
#define meshtastic_UserLite_short_name_tag 3
@@ -298,7 +301,8 @@ X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \
X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \
X(a, STATIC, SINGULAR, INT32, altitude, 3) \
X(a, STATIC, SINGULAR, FIXED32, time, 4) \
X(a, STATIC, SINGULAR, UENUM, location_source, 5)
X(a, STATIC, SINGULAR, UENUM, location_source, 5) \
X(a, STATIC, SINGULAR, UINT32, precision_bits, 6)
#define meshtastic_PositionLite_CALLBACK NULL
#define meshtastic_PositionLite_DEFAULT NULL
@@ -447,10 +451,10 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg;
#define meshtastic_DeviceState_size 1737
#define meshtastic_NodeEnvironmentEntry_size 170
#define meshtastic_NodeInfoLite_size 105
#define meshtastic_NodePositionEntry_size 36
#define meshtastic_NodePositionEntry_size 42
#define meshtastic_NodeStatusEntry_size 89
#define meshtastic_NodeTelemetryEntry_size 35
#define meshtastic_PositionLite_size 28
#define meshtastic_PositionLite_size 34
#define meshtastic_UserLite_size 98
#ifdef __cplusplus
@@ -115,7 +115,7 @@ extern const pb_msgdesc_t meshtastic_NodeDatabase_Legacy_msg;
/* Maximum encoded size of messages (where known) */
/* meshtastic_NodeDatabase_Legacy_size depends on runtime parameters */
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_LEGACY_PB_H_MAX_SIZE meshtastic_NodeInfoLite_Legacy_size
#define meshtastic_NodeInfoLite_Legacy_size 196
#define meshtastic_NodeInfoLite_Legacy_size 202
#ifdef __cplusplus
} /* extern "C" */
@@ -57,6 +57,9 @@ PB_BIND(meshtastic_QueueStatus, meshtastic_QueueStatus, AUTO)
PB_BIND(meshtastic_FromRadio, meshtastic_FromRadio, 2)
PB_BIND(meshtastic_LockdownStatus, meshtastic_LockdownStatus, AUTO)
PB_BIND(meshtastic_ClientNotification, meshtastic_ClientNotification, 2)
@@ -134,6 +137,8 @@ PB_BIND(meshtastic_ChunkedPayloadResponse, meshtastic_ChunkedPayloadResponse, AU
+88 -1
View File
@@ -319,6 +319,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_HELTEC_V4_R8 = 132,
/* The HELTEC_MESH_NODE_T1 uses an NRF52840 chip, plus an SX1262. */
meshtastic_HardwareModel_HELTEC_MESH_NODE_T1 = 133,
/* B&Q Consulting Station G3: TBD */
meshtastic_HardwareModel_STATION_G3 = 134,
/* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */
@@ -636,6 +638,25 @@ typedef enum _meshtastic_LogRecord_Level {
meshtastic_LogRecord_Level_TRACE = 5
} meshtastic_LogRecord_Level;
typedef enum _meshtastic_LockdownStatus_State {
/* Default; should not be sent. */
meshtastic_LockdownStatus_State_STATE_UNSPECIFIED = 0,
/* No passphrase has ever been provisioned on this device.
Client should prompt the operator to set one. */
meshtastic_LockdownStatus_State_NEEDS_PROVISION = 1,
/* Storage is locked or this client has not authenticated yet.
lock_reason carries a machine-readable detail string.
Client should present (or auto-replay) a passphrase via
AdminMessage.lockdown_auth. */
meshtastic_LockdownStatus_State_LOCKED = 2,
/* Passphrase accepted; client is now authorized for this connection.
boots_remaining and valid_until_epoch describe the active session
token's TTL. */
meshtastic_LockdownStatus_State_UNLOCKED = 3,
/* Passphrase rejected. backoff_seconds is non-zero when rate-limited. */
meshtastic_LockdownStatus_State_UNLOCK_FAILED = 4
} meshtastic_LockdownStatus_State;
/* Struct definitions */
/* A GPS Position */
typedef struct _meshtastic_Position {
@@ -1146,6 +1167,38 @@ typedef struct _meshtastic_QueueStatus {
uint32_t mesh_packet_id;
} meshtastic_QueueStatus;
/* Lockdown state report from firmware to client (for hardened builds
with MESHTASTIC_LOCKDOWN). Sent immediately after config_complete_id
to inform a freshly-connected unauthorized client what it must do,
and again in response to each LockdownAuth admin command. */
typedef struct _meshtastic_LockdownStatus {
/* Current lockdown state being reported. */
meshtastic_LockdownStatus_State state;
/* For LOCKED: machine-readable reason. Known values:
"needs_auth" — storage already unlocked, client must auth
"token_missing" — no boot token on flash
"token_expired" — boot token wall-clock TTL elapsed
"token_boots_zero" — boot token boot-count TTL exhausted
"token_hmac_fail" — token tampered or wrong device
"token_dek_fail" — token DEK decrypt failed
"token_wrong_size" — token file corrupted
"token_bad_magic" — token file corrupted
"not_provisioned" — should generally use NEEDS_PROVISION state instead
Other values may be added; clients should treat unknown values as
"locked, ask for passphrase". */
char lock_reason[32];
/* For UNLOCKED: remaining boots on the issued session token.
Decrements by 1 on each subsequent boot. */
uint32_t boots_remaining;
/* For UNLOCKED: wall-clock expiry of the issued session token,
absolute Unix-epoch seconds. 0 = no time limit. */
uint32_t valid_until_epoch;
/* For UNLOCK_FAILED: seconds the client must wait before another
passphrase attempt will be accepted. 0 = wrong passphrase, no
backoff (immediate retry allowed but advisable to prompt user). */
uint32_t backoff_seconds;
} meshtastic_LockdownStatus;
typedef struct _meshtastic_KeyVerificationNumberInform {
uint64_t nonce;
char remote_longname[40];
@@ -1319,6 +1372,12 @@ typedef struct _meshtastic_FromRadio {
meshtastic_ClientNotification clientNotification;
/* Persistent data for device-ui */
meshtastic_DeviceUIConfig deviceuiConfig;
/* Lockdown state notification for hardened firmware builds.
Sent post-config (so unauthorized clients learn they must
provision/unlock) and after each LockdownAuth admin command
to report success or failure. Replaces the earlier scheme of
encoding state as magic-string prefixes inside ClientNotification. */
meshtastic_LockdownStatus lockdown_status;
};
} meshtastic_FromRadio;
@@ -1460,6 +1519,10 @@ extern "C" {
#define _meshtastic_LogRecord_Level_MAX meshtastic_LogRecord_Level_CRITICAL
#define _meshtastic_LogRecord_Level_ARRAYSIZE ((meshtastic_LogRecord_Level)(meshtastic_LogRecord_Level_CRITICAL+1))
#define _meshtastic_LockdownStatus_State_MIN meshtastic_LockdownStatus_State_STATE_UNSPECIFIED
#define _meshtastic_LockdownStatus_State_MAX meshtastic_LockdownStatus_State_UNLOCK_FAILED
#define _meshtastic_LockdownStatus_State_ARRAYSIZE ((meshtastic_LockdownStatus_State)(meshtastic_LockdownStatus_State_UNLOCK_FAILED+1))
#define meshtastic_Position_location_source_ENUMTYPE meshtastic_Position_LocSource
#define meshtastic_Position_altitude_source_ENUMTYPE meshtastic_Position_AltSource
@@ -1490,6 +1553,8 @@ extern "C" {
#define meshtastic_LockdownStatus_state_ENUMTYPE meshtastic_LockdownStatus_State
#define meshtastic_ClientNotification_level_ENUMTYPE meshtastic_LogRecord_Level
@@ -1530,6 +1595,7 @@ extern "C" {
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_default {0, 0, 0, 0}
#define meshtastic_FromRadio_init_default {0, 0, {meshtastic_MeshPacket_init_default}}
#define meshtastic_LockdownStatus_init_default {_meshtastic_LockdownStatus_State_MIN, "", 0, 0, 0}
#define meshtastic_ClientNotification_init_default {false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, {meshtastic_KeyVerificationNumberInform_init_default}}
#define meshtastic_KeyVerificationNumberInform_init_default {0, "", 0}
#define meshtastic_KeyVerificationNumberRequest_init_default {0, ""}
@@ -1564,6 +1630,7 @@ extern "C" {
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0}
#define meshtastic_FromRadio_init_zero {0, 0, {meshtastic_MeshPacket_init_zero}}
#define meshtastic_LockdownStatus_init_zero {_meshtastic_LockdownStatus_State_MIN, "", 0, 0, 0}
#define meshtastic_ClientNotification_init_zero {false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, {meshtastic_KeyVerificationNumberInform_init_zero}}
#define meshtastic_KeyVerificationNumberInform_init_zero {0, "", 0}
#define meshtastic_KeyVerificationNumberRequest_init_zero {0, ""}
@@ -1716,6 +1783,11 @@ extern "C" {
#define meshtastic_QueueStatus_free_tag 2
#define meshtastic_QueueStatus_maxlen_tag 3
#define meshtastic_QueueStatus_mesh_packet_id_tag 4
#define meshtastic_LockdownStatus_state_tag 1
#define meshtastic_LockdownStatus_lock_reason_tag 2
#define meshtastic_LockdownStatus_boots_remaining_tag 3
#define meshtastic_LockdownStatus_valid_until_epoch_tag 4
#define meshtastic_LockdownStatus_backoff_seconds_tag 5
#define meshtastic_KeyVerificationNumberInform_nonce_tag 1
#define meshtastic_KeyVerificationNumberInform_remote_longname_tag 2
#define meshtastic_KeyVerificationNumberInform_security_number_tag 3
@@ -1775,6 +1847,7 @@ extern "C" {
#define meshtastic_FromRadio_fileInfo_tag 15
#define meshtastic_FromRadio_clientNotification_tag 16
#define meshtastic_FromRadio_deviceuiConfig_tag 17
#define meshtastic_FromRadio_lockdown_status_tag 18
#define meshtastic_Heartbeat_nonce_tag 1
#define meshtastic_ToRadio_packet_tag 1
#define meshtastic_ToRadio_want_config_id_tag 3
@@ -2015,7 +2088,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,metadata,metadata), 13) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,mqttClientProxyMessage,mqttClientProxyMessage), 14) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,fileInfo,fileInfo), 15) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,clientNotification,clientNotification), 16) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,deviceuiConfig,deviceuiConfig), 17)
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,deviceuiConfig,deviceuiConfig), 17) \
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,lockdown_status,lockdown_status), 18)
#define meshtastic_FromRadio_CALLBACK NULL
#define meshtastic_FromRadio_DEFAULT NULL
#define meshtastic_FromRadio_payload_variant_packet_MSGTYPE meshtastic_MeshPacket
@@ -2032,6 +2106,16 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,deviceuiConfig,deviceuiConfi
#define meshtastic_FromRadio_payload_variant_fileInfo_MSGTYPE meshtastic_FileInfo
#define meshtastic_FromRadio_payload_variant_clientNotification_MSGTYPE meshtastic_ClientNotification
#define meshtastic_FromRadio_payload_variant_deviceuiConfig_MSGTYPE meshtastic_DeviceUIConfig
#define meshtastic_FromRadio_payload_variant_lockdown_status_MSGTYPE meshtastic_LockdownStatus
#define meshtastic_LockdownStatus_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UENUM, state, 1) \
X(a, STATIC, SINGULAR, STRING, lock_reason, 2) \
X(a, STATIC, SINGULAR, UINT32, boots_remaining, 3) \
X(a, STATIC, SINGULAR, UINT32, valid_until_epoch, 4) \
X(a, STATIC, SINGULAR, UINT32, backoff_seconds, 5)
#define meshtastic_LockdownStatus_CALLBACK NULL
#define meshtastic_LockdownStatus_DEFAULT NULL
#define meshtastic_ClientNotification_FIELDLIST(X, a) \
X(a, STATIC, OPTIONAL, UINT32, reply_id, 1) \
@@ -2192,6 +2276,7 @@ extern const pb_msgdesc_t meshtastic_MyNodeInfo_msg;
extern const pb_msgdesc_t meshtastic_LogRecord_msg;
extern const pb_msgdesc_t meshtastic_QueueStatus_msg;
extern const pb_msgdesc_t meshtastic_FromRadio_msg;
extern const pb_msgdesc_t meshtastic_LockdownStatus_msg;
extern const pb_msgdesc_t meshtastic_ClientNotification_msg;
extern const pb_msgdesc_t meshtastic_KeyVerificationNumberInform_msg;
extern const pb_msgdesc_t meshtastic_KeyVerificationNumberRequest_msg;
@@ -2228,6 +2313,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_LogRecord_fields &meshtastic_LogRecord_msg
#define meshtastic_QueueStatus_fields &meshtastic_QueueStatus_msg
#define meshtastic_FromRadio_fields &meshtastic_FromRadio_msg
#define meshtastic_LockdownStatus_fields &meshtastic_LockdownStatus_msg
#define meshtastic_ClientNotification_fields &meshtastic_ClientNotification_msg
#define meshtastic_KeyVerificationNumberInform_fields &meshtastic_KeyVerificationNumberInform_msg
#define meshtastic_KeyVerificationNumberRequest_fields &meshtastic_KeyVerificationNumberRequest_msg
@@ -2263,6 +2349,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
#define meshtastic_KeyVerificationNumberInform_size 58
#define meshtastic_KeyVerificationNumberRequest_size 52
#define meshtastic_KeyVerification_size 79
#define meshtastic_LockdownStatus_size 53
#define meshtastic_LogRecord_size 426
#define meshtastic_LowEntropyKey_size 0
#define meshtastic_MeshPacket_size 381
+1 -1
View File
@@ -80,7 +80,7 @@ static_assert(sizeof(meshtastic_NodeInfoLite) <= 130, "NodeInfoLite size increas
#if defined(ARCH_STM32WL)
#define MAX_NUM_NODES 10
#elif defined(ARCH_NRF52)
#define MAX_NUM_NODES 80
#define MAX_NUM_NODES 150
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#include "Esp.h"
static inline int get_max_num_nodes()
+89 -16
View File
@@ -15,6 +15,12 @@
#define ETH ETH2
#endif // HAS_ETHERNET
#if HAS_ETHERNET && defined(USE_CH390D)
#include "ESP32_CH390.h"
#include "hal/spi_types.h"
#define ETH CH390
#endif // HAS_ETHERNET
#include <WiFiUdp.h>
#ifdef ARCH_ESP32
#if !MESHTASTIC_EXCLUDE_WEBSERVER
@@ -56,12 +62,43 @@ unsigned long lastrun_ntp = 0;
bool needReconnect = true; // If we create our reconnector, run it once at the beginning
bool isReconnecting = false; // If we are currently reconnecting
#if defined(USE_WS5500) || defined(USE_CH390D)
static volatile bool ethNetworkConnectedPending = false;
#endif
WiFiUDP syslogClient;
meshtastic::Syslog syslog(syslogClient);
Periodic *wifiReconnect;
#if defined(USE_WS5500) || defined(USE_CH390D)
static void onNetworkConnected();
static uint32_t lastEthIP = 0;
static int32_t ethNetworkConnectedPoll()
{
if (ethNetworkConnectedPending) {
ethNetworkConnectedPending = false;
uint32_t ip = (uint32_t)ETH.localIP();
bool ipChanged = APStartupComplete && ip != 0 && ip != lastEthIP;
onNetworkConnected();
if (ipChanged) {
LOG_INFO("Ethernet IP changed (%u.%u.%u.%u), restarting mDNS", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff,
(ip >> 24) & 0xff);
MDNS.end();
if (MDNS.begin("Meshtastic")) {
MDNS.addService("meshtastic", "tcp", SERVER_API_DEFAULT_PORT);
MDNS.addServiceTxt("meshtastic", "tcp", "shortname", String(owner.short_name));
MDNS.addServiceTxt("meshtastic", "tcp", "id", String(nodeDB->getNodeId().c_str()));
MDNS.addServiceTxt("meshtastic", "tcp", "pio_env", optstr(APP_ENV));
}
}
if (ip != 0)
lastEthIP = ip;
}
return 500;
}
#endif
#ifdef USE_WS5500
// Startup Ethernet
bool initEthernet()
@@ -72,6 +109,38 @@ bool initEthernet()
#if !MESHTASTIC_EXCLUDE_WEBSERVER
createSSLCert(); // For WebServer
#endif
new concurrency::Periodic("EthConnect", ethNetworkConnectedPoll);
return true;
}
return false;
}
#endif
#ifdef USE_CH390D
// Startup Ethernet
bool initEthernet()
{
// Configure CH390
ch390_config_t ch390_conf = CH390_DEFAULT_CONFIG();
ch390_conf.spi_host = SPI3_HOST;
ch390_conf.spi_cs_gpio = ETH_CS_PIN;
ch390_conf.spi_sck_gpio = ETH_SCLK_PIN;
ch390_conf.spi_mosi_gpio = ETH_MOSI_PIN;
ch390_conf.spi_miso_gpio = ETH_MISO_PIN;
ch390_conf.int_gpio = ETH_INT_PIN;
#ifdef ETH_RST_PIN
ch390_conf.reset_gpio = ETH_RST_PIN;
#else
ch390_conf.reset_gpio = -1;
#endif
ch390_conf.spi_clock_mhz = 20;
if ((config.network.eth_enabled) && (ETH.begin(ch390_conf))) {
WiFi.onEvent(WiFiEvent);
#if !MESHTASTIC_EXCLUDE_WEBSERVER
createSSLCert(); // For WebServer
#endif
new concurrency::Periodic("EthConnect", ethNetworkConnectedPoll);
return true;
}
@@ -222,10 +291,8 @@ static int32_t reconnectWiFi()
#endif
return 1000; // check once per second
} else {
#ifdef ARCH_RP2040
onNetworkConnected(); // will only do anything once
#endif
return 300000; // every 5 minutes
onNetworkConnected(); // will only do anything once (guarded by APStartupComplete)
return 300000; // every 5 minutes
}
}
@@ -234,7 +301,7 @@ bool isWifiAvailable()
if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) {
return true;
#ifdef USE_WS5500
#if defined(USE_WS5500) || defined(USE_CH390D)
} else if (config.network.eth_enabled) {
return true;
#endif
@@ -274,9 +341,6 @@ bool initWifi()
const char *wifiPsw = config.network.wifi_psk;
#ifndef ARCH_RP2040
#if !MESHTASTIC_EXCLUDE_WEBSERVER
createSSLCert(); // For WebServer
#endif
WiFi.persistent(false); // Disable flash storage for WiFi credentials
#endif
if (!*wifiPsw) // Treat empty password as no password
@@ -301,6 +365,9 @@ bool initWifi()
#endif
}
#ifdef ARCH_ESP32
// Register WiFi event handler BEFORE createSSLCert() to prevent race condition:
// Without this, WiFi can auto-reconnect during cert generation and fire GOT_IP
// before the handler is registered, causing onNetworkConnected() to never run.
WiFi.onEvent(WiFiEvent);
WiFi.setAutoReconnect(true);
WiFi.setSleep(false);
@@ -322,6 +389,12 @@ bool initWifi()
wifiDisconnectReason = info.wifi_sta_disconnected.reason;
},
WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
#endif
#ifndef ARCH_RP2040
#if !MESHTASTIC_EXCLUDE_WEBSERVER
createSSLCert(); // For WebServer - called after WiFi.onEvent() to avoid race condition
#endif
#endif
LOG_DEBUG("JOINING WIFI soon: ssid=%s", wifiName);
wifiReconnect = new Periodic("WifiConnect", reconnectWiFi);
@@ -384,13 +457,13 @@ static void WiFiEvent(WiFiEvent_t event)
#endif
}
#ifdef WIFI_LED
digitalWrite(WIFI_LED, HIGH);
digitalWrite(WIFI_LED, LOW ^ WIFI_STATE_ON);
#endif
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
LOG_INFO("Disconnected from WiFi access point");
#ifdef WIFI_LED
digitalWrite(WIFI_LED, LOW);
digitalWrite(WIFI_LED, HIGH ^ WIFI_STATE_ON);
#endif
#if HAS_UDP_MULTICAST
if (udpHandler) {
@@ -452,13 +525,13 @@ static void WiFiEvent(WiFiEvent_t event)
case ARDUINO_EVENT_WIFI_AP_START:
LOG_INFO("WiFi access point started");
#ifdef WIFI_LED
digitalWrite(WIFI_LED, HIGH);
digitalWrite(WIFI_LED, LOW ^ WIFI_STATE_ON);
#endif
break;
case ARDUINO_EVENT_WIFI_AP_STOP:
LOG_INFO("WiFi access point stopped");
#ifdef WIFI_LED
digitalWrite(WIFI_LED, LOW);
digitalWrite(WIFI_LED, HIGH ^ WIFI_STATE_ON);
#endif
break;
case ARDUINO_EVENT_WIFI_AP_STACONNECTED:
@@ -494,18 +567,18 @@ static void WiFiEvent(WiFiEvent_t event)
LOG_INFO("Ethernet disconnected");
break;
case ARDUINO_EVENT_ETH_GOT_IP:
#ifdef USE_WS5500
#if defined(USE_WS5500) || defined(USE_CH390D)
LOG_INFO("Obtained IP address: %s, %u Mbps, %s", ETH.localIP().toString().c_str(), ETH.linkSpeed(),
ETH.fullDuplex() ? "FULL_DUPLEX" : "HALF_DUPLEX");
onNetworkConnected();
ethNetworkConnectedPending = true;
#endif
break;
case ARDUINO_EVENT_ETH_GOT_IP6:
#ifdef USE_WS5500
#if defined(USE_WS5500) || defined(USE_CH390D)
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
LOG_INFO("Obtained Local IP6 address: %s", ETH.linkLocalIPv6().toString().c_str());
LOG_INFO("Obtained GlobalIP6 address: %s", ETH.globalIPv6().toString().c_str());
#else
#elif defined(USE_WS5500)
LOG_INFO("Obtained IP6 address: %s", ETH.localIPv6().toString().c_str());
#endif
#endif
+1 -1
View File
@@ -26,7 +26,7 @@ bool isWifiAvailable();
uint8_t getWifiDisconnectReason();
#ifdef USE_WS5500
#if defined(USE_WS5500) || defined(USE_CH390D)
// Startup Ethernet
bool initEthernet();
#endif
+1 -1
View File
@@ -1318,7 +1318,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r
}
#endif
#if HAS_ETHERNET && !defined(USE_WS5500)
#if HAS_ETHERNET && !defined(USE_WS5500) && !defined(USE_CH390D)
conn.has_ethernet = true;
conn.ethernet.has_status = true;
if (Ethernet.linkStatus() == LinkON) {
+11
View File
@@ -115,6 +115,17 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event)
case INPUT_BROKER_SHUTDOWN:
shutdownAtMsec = millis();
return true;
// factory reset
case INPUT_BROKER_FACTORY_RST:
disableBluetooth();
LOG_INFO("Initiate full factory reset");
nodeDB->factoryReset(true);
// reboot(DEFAULT_REBOOT_SECONDS);
LOG_INFO("Reboot in %d seconds", DEFAULT_REBOOT_SECONDS);
if (screen)
screen->showSimpleBanner("Rebooting...", 0); // stays on screen
rebootAtMsec = (DEFAULT_REBOOT_SECONDS < 0) ? 0 : (millis() + DEFAULT_REBOOT_SECONDS * 1000);
return true;
default:
// No other input events handled here
+1 -4
View File
@@ -21,9 +21,6 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
textPacketList[textPacketListIndex] = mp.id;
textPacketListIndex = (textPacketListIndex + 1) % TEXT_PACKET_LIST_SIZE;
// We only store/display messages destined for us.
devicestate.rx_text_message = mp;
devicestate.has_rx_text_message = true;
IF_SCREEN(
// Guard against running in MeshtasticUI or with no screen
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR) {
@@ -59,4 +56,4 @@ bool TextMessageModule::recentlySeen(uint32_t id)
}
}
return false;
}
}
+3 -3
View File
@@ -7,8 +7,8 @@
* Text message handling for Meshtastic.
*
* This module is responsible for receiving and storing incoming text messages
* from the mesh. It updates device state and notifies observers so that other
* components (such as the MessageRenderer) can later display or process them.
* from the mesh. It notifies observers so that other components (such as the
* MessageRenderer) can later display or process them.
*
* Rendering of messages on screen is no longer done here.
*/
@@ -36,4 +36,4 @@ class TextMessageModule : public SinglePortModule, public Observable<const mesht
size_t textPacketListIndex = 0;
};
extern TextMessageModule *textMessageModule;
extern TextMessageModule *textMessageModule;
+6
View File
@@ -22,6 +22,9 @@
#if HAS_ETHERNET && defined(USE_WS5500)
#include <ETHClass2.h>
#define ETH ETH2
#elif HAS_ETHERNET && defined(USE_CH390D)
#include "ESP32_CH390.h"
#define ETH CH390
#endif // HAS_ETHERNET
#include "Default.h"
#if !defined(ARCH_NRF52) || NRF52_USE_JSON
@@ -344,6 +347,9 @@ inline bool isConnectedToNetwork()
#ifdef USE_WS5500
if (ETH.connected())
return true;
#elif defined(USE_CH390D)
if (ETH.isConnected())
return true;
#endif
#if HAS_WIFI
+1 -1
View File
@@ -15,7 +15,7 @@
#include <WiFiClientSecure.h>
#endif
#endif
#if HAS_ETHERNET && !defined(USE_WS5500)
#if HAS_ETHERNET && !defined(USE_WS5500) && !defined(USE_CH390D)
#include <EthernetClient.h>
#endif
+2
View File
@@ -146,6 +146,8 @@
#define HW_VENDOR meshtastic_HardwareModel_THINKNODE_M2
#elif defined(ELECROW_ThinkNode_M5)
#define HW_VENDOR meshtastic_HardwareModel_THINKNODE_M5
#elif defined(ELECROW_ThinkNode_M7)
#define HW_VENDOR meshtastic_HardwareModel_THINKNODE_M7
#elif defined(ESP32_S3_PICO)
#define HW_VENDOR meshtastic_HardwareModel_ESP32_S3_PICO
#elif defined(SENSELORA_S3)
+1 -1
View File
@@ -32,7 +32,7 @@ void variant_shutdown() {}
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_BLUETOOTH
void setBluetoothEnable(bool enable)
{
#ifdef USE_WS5500
#if defined(USE_WS5500) || defined(USE_CH390D)
if ((config.bluetooth.enabled == true) && (config.network.wifi_enabled == false))
#elif HAS_WIFI
if (!isWifiAvailable() && config.bluetooth.enabled == true)
@@ -291,7 +291,7 @@ std::string MeshPacketSerializer::JsonSerialize(const meshtastic_MeshPacket *mp,
auto addToRoute = [](JsonArray *route, NodeNum num) {
char long_name[40] = "Unknown";
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(num);
const meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(num);
bool name_known = nodeInfoLiteHasUser(node);
if (name_known) {
const size_t copy_len =
+12 -2
View File
@@ -119,18 +119,24 @@ void XModemAdapter::handlePacket(meshtastic_XModem xmodemPacket)
case meshtastic_XModem_Control_STX:
if ((xmodemPacket.seq == 0) && !isReceiving && !isTransmitting) {
// NULL packet has the destination filename
memcpy(filename, &xmodemPacket.buffer.bytes, xmodemPacket.buffer.size);
strncpy(filename, (const char *)xmodemPacket.buffer.bytes, sizeof(filename) - 1);
filename[sizeof(filename) - 1] = '\0';
if (xmodemPacket.control == meshtastic_XModem_Control_SOH) { // Receive this file and put to Flash
// FILE_O_WRITE on Adafruit_LittleFS is append, not truncate — remove first.
spiLock->lock();
if (FSCom.exists(filename))
FSCom.remove(filename);
file = FSCom.open(filename, FILE_O_WRITE);
spiLock->unlock();
if (file) {
LOG_INFO("XModem: receiving %s", filename);
sendControl(meshtastic_XModem_Control_ACK);
isReceiving = true;
packetno = 1;
break;
}
LOG_WARN("XModem: open(%s, WRITE) failed", filename);
sendControl(meshtastic_XModem_Control_NAK);
isReceiving = false;
break;
@@ -168,8 +174,12 @@ void XModemAdapter::handlePacket(meshtastic_XModem xmodemPacket)
check(xmodemPacket.buffer.bytes, xmodemPacket.buffer.size, xmodemPacket.crc16)) {
// valid packet
spiLock->lock();
file.write(xmodemPacket.buffer.bytes, xmodemPacket.buffer.size);
size_t written = file.write(xmodemPacket.buffer.bytes, xmodemPacket.buffer.size);
spiLock->unlock();
if (written != xmodemPacket.buffer.size) {
LOG_WARN("XModem: short write seq=%d expected=%d wrote=%d (LittleFS partition full?)",
(int)xmodemPacket.seq, (int)xmodemPacket.buffer.size, (int)written);
}
sendControl(meshtastic_XModem_Control_ACK);
packetno++;
break;
+3
View File
@@ -52,6 +52,9 @@ class XModemAdapter
meshtastic_XModem getForPhone();
void resetForPhone();
// True while a file transfer is in flight; lets callers avoid racing our `file` handle.
bool isBusy() const { return isReceiving || isTransmitting; }
private:
bool isReceiving = false;
bool isTransmitting = false;
+153
View File
@@ -0,0 +1,153 @@
# Fake NodeDB Fixtures
Deterministic JSONL seed files for the v25 `meshtastic_NodeDatabase` format
plus tooling that compiles them to binary `.proto` files and pushes them
onto a device for testing.
Centered on Truth or Consequences, NM (33.1284°N, 107.2528°W) with a 60 km
spread — change via `--centroid` and `--spread-km` if you want a different
geography.
## Pipeline
```text
bin/gen-fake-nodedb-seed.py
↓ (single Random(seed); no wall-clock dependence)
test/fixtures/nodedb/seed_v25_<N>.jsonl ← committed, hand-editable
↓
bin/seed-json-to-proto.py
↓ (resolves *_offset_sec → now-relative epochs at compile time)
build/fixtures/nodedb/nodes_v25_<N>.proto ← .gitignored, fresh timestamps
↓
- Portduino: cp to ~/.portduino/<config>/prefs/nodes.proto
- Hardware: XModem upload via mcp-server's push_fake_nodedb tool
```
## What's committed
| File | Size | Purpose |
| --------------------- | ------- | ------------------------------------------------------- |
| `seed_v25_0250.jsonl` | ~200 KB | Matches ESP32-S3 high-flash MAX_NUM_NODES cap |
| `seed_v25_0500.jsonl` | ~400 KB | Stress between caps |
| `seed_v25_1000.jsonl` | ~800 KB | Large mesh stress |
| `seed_v25_2000.jsonl` | ~1.6 MB | Truncation/eviction stress (exceeds every platform cap) |
## Determinism contract
**Structural fields are deterministic** given a fixed `--seed`: NodeNum,
long_name, short_name, hw_model, role, public_key, snr, channel, hops_away,
next_hop, bitfield flags, latitude/longitude/altitude, all
DeviceMetrics/EnvironmentMetrics/StatusMessage values.
**Timestamps are intentionally non-deterministic** at compile time. The JSONL
stores `*_offset_sec` (seconds before "now"); the compile step subtracts these
from current wall clock so the loaded NodeDB shows fresh "recently heard"
peers regardless of when the fixture was generated. Pass `--now-epoch T` to
the compile step to pin it for byte-identical CI artifacts.
## Active-board allow-list
`hw_model` values are restricted to the intersection of:
1. Variants with `custom_meshtastic_support_level = 1` in `variants/*/*/platformio.ini`
2. Values present in the `HardwareModel` enum in `mesh.proto`
This excludes legacy/deprecated boards (Heltec V1–V2, TLORA V1–V2, classic
TBEAM (4) and TBEAM_V0P7 (6), Nano G1, Station G1/G2, etc.) and fuzzer-only
sentinels (PORTDUINO, ANDROID_SIM, DIY_V1, LORA_RELAY_V1, etc.).
Refresh the allow-list in `bin/gen-fake-nodedb-seed.py:HW_MODEL_WEIGHTS` when
boards graduate to tier-1 (or retire). One-liner to print the current
intersection:
```bash
for f in $(find variants -name 'platformio.ini' | xargs grep -lE 'custom_meshtastic_support_level = 1'); do
grep custom_meshtastic_hw_model_slug "$f" | awk -F= '{print $2}' | tr -d ' '
done | sort -u | comm -12 - <(
bin/_generated/meshtastic_v25/__init__.py >/dev/null 2>&1 || ./bin/regen-py-protos.sh >&2
python3 -c "import sys; sys.path.insert(0,'bin/_generated'); \
from meshtastic_v25.mesh_pb2 import HardwareModel; \
print('\n'.join(HardwareModel.keys()))" | sort
)
```
## Role allow-list
`role` is drawn from non-deprecated `Config.DeviceConfig.Role` values:
- Excluded: `ROUTER_CLIENT` (deprecated v2.3.15), `REPEATER` (deprecated v2.7.11)
- Active: CLIENT, CLIENT_MUTE, ROUTER, TRACKER, SENSOR, TAK, CLIENT_HIDDEN,
LOST_AND_FOUND, TAK_TRACKER, ROUTER_LATE, CLIENT_BASE
## Quickstart
### Regenerate fixtures with fresh timestamps
```bash
./bin/regen-fake-nodedbs.sh
```
This recompiles all four `.proto` outputs into `build/fixtures/nodedb/` from
the committed JSONL seeds, using current wall clock for timestamps. Re-run
whenever you want "recent-looking" cached state on a freshly-booted device.
### Bump the seed (regenerate JSONL structure)
```bash
REGEN_SEEDS=yes ./bin/regen-fake-nodedbs.sh
```
This overwrites the committed JSONL files. Commit the result.
### Hand-edit a specific scenario
```bash
# Find the node you want to tweak, edit the line in place.
$EDITOR test/fixtures/nodedb/seed_v25_0250.jsonl
# Recompile and push.
./bin/regen-fake-nodedbs.sh
```
Each line of the JSONL is one node + metadata as the first line. Field schema
documented inline in `bin/gen-fake-nodedb-seed.py`. To override a specific
timestamp, replace the `last_heard_offset_sec` field with `last_heard` (an
absolute epoch); the compile step honors absolute values.
### Load onto Portduino (native macOS / linux)
```bash
cp build/fixtures/nodedb/nodes_v25_1000.proto ~/.portduino/default/prefs/nodes.proto
# Run the native binary; loadFromDisk picks it up at boot.
```
### Push to USB-attached hardware via mcp-server
```python
# From within the mcp-server tool surface:
push_fake_nodedb(
size=500,
target="hardware",
port="/dev/cu.usbmodem21301", # discover via list_devices
confirm=True, # gates the destructive write + reboot
)
```
Streams the proto over XModem to `/prefs/nodes.proto`, then issues a 1-second
reboot so `loadFromDisk` picks it up on next boot. CRC16-CCITT-validated
chunks; retries each chunk up to 5× on NAK before aborting with `CAN`.
## Schema reference
See `bin/gen-fake-nodedb-seed.py` for the JSONL field reference. Key points:
- `num` is a hex string (`"0xa1b2c3d4"`)
- `public_key_hex` is 64 hex chars (32 bytes), empty for keyless nodes
- `hw_model` and `role` are enum **names**; the compile step resolves them
via `HardwareModel.Value(name)` / `Config.DeviceConfig.Role.Value(name)`
- `bitfield` is a struct of named booleans; the compile step packs them
per the bit positions in `src/mesh/NodeDB.h:467-484`
- `position` / `telemetry` / `environment` / `status` are nullable;
coverage ratios at seed time decide which nodes get which
- `latitude` / `longitude` are floats in degrees (compiled to `latitude_i =
int(lat * 1e7)` matching `meshtastic_PositionLite`)
+251
View File
@@ -0,0 +1,251 @@
{"_meta": {"centroid": [33.1284, -107.2528], "count": 250, "coverage": {"environment": 0.25, "position": 0.85, "status": 0.4, "telemetry": 0.7}, "generated_at_iso": "1970-08-23T11:55:11Z", "last_heard_max_sec": 604800, "last_heard_mean_sec": 3600, "my_node_num_excluded": null, "seed": 20260511, "spread_km": 60.0, "version": 25}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1009.74, "iaq": 31, "relative_humidity": 46.72, "temperature": 24.16}, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 4809, "long_name": "Drifting Phoenix", "next_hop": 253, "num": "0x0005e869", "position": {"altitude": 1338, "latitude": 33.690292, "location_source": "LOC_INTERNAL", "longitude": -106.436201, "time_offset_sec": 4996}, "public_key_hex": "056060d6ceae374c7ee39ffb5fb6c2503d238610f2277c47e7cc008a9a096dc5", "role": "CLIENT", "short_name": "DB5I", "snr": 6.64, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1023.84, "iaq": 38, "relative_humidity": 21.78, "temperature": 30.58}, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 1304, "long_name": "Hidden Aspen", "next_hop": 0, "num": "0x00511844", "position": {"altitude": 1535, "latitude": 32.558935, "location_source": "LOC_INTERNAL", "longitude": -107.91722, "time_offset_sec": 1442}, "public_key_hex": "3cae2af9a3e9e2d04829c53ad6cac0f87d8cc81ef4b3ac26a20548113a0d8280", "role": "CLIENT", "short_name": "H4WA", "snr": -0.68, "status": null, "telemetry": {"air_util_tx": 0.075, "battery_level": 75, "channel_utilization": 11.57, "uptime_seconds": 162386, "voltage": 3.975}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1836, "long_name": "Iron Otter", "next_hop": 0, "num": "0x02396342", "position": {"altitude": 1379, "latitude": 32.240662, "location_source": "LOC_INTERNAL", "longitude": -107.329117, "time_offset_sec": 2132}, "public_key_hex": "12e9fbc814fd38f3cb2f87dff7de3e9d16d456ee4c68c35cbba37c34e69182f4", "role": "CLIENT", "short_name": "IAJQ", "snr": 10.63, "status": null, "telemetry": {"air_util_tx": 0.304, "battery_level": 56, "channel_utilization": 36.83, "uptime_seconds": 103925, "voltage": 3.804}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.88, "iaq": 72, "relative_humidity": 36.6, "temperature": 17.87}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 1507, "long_name": "Tall Cougar", "next_hop": 0, "num": "0x02b15d65", "position": {"altitude": 1087, "latitude": 32.881111, "location_source": "LOC_INTERNAL", "longitude": -106.606342, "time_offset_sec": 1695}, "public_key_hex": "78f0eb2208a2d578e455169e63f635a2d7d5229e6482453317a1971256a93a44", "role": "CLIENT", "short_name": "TYD8", "snr": 6.84, "status": null, "telemetry": {"air_util_tx": 0.978, "battery_level": 43, "channel_utilization": 10.6, "uptime_seconds": 133906, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1009.27, "iaq": 67, "relative_humidity": 60.2, "temperature": 23.87}, "hops_away": 0, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 4638, "long_name": "Quick Yucca", "next_hop": 0, "num": "0x03829eb5", "position": {"altitude": 1526, "latitude": 32.816327, "location_source": "LOC_INTERNAL", "longitude": -107.795843, "time_offset_sec": 4912}, "public_key_hex": "502fc9984eefe0f5022e7c3b1baac8c2701d24e5e9a64a08791026f85ca17d3b", "role": "CLIENT", "short_name": "Q9YW", "snr": 8.1, "status": null, "telemetry": {"air_util_tx": 0.102, "battery_level": 100, "channel_utilization": 31.04, "uptime_seconds": 739545, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 4946, "long_name": "Wandering Doe", "next_hop": 0, "num": "0x03f1d514", "position": {"altitude": 1509, "latitude": 33.566253, "location_source": "LOC_INTERNAL", "longitude": -107.554414, "time_offset_sec": 4982}, "public_key_hex": "6bbae52865c1305682f3ac1ef3de4e3d39ec219cab928731137f2131883ef397", "role": "TRACKER", "short_name": "WR0J", "snr": 10.58, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 4827, "long_name": "Lone Hare", "next_hop": 0, "num": "0x04ca3beb", "position": {"altitude": 1092, "latitude": 33.004522, "location_source": "LOC_INTERNAL", "longitude": -107.283169, "time_offset_sec": 4829}, "public_key_hex": "", "role": "SENSOR", "short_name": "LO87", "snr": 12.0, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 1.037, "battery_level": 27, "channel_utilization": 2.08, "uptime_seconds": 49520, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 2448, "long_name": "Dusk Cougar", "next_hop": 0, "num": "0x0535c6ea", "position": {"altitude": 856, "latitude": 31.937803, "location_source": "LOC_INTERNAL", "longitude": -106.516028, "time_offset_sec": 2539}, "public_key_hex": "461adb831f736b11725a4c1a4574c6a74c88753d8046435f641a0fea108e9962", "role": "CLIENT_BASE", "short_name": "DFI5", "snr": 9.58, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 160, "long_name": "Sneaky Hawk", "next_hop": 0, "num": "0x061c8543", "position": {"altitude": 1543, "latitude": 33.531176, "location_source": "LOC_INTERNAL", "longitude": -107.114202, "time_offset_sec": 177}, "public_key_hex": "e70785c21cb865614a71a43f5bfb6d1139fc672e80fd598e3c1a15bfefe9a2af", "role": "CLIENT", "short_name": "SWXS", "snr": 8.12, "status": null, "telemetry": {"air_util_tx": 1.227, "battery_level": 101, "channel_utilization": 14.58, "uptime_seconds": 3338, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1717, "long_name": "Gold Adder", "next_hop": 0, "num": "0x0672aa7b", "position": {"altitude": 926, "latitude": 32.997975, "location_source": "LOC_INTERNAL", "longitude": -108.310088, "time_offset_sec": 1985}, "public_key_hex": "", "role": "CLIENT", "short_name": "GKVX", "snr": 1.62, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": {"barometric_pressure": 1015.21, "iaq": 55, "relative_humidity": 34.4, "temperature": 38.58}, "hops_away": 0, "hw_model": "THINKNODE_M1", "last_heard_offset_sec": 1257, "long_name": "Silent Dolphin", "next_hop": 0, "num": "0x070e1b66", "position": {"altitude": 1591, "latitude": 33.299113, "location_source": "LOC_INTERNAL", "longitude": -107.818463, "time_offset_sec": 1434}, "public_key_hex": "bc40ef1f82acda597f9259c27880e996eaf5d31db18a08daf4b92c333364f823", "role": "CLIENT", "short_name": "🗻", "snr": 0.08, "status": null, "telemetry": {"air_util_tx": 1.092, "battery_level": 57, "channel_utilization": 3.38, "uptime_seconds": 68787, "voltage": 3.813}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 948, "long_name": "Rough Doe", "next_hop": 0, "num": "0x07adbb88", "position": {"altitude": 1658, "latitude": 33.262723, "location_source": "LOC_INTERNAL", "longitude": -108.220474, "time_offset_sec": 1019}, "public_key_hex": "4a8bd22cc5910d64d9d1cbb9cfac6ba12e15d5a3eaf432a25914e282afdf6ad8", "role": "CLIENT", "short_name": "RP6F", "snr": 7.14, "status": null, "telemetry": {"air_util_tx": 0.718, "battery_level": 38, "channel_utilization": 5.75, "uptime_seconds": 52963, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 4100, "long_name": "Wandering Crow", "next_hop": 0, "num": "0x07bc9340", "position": {"altitude": 1555, "latitude": 33.465538, "location_source": "LOC_INTERNAL", "longitude": -108.0528, "time_offset_sec": 4267}, "public_key_hex": "8c38b26d1f0494c5e8ae1e8f259b2127f7a4ed7193820e2b5142196b4a5ca72e", "role": "CLIENT", "short_name": "🌵", "snr": 7.37, "status": null, "telemetry": {"air_util_tx": 0.128, "battery_level": 43, "channel_utilization": 13.24, "uptime_seconds": 3455, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 135, "long_name": "Lone Hawk", "next_hop": 0, "num": "0x083ddc7d", "position": {"altitude": 1727, "latitude": 33.142932, "location_source": "LOC_INTERNAL", "longitude": -107.69923, "time_offset_sec": 190}, "public_key_hex": "633bbaccd26d91e50d7482dfb72d7caa0c3d3ea2ac4537035af5dec53d703135", "role": "CLIENT", "short_name": "LPH4", "snr": 8.17, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1028.3, "iaq": 19, "relative_humidity": 65.94, "temperature": 2.42}, "hops_away": 3, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 6576, "long_name": "Sleepy Doe", "next_hop": 171, "num": "0x08a9fb83", "position": null, "public_key_hex": "5e98de33af5bf7584fa18bc37877e763892d8564bd3878a360631810d5b347ea", "role": "CLIENT", "short_name": "🐺", "snr": 9.09, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1011.54, "iaq": 58, "relative_humidity": 42.81, "temperature": 3.35}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 2645, "long_name": "Howling Elk", "next_hop": 0, "num": "0x08d5357a", "position": {"altitude": 1113, "latitude": 33.563203, "location_source": "LOC_INTERNAL", "longitude": -107.077155, "time_offset_sec": 2657}, "public_key_hex": "04c61243842c533fad9ecf8d25f76123d1626f074b5e0f27251eb78a7b8e7e2c", "role": "CLIENT", "short_name": "H8L8", "snr": 8.67, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.756, "battery_level": 84, "channel_utilization": 18.15, "uptime_seconds": 172126, "voltage": 4.056}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 587, "long_name": "Drifting Mamba", "next_hop": 64, "num": "0x08d602a7", "position": {"altitude": 1280, "latitude": 32.981947, "location_source": "LOC_INTERNAL", "longitude": -107.511111, "time_offset_sec": 885}, "public_key_hex": "6394f02f41a0e243c6ca8a8caf75c1e0b417e213446bf2713d9938fd759cb410", "role": "CLIENT", "short_name": "DLUF", "snr": 9.46, "status": null, "telemetry": {"air_util_tx": 0.411, "battery_level": 101, "channel_utilization": 16.4, "uptime_seconds": 75514, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 2735, "long_name": "Smooth Badger", "next_hop": 0, "num": "0x0923d80c", "position": {"altitude": 1401, "latitude": 33.18486, "location_source": "LOC_INTERNAL", "longitude": -107.615573, "time_offset_sec": 2892}, "public_key_hex": "c09db88982c59eac6204dd0dddb9adbe05e778349f78c2f62fce90dadd433f05", "role": "CLIENT", "short_name": "SANX", "snr": 7.62, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1004.17, "iaq": 20, "relative_humidity": 68.57, "temperature": 12.23}, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 10427, "long_name": "Silver Wolf", "next_hop": 23, "num": "0x0a277969", "position": {"altitude": 1432, "latitude": 33.347268, "location_source": "LOC_INTERNAL", "longitude": -107.752326, "time_offset_sec": 10447}, "public_key_hex": "", "role": "CLIENT", "short_name": "SB1N", "snr": 2.51, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1485, "long_name": "Silent Falcon", "next_hop": 100, "num": "0x0a526ec8", "position": {"altitude": 1404, "latitude": 32.852863, "location_source": "LOC_INTERNAL", "longitude": -105.833072, "time_offset_sec": 1677}, "public_key_hex": "1b3b314eca34b5eda9bfee5edef66f954a24378efc0ada41cb6865818a18627d", "role": "CLIENT_MUTE", "short_name": "SCXD", "snr": 6.59, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.855, "battery_level": 28, "channel_utilization": 8.74, "uptime_seconds": 162069, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 6351, "long_name": "Sneaky Viper", "next_hop": 0, "num": "0x0a87420a", "position": {"altitude": 2097, "latitude": 33.46946, "location_source": "LOC_INTERNAL", "longitude": -107.854801, "time_offset_sec": 6351}, "public_key_hex": "", "role": "CLIENT", "short_name": "SXGT", "snr": 9.66, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 2668, "long_name": "Slow Raven", "next_hop": 0, "num": "0x0a9785bb", "position": {"altitude": 1168, "latitude": 33.399476, "location_source": "LOC_INTERNAL", "longitude": -107.002506, "time_offset_sec": 2827}, "public_key_hex": "c8f36e0258e1c3c3223010df3176b2ea4e4c4479c49ca206aa7e9e4a7acf6d95", "role": "CLIENT_MUTE", "short_name": "S53U", "snr": 11.62, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.144, "battery_level": 61, "channel_utilization": 2.7, "uptime_seconds": 31838, "voltage": 3.849}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 74, "long_name": "Wild Phoenix", "next_hop": 0, "num": "0x0b377d65", "position": {"altitude": 1535, "latitude": 32.619246, "location_source": "LOC_INTERNAL", "longitude": -107.303937, "time_offset_sec": 216}, "public_key_hex": "8ed086ac62317421d7a9a962c1f79458c7b1ce9c00da0c45037b26dfeb1cd070", "role": "CLIENT", "short_name": "🗻", "snr": 8.49, "status": null, "telemetry": {"air_util_tx": 0.959, "battery_level": 40, "channel_utilization": 16.45, "uptime_seconds": 46826, "voltage": 3.66}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 639, "long_name": "Lone Yucca", "next_hop": 0, "num": "0x0bbac3e3", "position": {"altitude": 1418, "latitude": 32.838025, "location_source": "LOC_INTERNAL", "longitude": -106.952382, "time_offset_sec": 755}, "public_key_hex": "565e3acd1523d5efd9db6717454eb11ad7832e6306d8c769fb6df4f1914ecb11", "role": "TAK_TRACKER", "short_name": "🌵", "snr": 9.57, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.085, "battery_level": 38, "channel_utilization": 13.02, "uptime_seconds": 46809, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 4396, "long_name": "Solar Raven", "next_hop": 0, "num": "0x0cad1877", "position": {"altitude": 1442, "latitude": 33.838306, "location_source": "LOC_INTERNAL", "longitude": -107.31537, "time_offset_sec": 4451}, "public_key_hex": "", "role": "ROUTER_LATE", "short_name": "ST9H", "snr": 10.64, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 6007, "long_name": "Smooth Bison", "next_hop": 225, "num": "0x0cb3920e", "position": {"altitude": 1473, "latitude": 32.799514, "location_source": "LOC_INTERNAL", "longitude": -107.318775, "time_offset_sec": 6032}, "public_key_hex": "135c23e5ef3009668b333313a4ec57f58b74148d90135fddc983d31774ad4c00", "role": "CLIENT", "short_name": "SDEG", "snr": 6.49, "status": null, "telemetry": {"air_util_tx": 0.252, "battery_level": 76, "channel_utilization": 12.26, "uptime_seconds": 1707, "voltage": 3.984}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 3075, "long_name": "Red Adder", "next_hop": 0, "num": "0x0cd3c9b8", "position": {"altitude": 1746, "latitude": 32.398996, "location_source": "LOC_INTERNAL", "longitude": -107.079664, "time_offset_sec": 3102}, "public_key_hex": "d6e909ad875b1afe4e2acca344f4b77a75eb0ac6eab0231ba27cf97a41a6a2e6", "role": "ROUTER_LATE", "short_name": "RKHV", "snr": 9.3, "status": null, "telemetry": {"air_util_tx": 0.092, "battery_level": 54, "channel_utilization": 6.94, "uptime_seconds": 46741, "voltage": 3.786}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 11846, "long_name": "Blue Turtle", "next_hop": 42, "num": "0x0cf6f075", "position": {"altitude": 1599, "latitude": 33.292365, "location_source": "LOC_INTERNAL", "longitude": -106.642067, "time_offset_sec": 11851}, "public_key_hex": "29f0d88c9858804290119564279b259728e09815ba7f953bfbbc0235a3b7ca59", "role": "ROUTER", "short_name": "BE2J", "snr": 3.22, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.103, "battery_level": 30, "channel_utilization": 9.29, "uptime_seconds": 119323, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 12334, "long_name": "Sleepy Badger", "next_hop": 0, "num": "0x0d3ce504", "position": {"altitude": 1333, "latitude": 33.571284, "location_source": "LOC_INTERNAL", "longitude": -107.427147, "time_offset_sec": 12617}, "public_key_hex": "ef30355e2fd16b456d44a21f9b96bc848eed29615dc26abc43e4968a50aae461", "role": "CLIENT", "short_name": "SPED", "snr": 5.13, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 2432, "long_name": "Burning Coyote", "next_hop": 0, "num": "0x0d8ca8ba", "position": null, "public_key_hex": "aa735974126186912e6affeb580aeb2cdd7eaefdbae2844c4df102f11b316e71", "role": "CLIENT", "short_name": "BG4J", "snr": 9.6, "status": null, "telemetry": {"air_util_tx": 0.585, "battery_level": 89, "channel_utilization": 33.07, "uptime_seconds": 48, "voltage": 4.101}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 697, "long_name": "Gold Pine", "next_hop": 0, "num": "0x0dc79902", "position": {"altitude": 1547, "latitude": 33.325688, "location_source": "LOC_INTERNAL", "longitude": -106.36506, "time_offset_sec": 948}, "public_key_hex": "2a23f899fd519cfc08c957b9e8ba17540d56edeba480530a48947799fef05839", "role": "CLIENT", "short_name": "🌵", "snr": 5.6, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 5174, "long_name": "Black Salmon", "next_hop": 0, "num": "0x0df39b49", "position": {"altitude": 1507, "latitude": 33.799625, "location_source": "LOC_INTERNAL", "longitude": -107.081248, "time_offset_sec": 5294}, "public_key_hex": "67046c933ed949ce758a1b4dbe62e1465acdbd08f6610b21ab98606c2ebea11b", "role": "CLIENT", "short_name": "BC24", "snr": 4.36, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1021.75, "iaq": 52, "relative_humidity": 53.83, "temperature": 22.67}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2507, "long_name": "Silver Ridge NM2PJ", "next_hop": 0, "num": "0x0e466af3", "position": {"altitude": 1161, "latitude": 32.844045, "location_source": "LOC_INTERNAL", "longitude": -106.934913, "time_offset_sec": 2662}, "public_key_hex": "3c7c399e35477b4b00daa1a6fbe53a9f867b0d2911654098069329b3651c3f01", "role": "ROUTER", "short_name": "SLVY", "snr": 4.23, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.005, "battery_level": 87, "channel_utilization": 15.46, "uptime_seconds": 63106, "voltage": 4.083}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 1105, "long_name": "Red Adder", "next_hop": 142, "num": "0x0e73347a", "position": {"altitude": 1713, "latitude": 32.128782, "location_source": "LOC_INTERNAL", "longitude": -107.197526, "time_offset_sec": 1241}, "public_key_hex": "fb59e2604d8f8506f13a00e620f3ac7213794c0ec66b9cca1ff18487eba8c3f5", "role": "CLIENT", "short_name": "RZM6", "snr": 11.91, "status": null, "telemetry": {"air_util_tx": 0.899, "battery_level": 34, "channel_utilization": 30.04, "uptime_seconds": 348824, "voltage": 3.606}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 5269, "long_name": "Smooth Squirrel", "next_hop": 0, "num": "0x0e74c170", "position": {"altitude": 1173, "latitude": 33.375622, "location_source": "LOC_INTERNAL", "longitude": -107.383683, "time_offset_sec": 5279}, "public_key_hex": "5d76465b574f6a8605a021ad5297582546fa352876f250cb0e6a43c4f3d99263", "role": "CLIENT", "short_name": "🦌", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 1.626, "battery_level": 101, "channel_utilization": 12.18, "uptime_seconds": 192410, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 7, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 195, "long_name": "Sharp Mustang", "next_hop": 189, "num": "0x0f969f92", "position": {"altitude": 1326, "latitude": 33.071155, "location_source": "LOC_INTERNAL", "longitude": -107.28847, "time_offset_sec": 275}, "public_key_hex": "203b997abe373c62563240a3f88aa604ec0b7f226eaec9d44687c05ee3e099ca", "role": "CLIENT", "short_name": "SCYS", "snr": 3.98, "status": null, "telemetry": {"air_util_tx": 0.509, "battery_level": 88, "channel_utilization": 22.37, "uptime_seconds": 94713, "voltage": 4.092}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 6, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 556, "long_name": "Lost Falcon", "next_hop": 10, "num": "0x1068b9c3", "position": {"altitude": 1639, "latitude": 32.08854, "location_source": "LOC_INTERNAL", "longitude": -107.420525, "time_offset_sec": 835}, "public_key_hex": "403a60ad42e3e05848cda956b3572c2b6d9716487ee0c8ea9f29b03516d095f0", "role": "CLIENT", "short_name": "L2J5", "snr": 12.0, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1012.19, "iaq": 94, "relative_humidity": 74.04, "temperature": 9.55}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2179, "long_name": "Brave Shark", "next_hop": 0, "num": "0x106e1aa9", "position": {"altitude": 1516, "latitude": 33.052381, "location_source": "LOC_INTERNAL", "longitude": -106.368485, "time_offset_sec": 2181}, "public_key_hex": "fe2b739b59a8e775f040b609fddd7c541e43f6e02b7b752e1dc6e4fb5481da32", "role": "CLIENT", "short_name": "BQFR", "snr": 8.56, "status": null, "telemetry": {"air_util_tx": 0.393, "battery_level": 55, "channel_utilization": 12.42, "uptime_seconds": 125558, "voltage": 3.795}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1770, "long_name": "Black Turtle", "next_hop": 0, "num": "0x10fdbb7c", "position": {"altitude": 1120, "latitude": 32.111339, "location_source": "LOC_INTERNAL", "longitude": -107.662349, "time_offset_sec": 2036}, "public_key_hex": "", "role": "CLIENT", "short_name": "🦂", "snr": 7.83, "status": null, "telemetry": {"air_util_tx": 0.72, "battery_level": 79, "channel_utilization": 19.07, "uptime_seconds": 53503, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1021.23, "iaq": 37, "relative_humidity": 78.84, "temperature": 19.85}, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 903, "long_name": "Howling Iguana", "next_hop": 26, "num": "0x114c8d0c", "position": {"altitude": 1474, "latitude": 33.869401, "location_source": "LOC_INTERNAL", "longitude": -108.620133, "time_offset_sec": 1079}, "public_key_hex": "953c0a6d8bf0ac6e8db0c8fd701f51841183ef8fb1ba16b109dc8290411d4549", "role": "CLIENT", "short_name": "HDW4", "snr": 10.98, "status": {"status": "running"}, "telemetry": {"air_util_tx": 2.014, "battery_level": 98, "channel_utilization": 17.04, "uptime_seconds": 38009, "voltage": 4.182}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": {"barometric_pressure": 1017.71, "iaq": 33, "relative_humidity": 62.97, "temperature": 21.51}, "hops_away": 0, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 1820, "long_name": "Wild Eagle", "next_hop": 0, "num": "0x120b19a3", "position": {"altitude": 1391, "latitude": 33.611799, "location_source": "LOC_INTERNAL", "longitude": -107.006216, "time_offset_sec": 1904}, "public_key_hex": "4f7cac84044ada634f60e87e9a63e56ca1cb8a73f76306f0627c8078063c568e", "role": "ROUTER", "short_name": "WPE2", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.756, "battery_level": 97, "channel_utilization": 3.27, "uptime_seconds": 12783, "voltage": 4.173}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": null, "hops_away": 1, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 3752, "long_name": "Red Mole K17PL", "next_hop": 126, "num": "0x12384425", "position": null, "public_key_hex": "a590327c39a8811f4b495c11c1303361da64452685d896d3b6ed9f1adfc060f8", "role": "CLIENT", "short_name": "🐢", "snr": 5.84, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.333, "battery_level": 12, "channel_utilization": 18.99, "uptime_seconds": 53482, "voltage": 3.408}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 6541, "long_name": "Tall Squirrel", "next_hop": 79, "num": "0x126ceb2c", "position": {"altitude": 1375, "latitude": 32.841802, "location_source": "LOC_INTERNAL", "longitude": -107.427944, "time_offset_sec": 6724}, "public_key_hex": "", "role": "CLIENT", "short_name": "TQM3", "snr": 2.55, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1002.98, "iaq": 111, "relative_humidity": 89.08, "temperature": 33.48}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 4162, "long_name": "Steel Turtle", "next_hop": 0, "num": "0x12f76d86", "position": {"altitude": 1208, "latitude": 32.892447, "location_source": "LOC_INTERNAL", "longitude": -107.118326, "time_offset_sec": 4430}, "public_key_hex": "", "role": "CLIENT", "short_name": "S5F4", "snr": 10.89, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.292, "battery_level": 53, "channel_utilization": 12.83, "uptime_seconds": 2678, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "SENSECAP_INDICATOR", "last_heard_offset_sec": 224, "long_name": "Silent Raven", "next_hop": 201, "num": "0x130f2fb7", "position": {"altitude": 1413, "latitude": 32.938113, "location_source": "LOC_INTERNAL", "longitude": -107.179085, "time_offset_sec": 225}, "public_key_hex": "a7efa3ea6ddaa0a40bcc0e12b957c55331369acee2899c0a0d2b8028d2f1e170", "role": "CLIENT", "short_name": "SZWZ", "snr": 6.34, "status": null, "telemetry": {"air_util_tx": 0.329, "battery_level": 79, "channel_utilization": 19.84, "uptime_seconds": 40527, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "WISMESH_TAG", "last_heard_offset_sec": 3447, "long_name": "Whispering Adder", "next_hop": 23, "num": "0x13293edd", "position": {"altitude": 1269, "latitude": 33.452132, "location_source": "LOC_INTERNAL", "longitude": -106.69832, "time_offset_sec": 3648}, "public_key_hex": "f52d28036520d2bcaa71bd4c3cf8705bb41aec203e95eb97240a7d90ff224378", "role": "CLIENT", "short_name": "W53C", "snr": 6.71, "status": {"status": "weak-signal"}, "telemetry": {"air_util_tx": 0.102, "battery_level": 25, "channel_utilization": 9.98, "uptime_seconds": 14375, "voltage": 3.525}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 5126, "long_name": "Shady Crane", "next_hop": 4, "num": "0x13b2ba9f", "position": {"altitude": 1406, "latitude": 32.818484, "location_source": "LOC_INTERNAL", "longitude": -107.401426, "time_offset_sec": 5424}, "public_key_hex": "b9881b3aa54bb216618fcd9667532add5f2de8020a7c9143e7a160145af4f103", "role": "CLIENT", "short_name": "SP0D", "snr": 6.85, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 2395, "long_name": "River Viper", "next_hop": 0, "num": "0x14758ac9", "position": {"altitude": 1254, "latitude": 32.825863, "location_source": "LOC_INTERNAL", "longitude": -107.703222, "time_offset_sec": 2430}, "public_key_hex": "430af60798f22e409d7c4f8fc662539c25cd09c16b5a3e3eb987fc46c0469167", "role": "CLIENT", "short_name": "R3ZD", "snr": 11.9, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 580, "long_name": "Blue Mesa", "next_hop": 155, "num": "0x14a5204d", "position": {"altitude": 1187, "latitude": 33.093378, "location_source": "LOC_INTERNAL", "longitude": -106.854458, "time_offset_sec": 613}, "public_key_hex": "6358368d5865bb7758b9834d3512457be607092ed2e299be69da713780342f33", "role": "CLIENT", "short_name": "BTTY", "snr": 6.51, "status": null, "telemetry": {"air_util_tx": 2.628, "battery_level": 40, "channel_utilization": 22.99, "uptime_seconds": 87527, "voltage": 3.66}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 1003, "long_name": "Old Mamba", "next_hop": 0, "num": "0x1564261a", "position": {"altitude": 1666, "latitude": 33.943138, "location_source": "LOC_INTERNAL", "longitude": -107.171092, "time_offset_sec": 1202}, "public_key_hex": "54240722fd0126e61a3882ec9c403788f496ef6ba21ddabd23d8252013b10059", "role": "CLIENT", "short_name": "OZKL", "snr": 8.48, "status": {"status": "low-batt"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 12975, "long_name": "Whispering Bear", "next_hop": 205, "num": "0x1615bf36", "position": {"altitude": 738, "latitude": 33.554574, "location_source": "LOC_INTERNAL", "longitude": -106.641352, "time_offset_sec": 13150}, "public_key_hex": "7a01f1d9fc0dc8be20d7f267aa9c9abe5d2ed23c5173372b9536c2b8b2397827", "role": "CLIENT", "short_name": "WBL0", "snr": 9.7, "status": null, "telemetry": {"air_util_tx": 0.222, "battery_level": 50, "channel_utilization": 7.5, "uptime_seconds": 23756, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.22, "iaq": 28, "relative_humidity": 73.84, "temperature": 37.27}, "hops_away": 3, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 2565, "long_name": "Gold Yucca", "next_hop": 248, "num": "0x1644d8bc", "position": {"altitude": 1764, "latitude": 32.887885, "location_source": "LOC_INTERNAL", "longitude": -106.298752, "time_offset_sec": 2844}, "public_key_hex": "247e5e5b436da4f5db45db12f0c373deb057d05621ca70d77233b4a279d3b89a", "role": "CLIENT", "short_name": "GL20", "snr": 0.4, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 2941, "long_name": "Tiny Gecko", "next_hop": 0, "num": "0x16b3cb8d", "position": {"altitude": 1348, "latitude": 33.724181, "location_source": "LOC_INTERNAL", "longitude": -107.174284, "time_offset_sec": 2941}, "public_key_hex": "941fd5f96cf769a08fbff7f3215ca75ad0a9b18fdf8cb78dc29cd40bb82d2150", "role": "CLIENT", "short_name": "TO7I", "snr": 7.42, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 871, "long_name": "Steel Trout", "next_hop": 175, "num": "0x1711f35f", "position": null, "public_key_hex": "139c29b1aa2cb64879370ed42b478b94a9af417661a7cc02f8cdec0ad17845fc", "role": "TRACKER", "short_name": "S7DX", "snr": 4.27, "status": null, "telemetry": {"air_util_tx": 0.645, "battery_level": 44, "channel_utilization": 3.4, "uptime_seconds": 160815, "voltage": 3.696}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3326, "long_name": "Red Wolf", "next_hop": 233, "num": "0x177be91b", "position": null, "public_key_hex": "55adf85e42585ebe03f0e32cb630e12472993b9fd0e7052572d843e0eba6d52f", "role": "CLIENT", "short_name": "RHM4", "snr": 0.38, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 1462, "long_name": "New Aspen", "next_hop": 0, "num": "0x17d34d2f", "position": null, "public_key_hex": "bbf436b42ee2abed84219c04516f33a62e5393f50b6b849495bc8c0bbb053cf3", "role": "CLIENT", "short_name": "NHXL", "snr": 4.01, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 4776, "long_name": "River Seal", "next_hop": 33, "num": "0x17f3a94a", "position": {"altitude": 1664, "latitude": 32.860698, "location_source": "LOC_INTERNAL", "longitude": -106.353502, "time_offset_sec": 5072}, "public_key_hex": "316b919aac604507432d927ff4bc7458e3852b85105a918fd3ddfc41549f488f", "role": "CLIENT", "short_name": "R7R3", "snr": 5.17, "status": null, "telemetry": {"air_util_tx": 1.346, "battery_level": 17, "channel_utilization": 4.74, "uptime_seconds": 30218, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": {"barometric_pressure": 1021.6, "iaq": 17, "relative_humidity": 65.68, "temperature": 24.24}, "hops_away": 3, "hw_model": "RAK3401", "last_heard_offset_sec": 350, "long_name": "Hidden Pine", "next_hop": 251, "num": "0x180443f5", "position": {"altitude": 1319, "latitude": 32.404289, "location_source": "LOC_INTERNAL", "longitude": -106.934617, "time_offset_sec": 508}, "public_key_hex": "9fadbb08623c9913b28bd7a458638bdbc6f8f7e31181b9a121ffcde8b20bbc1e", "role": "CLIENT", "short_name": "🦅", "snr": 0.66, "status": null, "telemetry": {"air_util_tx": 0.806, "battery_level": 33, "channel_utilization": 12.19, "uptime_seconds": 95281, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 142, "long_name": "Sleepy Bison", "next_hop": 0, "num": "0x18dd2de3", "position": {"altitude": 1129, "latitude": 33.62816, "location_source": "LOC_INTERNAL", "longitude": -107.024573, "time_offset_sec": 313}, "public_key_hex": "", "role": "ROUTER", "short_name": "SS7V", "snr": 6.53, "status": null, "telemetry": {"air_util_tx": 0.689, "battery_level": 44, "channel_utilization": 2.6, "uptime_seconds": 2877, "voltage": 3.696}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1014.99, "iaq": 73, "relative_humidity": 78.79, "temperature": 28.95}, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 567, "long_name": "Fast Turtle", "next_hop": 0, "num": "0x18ef7a96", "position": null, "public_key_hex": "0ec2598567e0e8cd092b276487781df7399307ff10d12964f08b6f99ee76e68a", "role": "CLIENT", "short_name": "FUHT", "snr": 1.18, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1075, "long_name": "Canyon Coyote", "next_hop": 0, "num": "0x1939a174", "position": {"altitude": 1239, "latitude": 32.965874, "location_source": "LOC_INTERNAL", "longitude": -106.002274, "time_offset_sec": 1084}, "public_key_hex": "bea2d386101b64e5fe16904ee43db809e962b2edc92d583d3bce4cf469c9c770", "role": "CLIENT", "short_name": "C42Q", "snr": 4.07, "status": null, "telemetry": {"air_util_tx": 0.587, "battery_level": 36, "channel_utilization": 29.37, "uptime_seconds": 161621, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 7533, "long_name": "Brave Phoenix", "next_hop": 161, "num": "0x19606048", "position": {"altitude": 1207, "latitude": 32.520481, "location_source": "LOC_INTERNAL", "longitude": -107.707377, "time_offset_sec": 7611}, "public_key_hex": "", "role": "CLIENT", "short_name": "B2EE", "snr": 5.18, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1021.51, "iaq": 81, "relative_humidity": 41.63, "temperature": 18.29}, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 5429, "long_name": "Found Ridge", "next_hop": 95, "num": "0x1967fd5f", "position": {"altitude": 1367, "latitude": 32.374835, "location_source": "LOC_INTERNAL", "longitude": -106.844832, "time_offset_sec": 5572}, "public_key_hex": "1a0dbcfd50865ed35a464d947bebb1364c0ede8ae6fabca77ee2ee5bc7a22db2", "role": "CLIENT", "short_name": "FMOK", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 1.306, "battery_level": 71, "channel_utilization": 22.2, "uptime_seconds": 125119, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1001.64, "iaq": 86, "relative_humidity": 7.71, "temperature": 31.37}, "hops_away": 2, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 1873, "long_name": "Loud Marmot KX8YO", "next_hop": 148, "num": "0x19c898a0", "position": {"altitude": 1783, "latitude": 32.405528, "location_source": "LOC_INTERNAL", "longitude": -107.106416, "time_offset_sec": 2160}, "public_key_hex": "954f20cebbcc2abe846c90d8fd01106873d22cd7aa47dc862c5cc75981a81729", "role": "CLIENT", "short_name": "L7SZ", "snr": 6.87, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.397, "battery_level": 90, "channel_utilization": 14.17, "uptime_seconds": 6055, "voltage": 4.11}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 7996, "long_name": "Hidden Mesa", "next_hop": 0, "num": "0x1a39a908", "position": {"altitude": 1371, "latitude": 32.42213, "location_source": "LOC_INTERNAL", "longitude": -107.093866, "time_offset_sec": 8025}, "public_key_hex": "443b5cca642cee1c46ca97cbcbe87b55a133c2d547d62c5487bc7c3af01bb1a1", "role": "CLIENT", "short_name": "HSZR", "snr": 8.5, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 4, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 5421, "long_name": "Brave Shark", "next_hop": 90, "num": "0x1b56b90e", "position": {"altitude": 1441, "latitude": 32.889426, "location_source": "LOC_INTERNAL", "longitude": -106.537159, "time_offset_sec": 5704}, "public_key_hex": "27480efc8066b57abc0b7b949808894010ef10c105a2e88d289f5d040df21976", "role": "CLIENT", "short_name": "🌊", "snr": 9.72, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.202, "battery_level": 59, "channel_utilization": 23.59, "uptime_seconds": 101999, "voltage": 3.831}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2302, "long_name": "Happy Gecko", "next_hop": 0, "num": "0x1b6bf44c", "position": null, "public_key_hex": "7206286d9afd3155730837948ec0038876c333330cbd131ef96209e7b277d647", "role": "CLIENT", "short_name": "H15N", "snr": 0.62, "status": null, "telemetry": {"air_util_tx": 2.207, "battery_level": 93, "channel_utilization": 1.79, "uptime_seconds": 122358, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 7, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3119, "long_name": "Floating Lion", "next_hop": 202, "num": "0x1b713583", "position": null, "public_key_hex": "1d6bd24a1414da9f59d73703954239bb4b8cc827bae76dbaa09d01ba52452f85", "role": "CLIENT", "short_name": "FTPZ", "snr": 5.03, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.397, "battery_level": 68, "channel_utilization": 8.09, "uptime_seconds": 241505, "voltage": 3.912}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 2382, "long_name": "Short Raven", "next_hop": 0, "num": "0x1c0560ca", "position": {"altitude": 1464, "latitude": 34.21151, "location_source": "LOC_INTERNAL", "longitude": -107.210931, "time_offset_sec": 2445}, "public_key_hex": "dc645a4e861a9fc93aa0bf8005e0684ab7cf2f24058726eb2a214c97d68ca2fb", "role": "CLIENT", "short_name": "🐺", "snr": 11.22, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.24, "battery_level": 38, "channel_utilization": 15.58, "uptime_seconds": 50239, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 5657, "long_name": "Wandering Wolf", "next_hop": 0, "num": "0x1c36dc90", "position": {"altitude": 1147, "latitude": 32.250805, "location_source": "LOC_INTERNAL", "longitude": -106.884952, "time_offset_sec": 5947}, "public_key_hex": "f1d21755ecb8465c3c00f424d40aace7520544dc1102bf2f6ced1eae30989314", "role": "CLIENT", "short_name": "W2SJ", "snr": 8.52, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.01, "battery_level": 45, "channel_utilization": 20.36, "uptime_seconds": 18959, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.6, "iaq": 83, "relative_humidity": 52.43, "temperature": 23.21}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 133, "long_name": "Desert Mesa", "next_hop": 0, "num": "0x1cefe3cb", "position": {"altitude": 1311, "latitude": 33.656763, "location_source": "LOC_INTERNAL", "longitude": -107.626614, "time_offset_sec": 301}, "public_key_hex": "69dc1000761b943914f461621060293f761303807ce4a9178729eda65e9cdcff", "role": "CLIENT", "short_name": "DTI2", "snr": 0.02, "status": {"status": "online"}, "telemetry": {"air_util_tx": 1.621, "battery_level": 16, "channel_utilization": 9.62, "uptime_seconds": 45293, "voltage": 3.444}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 1807, "long_name": "Sunny Hawk", "next_hop": 0, "num": "0x1d722068", "position": {"altitude": 812, "latitude": 32.577717, "location_source": "LOC_INTERNAL", "longitude": -107.408054, "time_offset_sec": 2034}, "public_key_hex": "beabbf8bc9b06cea1c5c4a08c7888084eb3929c37760a670764fd6cadd7295a6", "role": "CLIENT", "short_name": "🦉", "snr": 9.23, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1012.02, "iaq": 63, "relative_humidity": 96.05, "temperature": 20.13}, "hops_away": 1, "hw_model": "TBEAM_1_WATT", "last_heard_offset_sec": 161, "long_name": "Frozen Cedar", "next_hop": 195, "num": "0x1d8163c2", "position": {"altitude": 1238, "latitude": 32.869186, "location_source": "LOC_INTERNAL", "longitude": -107.651904, "time_offset_sec": 416}, "public_key_hex": "91f0e28d288761bdb1f304ebe33f2d5fd7d9df9d44cb6a2f065b8e47e5fc7ac3", "role": "CLIENT", "short_name": "FKIT", "snr": 6.32, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.164, "battery_level": 41, "channel_utilization": 13.01, "uptime_seconds": 43618, "voltage": 3.669}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 6, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 1639, "long_name": "Canyon Owl", "next_hop": 27, "num": "0x1d82b94f", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "C7ZK", "snr": 9.18, "status": null, "telemetry": {"air_util_tx": 1.023, "battery_level": 48, "channel_utilization": 14.43, "uptime_seconds": 38354, "voltage": 3.732}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 4184, "long_name": "Smooth Mole", "next_hop": 0, "num": "0x1daca15d", "position": {"altitude": 1185, "latitude": 33.384658, "location_source": "LOC_INTERNAL", "longitude": -107.289712, "time_offset_sec": 4264}, "public_key_hex": "46921f68b88565974b589cac24f86cfe93ea100dbe7022089f71df082bb333cd", "role": "CLIENT_MUTE", "short_name": "🌙", "snr": 2.51, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1016.77, "iaq": 7, "relative_humidity": 69.95, "temperature": 30.02}, "hops_away": 2, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 9674, "long_name": "Storm Mesa", "next_hop": 225, "num": "0x1de48b4f", "position": {"altitude": 1496, "latitude": 33.354591, "location_source": "LOC_INTERNAL", "longitude": -106.570413, "time_offset_sec": 9772}, "public_key_hex": "8a3610408b8070eb103d779cf5e9d2900d4cb30d84598400cd21a9943b9d7df9", "role": "CLIENT", "short_name": "SY02", "snr": 3.07, "status": {"status": "weak-signal"}, "telemetry": {"air_util_tx": 1.042, "battery_level": 35, "channel_utilization": 43.64, "uptime_seconds": 199707, "voltage": 3.615}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 480, "long_name": "Brave Pike", "next_hop": 0, "num": "0x1e7ed5d4", "position": {"altitude": 798, "latitude": 33.470996, "location_source": "LOC_INTERNAL", "longitude": -107.416067, "time_offset_sec": 550}, "public_key_hex": "bf0171d6339e8eb928b8ba93385a22027a661d1a8b29f7e5984f28e309fd6d34", "role": "CLIENT", "short_name": "B2ZX", "snr": 6.14, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.361, "battery_level": 92, "channel_utilization": 8.47, "uptime_seconds": 190763, "voltage": 4.128}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 2556, "long_name": "Frosty Pine", "next_hop": 0, "num": "0x1ea77801", "position": {"altitude": 1528, "latitude": 32.418991, "location_source": "LOC_INTERNAL", "longitude": -106.093586, "time_offset_sec": 2772}, "public_key_hex": "0dea045571181b0214c5f3e0b31d33f7052cd424ecd71ffe705af811d3b25bcb", "role": "ROUTER", "short_name": "FOSC", "snr": 6.35, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "CROWPANEL", "last_heard_offset_sec": 2235, "long_name": "Lunar Whale", "next_hop": 0, "num": "0x1f6cc1bc", "position": {"altitude": 899, "latitude": 33.411689, "location_source": "LOC_INTERNAL", "longitude": -107.405901, "time_offset_sec": 2430}, "public_key_hex": "2736e197f4f6da0a2ee69c1e3a51ee35629d2867e1d3c34b4227d235b686a81f", "role": "CLIENT", "short_name": "LDSY", "snr": 10.0, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 8864, "long_name": "Loud Marmot", "next_hop": 0, "num": "0x1fdf7664", "position": {"altitude": 1536, "latitude": 33.654204, "location_source": "LOC_INTERNAL", "longitude": -107.187343, "time_offset_sec": 8957}, "public_key_hex": "f010cbc4e81263a439bc4f2716cb167d1714c92abb0a23c491b3602c772d383a", "role": "TAK", "short_name": "🌲", "snr": 6.38, "status": {"status": "low-batt"}, "telemetry": {"air_util_tx": 0.972, "battery_level": 58, "channel_utilization": 19.6, "uptime_seconds": 52550, "voltage": 3.822}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 9543, "long_name": "Smooth Pike", "next_hop": 0, "num": "0x201cbee0", "position": {"altitude": 1348, "latitude": 33.759616, "location_source": "LOC_INTERNAL", "longitude": -106.64923, "time_offset_sec": 9837}, "public_key_hex": "c32890238040eeb56215ef4b8e9e5c101015db7ca36b004f121a43c7ff899822", "role": "CLIENT_HIDDEN", "short_name": "SQK3", "snr": 5.33, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 4229, "long_name": "Shady Colt", "next_hop": 168, "num": "0x206963c3", "position": {"altitude": 1118, "latitude": 33.832162, "location_source": "LOC_INTERNAL", "longitude": -107.073608, "time_offset_sec": 4391}, "public_key_hex": "e1315e6691a0d99979d84e54f6500c2317aaae905fb491f4dc0222f8703aca42", "role": "CLIENT", "short_name": "S3EW", "snr": 8.78, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 12150, "long_name": "Forest Phoenix", "next_hop": 0, "num": "0x218f5088", "position": {"altitude": 1106, "latitude": 32.897549, "location_source": "LOC_INTERNAL", "longitude": -107.531896, "time_offset_sec": 12292}, "public_key_hex": "2d66dd4145234b2b57ea024df39279c239e97431db054756de54678b20f5da93", "role": "SENSOR", "short_name": "FW9Z", "snr": 9.15, "status": null, "telemetry": {"air_util_tx": 0.139, "battery_level": 79, "channel_utilization": 17.85, "uptime_seconds": 124412, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 1604, "long_name": "Sunny Mustang", "next_hop": 0, "num": "0x237435df", "position": {"altitude": 1720, "latitude": 33.689395, "location_source": "LOC_INTERNAL", "longitude": -106.620763, "time_offset_sec": 1795}, "public_key_hex": "de8c3a94d4068daa81f917c544b401537ede4f41ee908cfcfab3b8a7cbb077cf", "role": "CLIENT", "short_name": "SXDZ", "snr": 3.47, "status": null, "telemetry": {"air_util_tx": 0.434, "battery_level": 26, "channel_utilization": 7.32, "uptime_seconds": 78190, "voltage": 3.534}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 1284, "long_name": "Silver Dolphin", "next_hop": 113, "num": "0x23f54207", "position": {"altitude": 866, "latitude": 33.871469, "location_source": "LOC_INTERNAL", "longitude": -107.534801, "time_offset_sec": 1437}, "public_key_hex": "306a6a50b4b716250b255ea086314fc4ce70eb71e959107baa0284f4920f6822", "role": "ROUTER", "short_name": "S2F3", "snr": 8.89, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 759, "long_name": "Mountain Cactus", "next_hop": 0, "num": "0x23f8dd43", "position": {"altitude": 1548, "latitude": 33.293569, "location_source": "LOC_INTERNAL", "longitude": -107.692603, "time_offset_sec": 954}, "public_key_hex": "ad1317a5f42db4e6d4adc9505d7116df9f9a2f3063134627c22e8c42d8d0b861", "role": "CLIENT", "short_name": "MWI3", "snr": 0.4, "status": null, "telemetry": {"air_util_tx": 0.832, "battery_level": 85, "channel_utilization": 3.39, "uptime_seconds": 19402, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 6, "environment": null, "hops_away": 2, "hw_model": "T_DECK", "last_heard_offset_sec": 3147, "long_name": "Floating Cougar", "next_hop": 42, "num": "0x2483da22", "position": {"altitude": 1574, "latitude": 34.618557, "location_source": "LOC_INTERNAL", "longitude": -106.795298, "time_offset_sec": 3366}, "public_key_hex": "70743e0a888a095156f73537ad455490bbd8c3f542ed955a9cb39333730d0a7d", "role": "CLIENT", "short_name": "FXM3", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.507, "battery_level": 63, "channel_utilization": 5.56, "uptime_seconds": 102994, "voltage": 3.867}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 4, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 1063, "long_name": "Silent Seal", "next_hop": 0, "num": "0x2543fee0", "position": null, "public_key_hex": "437a8bf578d601494b638780ceb552c36172d1286d5a73133983be72837575f7", "role": "CLIENT", "short_name": "SO11", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.017, "battery_level": 28, "channel_utilization": 6.46, "uptime_seconds": 17298, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 796, "long_name": "Sunny Crow", "next_hop": 0, "num": "0x2563d10d", "position": {"altitude": 1406, "latitude": 32.882114, "location_source": "LOC_INTERNAL", "longitude": -107.561773, "time_offset_sec": 860}, "public_key_hex": "9239b3f0c406543fd79d7fc60add1f54c6b1dcf6f439976148be084955f2e6cf", "role": "ROUTER", "short_name": "S4BI", "snr": 9.54, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 5393, "long_name": "Sky Cobra", "next_hop": 38, "num": "0x256cfdf9", "position": {"altitude": 1230, "latitude": 33.35275, "location_source": "LOC_INTERNAL", "longitude": -106.720733, "time_offset_sec": 5559}, "public_key_hex": "66abd534d8050bd3a9b5e673958b42dd8be93dcc7b7bb3df3cddd55c54e6ddff", "role": "CLIENT", "short_name": "🦉", "snr": 1.45, "status": null, "telemetry": {"air_util_tx": 0.593, "battery_level": 79, "channel_utilization": 14.33, "uptime_seconds": 30967, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.13, "iaq": 0, "relative_humidity": 66.62, "temperature": 28.28}, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 7681, "long_name": "Found Sage", "next_hop": 8, "num": "0x2947046c", "position": {"altitude": 995, "latitude": 32.620757, "location_source": "LOC_INTERNAL", "longitude": -107.727416, "time_offset_sec": 7747}, "public_key_hex": "", "role": "CLIENT", "short_name": "FX3S", "snr": 9.15, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.41, "iaq": 37, "relative_humidity": 57.37, "temperature": 9.65}, "hops_away": 0, "hw_model": "SENSECAP_INDICATOR", "last_heard_offset_sec": 2786, "long_name": "Stone Cobra", "next_hop": 0, "num": "0x294c2dba", "position": {"altitude": 1400, "latitude": 32.83756, "location_source": "LOC_INTERNAL", "longitude": -107.65565, "time_offset_sec": 2822}, "public_key_hex": "7c0192e6eb7bad02522f3afaeec7e41451816fb5d3c3c96eabc35c66dba69015", "role": "CLIENT_MUTE", "short_name": "SM0Q", "snr": 5.47, "status": null, "telemetry": {"air_util_tx": 0.835, "battery_level": 33, "channel_utilization": 8.37, "uptime_seconds": 48228, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 3855, "long_name": "Wandering Bronco", "next_hop": 0, "num": "0x29ca8824", "position": {"altitude": 1308, "latitude": 32.768325, "location_source": "LOC_INTERNAL", "longitude": -107.304989, "time_offset_sec": 4107}, "public_key_hex": "0e293c8e21f1632490b3bf622b3034f74bb3f48300640d0f085c41e49cdee87f", "role": "CLIENT", "short_name": "WFFI", "snr": 4.79, "status": null, "telemetry": {"air_util_tx": 0.462, "battery_level": 39, "channel_utilization": 2.79, "uptime_seconds": 143329, "voltage": 3.651}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 7594, "long_name": "Happy Juniper", "next_hop": 0, "num": "0x2a38022d", "position": {"altitude": 1602, "latitude": 33.250885, "location_source": "LOC_INTERNAL", "longitude": -107.23156, "time_offset_sec": 7779}, "public_key_hex": "3e1c289337c793db000bbde022cf406494f9d412b35394570ac89f57652fd58d", "role": "CLIENT", "short_name": "HXCF", "snr": 6.13, "status": null, "telemetry": {"air_util_tx": 0.093, "battery_level": 101, "channel_utilization": 11.18, "uptime_seconds": 158807, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 370, "long_name": "Steel Hawk", "next_hop": 83, "num": "0x2a45d990", "position": {"altitude": 1416, "latitude": 32.684826, "location_source": "LOC_INTERNAL", "longitude": -107.454352, "time_offset_sec": 538}, "public_key_hex": "41e079053e96130355138dce101fb501f67a2371b6392ccd446936d4982687cb", "role": "CLIENT", "short_name": "S9DH", "snr": 3.49, "status": null, "telemetry": {"air_util_tx": 1.05, "battery_level": 60, "channel_utilization": 11.14, "uptime_seconds": 103663, "voltage": 3.84}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 5107, "long_name": "Blue Bison", "next_hop": 0, "num": "0x2af49b14", "position": {"altitude": 1731, "latitude": 32.352734, "location_source": "LOC_INTERNAL", "longitude": -107.333148, "time_offset_sec": 5235}, "public_key_hex": "4c6ce116048de8bce3727736799275a78ae798d97a2ac3f8af06c121c05a1681", "role": "TRACKER", "short_name": "B3XZ", "snr": 9.17, "status": null, "telemetry": {"air_util_tx": 0.319, "battery_level": 66, "channel_utilization": 11.87, "uptime_seconds": 25973, "voltage": 3.894}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 8236, "long_name": "Happy Hawk", "next_hop": 0, "num": "0x2b03792b", "position": null, "public_key_hex": "3868199e2f9abe0163cb67380ce20d0c601cbe73763ad6f223a4bfff063cab38", "role": "CLIENT", "short_name": "🌙", "snr": 5.17, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.609, "battery_level": 95, "channel_utilization": 20.61, "uptime_seconds": 72195, "voltage": 4.155}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2541, "long_name": "Smooth Adder", "next_hop": 185, "num": "0x2c7d0593", "position": {"altitude": 1178, "latitude": 32.166593, "location_source": "LOC_INTERNAL", "longitude": -106.773143, "time_offset_sec": 2622}, "public_key_hex": "9a0cb934580a5f33cbcd3de39a9f6ab5012c1889e33fc226dc9f91326d26fd14", "role": "CLIENT", "short_name": "🌲", "snr": 9.33, "status": null, "telemetry": {"air_util_tx": 1.019, "battery_level": 93, "channel_utilization": 6.5, "uptime_seconds": 63099, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 961, "long_name": "Drifting Pike", "next_hop": 0, "num": "0x2d0e8c42", "position": {"altitude": 1532, "latitude": 34.734724, "location_source": "LOC_INTERNAL", "longitude": -107.084259, "time_offset_sec": 1026}, "public_key_hex": "ad3f772db064508f43eb82bb8e958d4d8d4fab3308c5a5d194a696ba2fc12052", "role": "CLIENT", "short_name": "DI45", "snr": 5.8, "status": null, "telemetry": {"air_util_tx": 0.122, "battery_level": 58, "channel_utilization": 14.53, "uptime_seconds": 227656, "voltage": 3.822}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1014.68, "iaq": 14, "relative_humidity": 85.82, "temperature": 22.23}, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 1964, "long_name": "Loud Shark", "next_hop": 0, "num": "0x2e4cc1e6", "position": {"altitude": 1213, "latitude": 34.237167, "location_source": "LOC_INTERNAL", "longitude": -107.199683, "time_offset_sec": 2091}, "public_key_hex": "5c833a6036236e58f63965ce3ab3256b3bc170f31928512f7e1cfabca03a4cbd", "role": "CLIENT", "short_name": "LDFT", "snr": 10.85, "status": null, "telemetry": {"air_util_tx": 0.153, "battery_level": 73, "channel_utilization": 1.07, "uptime_seconds": 132926, "voltage": 3.957}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 126, "long_name": "Red Iguana", "next_hop": 116, "num": "0x2e68f619", "position": {"altitude": 1832, "latitude": 32.923994, "location_source": "LOC_INTERNAL", "longitude": -106.657373, "time_offset_sec": 329}, "public_key_hex": "", "role": "CLIENT", "short_name": "R7ZB", "snr": 4.76, "status": null, "telemetry": {"air_util_tx": 0.338, "battery_level": 24, "channel_utilization": 3.24, "uptime_seconds": 12781, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1006.38, "iaq": 30, "relative_humidity": 39.21, "temperature": 27.25}, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 12488, "long_name": "Misty Stag", "next_hop": 113, "num": "0x2ed4a8e4", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "MS2B", "snr": 0.46, "status": null, "telemetry": {"air_util_tx": 0.209, "battery_level": 73, "channel_utilization": 4.95, "uptime_seconds": 21300, "voltage": 3.957}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 706, "long_name": "Happy Crane", "next_hop": 0, "num": "0x2f190630", "position": {"altitude": 1326, "latitude": 32.193645, "location_source": "LOC_INTERNAL", "longitude": -108.049345, "time_offset_sec": 819}, "public_key_hex": "a3fbfff1a8985ff8dfc323d60115bfa7cf7b900797769c2108ee2aedafaa1280", "role": "CLIENT", "short_name": "H726", "snr": 0.66, "status": null, "telemetry": {"air_util_tx": 0.209, "battery_level": 80, "channel_utilization": 20.01, "uptime_seconds": 393994, "voltage": 4.02}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 358, "long_name": "Silent Mustang K14IJ", "next_hop": 0, "num": "0x2f57c805", "position": {"altitude": 1410, "latitude": 33.695552, "location_source": "LOC_INTERNAL", "longitude": -107.067123, "time_offset_sec": 485}, "public_key_hex": "16d1f52621f47df16b03a20e6523299f5efe1f4f95b7aeb10457858966ed2a82", "role": "CLIENT", "short_name": "SONZ", "snr": 2.78, "status": null, "telemetry": {"air_util_tx": 0.535, "battery_level": 10, "channel_utilization": 16.78, "uptime_seconds": 11456, "voltage": 3.39}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1004.38, "iaq": 29, "relative_humidity": 35.93, "temperature": 35.08}, "hops_away": 1, "hw_model": "XIAO_NRF52_KIT", "last_heard_offset_sec": 228, "long_name": "Wild Bear", "next_hop": 190, "num": "0x2f8120b8", "position": {"altitude": 1569, "latitude": 32.915073, "location_source": "LOC_INTERNAL", "longitude": -107.459333, "time_offset_sec": 339}, "public_key_hex": "1501e8e5e651653894574d21e3af92c8cc152d5f5f2b361a57f1566a27743f4a", "role": "CLIENT", "short_name": "🐢", "snr": 8.88, "status": null, "telemetry": {"air_util_tx": 0.378, "battery_level": 40, "channel_utilization": 19.12, "uptime_seconds": 32255, "voltage": 3.66}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 1841, "long_name": "Sneaky Owl", "next_hop": 155, "num": "0x2fb30c88", "position": null, "public_key_hex": "ed99fa218967e31fed4ff0766c016c3449d50055d1106ad503e8b9e2cdfc2b41", "role": "CLIENT", "short_name": "SGO4", "snr": 0.44, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.131, "battery_level": 96, "channel_utilization": 16.88, "uptime_seconds": 13908, "voltage": 4.164}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4212, "long_name": "Roving Squirrel", "next_hop": 62, "num": "0x2fe8f471", "position": {"altitude": 1083, "latitude": 33.046297, "location_source": "LOC_INTERNAL", "longitude": -107.497098, "time_offset_sec": 4479}, "public_key_hex": "fc5ac53f01bbc0951caf461a2cbf92eee367800881041f132b0d9f5623877728", "role": "CLIENT", "short_name": "RK7N", "snr": 3.45, "status": null, "telemetry": {"air_util_tx": 0.622, "battery_level": 89, "channel_utilization": 5.45, "uptime_seconds": 150733, "voltage": 4.101}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 4401, "long_name": "Sharp Cougar", "next_hop": 83, "num": "0x3117ad36", "position": null, "public_key_hex": "bcfa30fdae164084e2b1cfc1d6e17125c37a50480e57a3679c892fcce5a6168e", "role": "CLIENT", "short_name": "SNGJ", "snr": 9.12, "status": {"status": "online"}, "telemetry": {"air_util_tx": 1.231, "battery_level": 52, "channel_utilization": 21.0, "uptime_seconds": 23937, "voltage": 3.768}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 415, "long_name": "Gold Viper", "next_hop": 127, "num": "0x31bef7f0", "position": {"altitude": 1377, "latitude": 32.021334, "location_source": "LOC_INTERNAL", "longitude": -107.433857, "time_offset_sec": 697}, "public_key_hex": "5823cdb30133a932c4a81c9b454e608d811974d97cb709c70fb10fe5ab8345b9", "role": "CLIENT", "short_name": "G2ZX", "snr": 8.05, "status": null, "telemetry": {"air_util_tx": 0.521, "battery_level": 79, "channel_utilization": 3.1, "uptime_seconds": 216248, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 3129, "long_name": "Iron Lynx", "next_hop": 100, "num": "0x3208623d", "position": {"altitude": 1701, "latitude": 33.189569, "location_source": "LOC_INTERNAL", "longitude": -107.539966, "time_offset_sec": 3383}, "public_key_hex": "892dea76c661963c99ed1f1195d4bea9c6fa5163475b5b35ce9b3a5fda420ec0", "role": "CLIENT_HIDDEN", "short_name": "IWY3", "snr": 9.49, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1096, "long_name": "Steel Doe", "next_hop": 0, "num": "0x322f653a", "position": {"altitude": 1245, "latitude": 32.930805, "location_source": "LOC_INTERNAL", "longitude": -105.812392, "time_offset_sec": 1218}, "public_key_hex": "d75ceb23a3e896da98903cdeb81a6c3b946cfe56199eee9556f836f52c857815", "role": "CLIENT", "short_name": "S78M", "snr": 4.93, "status": null, "telemetry": {"air_util_tx": 0.211, "battery_level": 33, "channel_utilization": 39.3, "uptime_seconds": 98053, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 2228, "long_name": "Brave Salmon", "next_hop": 0, "num": "0x3245221d", "position": {"altitude": 938, "latitude": 32.657217, "location_source": "LOC_INTERNAL", "longitude": -107.920171, "time_offset_sec": 2525}, "public_key_hex": "54d85c0b0ddf309d95b3acdf2d203c2fa39f500256cd6362250d4061d48c3b07", "role": "SENSOR", "short_name": "B4DI", "snr": 1.54, "status": null, "telemetry": {"air_util_tx": 0.182, "battery_level": 19, "channel_utilization": 8.93, "uptime_seconds": 87158, "voltage": 3.471}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 2151, "long_name": "Storm Raven", "next_hop": 0, "num": "0x341f4692", "position": {"altitude": 1618, "latitude": 33.195702, "location_source": "LOC_INTERNAL", "longitude": -108.073506, "time_offset_sec": 2318}, "public_key_hex": "2bbc851a951cefd1b2b48a8b5b55e3263efd3ee5e6a33d131a19740950d46e16", "role": "CLIENT", "short_name": "SOEX", "snr": 12.0, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 2915, "long_name": "Frosty Juniper", "next_hop": 0, "num": "0x345796f1", "position": {"altitude": 1374, "latitude": 33.249679, "location_source": "LOC_INTERNAL", "longitude": -107.230585, "time_offset_sec": 2978}, "public_key_hex": "97c9b6de4acbacfc11b88b0f29c6a37e85bbf4e5c1c0e225b0865d83a2992c16", "role": "CLIENT", "short_name": "🌙", "snr": 6.38, "status": null, "telemetry": {"air_util_tx": 0.502, "battery_level": 71, "channel_utilization": 19.85, "uptime_seconds": 117857, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 0, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 9084, "long_name": "Storm Hawk", "next_hop": 0, "num": "0x34eb1977", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "S0JA", "snr": 1.68, "status": null, "telemetry": {"air_util_tx": 1.081, "battery_level": 50, "channel_utilization": 7.61, "uptime_seconds": 38562, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 1346, "long_name": "Forest Trout", "next_hop": 0, "num": "0x34f751c6", "position": {"altitude": 1326, "latitude": 32.338295, "location_source": "LOC_INTERNAL", "longitude": -107.444579, "time_offset_sec": 1349}, "public_key_hex": "3b2b981eeb23c8feb07890fc4a130978cc01042f49838735eeda90536da89afc", "role": "CLIENT", "short_name": "FTSG", "snr": 5.76, "status": null, "telemetry": {"air_util_tx": 0.426, "battery_level": 27, "channel_utilization": 11.69, "uptime_seconds": 8654, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 3630, "long_name": "Tiny Beaver", "next_hop": 0, "num": "0x350928d2", "position": {"altitude": 1394, "latitude": 33.767341, "location_source": "LOC_INTERNAL", "longitude": -107.072889, "time_offset_sec": 3829}, "public_key_hex": "38ebb2ccc72aa736e8dc5f4d9775bffc50dcb99766b48a972525e0ae84985b1d", "role": "ROUTER", "short_name": "TA4T", "snr": 6.23, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 3, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1205, "long_name": "Storm Crane", "next_hop": 124, "num": "0x35280f4d", "position": {"altitude": 1226, "latitude": 32.43356, "location_source": "LOC_INTERNAL", "longitude": -106.613189, "time_offset_sec": 1366}, "public_key_hex": "587cd2b9f47a6d59abf22ca05d92d521900ce70b27f1054f913d4498b434222e", "role": "CLIENT", "short_name": "SMH0", "snr": 3.07, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "THINKNODE_M6", "last_heard_offset_sec": 822, "long_name": "Roving Otter", "next_hop": 208, "num": "0x35281377", "position": {"altitude": 1321, "latitude": 32.536876, "location_source": "LOC_INTERNAL", "longitude": -108.039779, "time_offset_sec": 1027}, "public_key_hex": "ba0d4fb69c240d9a29dc357e3f5fd9479bd61da30e785c66722de8ef2fcc8c2d", "role": "CLIENT", "short_name": "RS7Q", "snr": -5.92, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.742, "battery_level": 101, "channel_utilization": 7.82, "uptime_seconds": 179764, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1449, "long_name": "Howling Falcon", "next_hop": 198, "num": "0x35eaa098", "position": {"altitude": 1552, "latitude": 33.404432, "location_source": "LOC_INTERNAL", "longitude": -107.924439, "time_offset_sec": 1581}, "public_key_hex": "a1fc3b0d9893f1242bea61d384ac9165cc0766cbd3a48f3ccd6a18ee6f812319", "role": "CLIENT_HIDDEN", "short_name": "HJ3F", "snr": 5.04, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 372, "long_name": "Tiny Elk", "next_hop": 0, "num": "0x35f0cc39", "position": {"altitude": 1427, "latitude": 33.290895, "location_source": "LOC_INTERNAL", "longitude": -107.201106, "time_offset_sec": 499}, "public_key_hex": "330a4052ea490328a3956becda9a08acdcfbc16bc0478a07cef222b5a30daafd", "role": "CLIENT", "short_name": "TE54", "snr": 9.56, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.597, "battery_level": 28, "channel_utilization": 4.76, "uptime_seconds": 31339, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 1101, "long_name": "Sunny Gecko", "next_hop": 116, "num": "0x3619ed0e", "position": {"altitude": 1985, "latitude": 33.257677, "location_source": "LOC_INTERNAL", "longitude": -107.385914, "time_offset_sec": 1362}, "public_key_hex": "757f839679e19f0949429e4df3ac104d6868cb752fe529ea4723c49d2e3f0845", "role": "CLIENT", "short_name": "🐢", "snr": 7.04, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 1366, "long_name": "Sleepy Colt", "next_hop": 0, "num": "0x379a7f4b", "position": {"altitude": 1482, "latitude": 33.010008, "location_source": "LOC_INTERNAL", "longitude": -108.104341, "time_offset_sec": 1645}, "public_key_hex": "d7e6c8d58e00e128529228bca8331472cefe3b6ade499a4229579e44a06a9909", "role": "CLIENT", "short_name": "SBJW", "snr": 6.5, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1012.41, "iaq": 52, "relative_humidity": 47.13, "temperature": 29.47}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4284, "long_name": "Sky Falcon", "next_hop": 0, "num": "0x37b90b2e", "position": {"altitude": 1498, "latitude": 32.135808, "location_source": "LOC_INTERNAL", "longitude": -106.657873, "time_offset_sec": 4402}, "public_key_hex": "9ee39d5af7fec89de02a3ce7d48b9ad82bb218d75d9324ff74eb317cab8aaf60", "role": "CLIENT", "short_name": "S9D7", "snr": 7.46, "status": null, "telemetry": {"air_util_tx": 0.463, "battery_level": 33, "channel_utilization": 16.68, "uptime_seconds": 196876, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.65, "iaq": 36, "relative_humidity": 46.5, "temperature": 23.13}, "hops_away": 3, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1643, "long_name": "Brave Owl", "next_hop": 85, "num": "0x37dccaab", "position": null, "public_key_hex": "ce6a097bf64b3b2f149276d389a0aaf54c3c62b3822b4dd57cad98049d85f645", "role": "CLIENT", "short_name": "B8MT", "snr": 5.19, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.454, "battery_level": 85, "channel_utilization": 22.66, "uptime_seconds": 261777, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1240, "long_name": "Silver Badger", "next_hop": 0, "num": "0x38ba7d6c", "position": null, "public_key_hex": "b735a5154885ba6bef03bd47d559b3d20e3c3a0ae4e3fa77fd70ffd623bd7a4b", "role": "CLIENT", "short_name": "SZTG", "snr": 1.95, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 4, "hw_model": "RAK4631", "last_heard_offset_sec": 1066, "long_name": "Wandering Bronco", "next_hop": 145, "num": "0x38e31b4f", "position": {"altitude": 1172, "latitude": 32.504572, "location_source": "LOC_INTERNAL", "longitude": -106.301649, "time_offset_sec": 1177}, "public_key_hex": "70d05e317b534b7d3818add161f43ca366cdee3abee2f7587393217af8e3e7da", "role": "CLIENT", "short_name": "WICA", "snr": 6.52, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "RAK4631", "last_heard_offset_sec": 1995, "long_name": "Lunar Bronco", "next_hop": 130, "num": "0x3a48853f", "position": {"altitude": 1400, "latitude": 33.976144, "location_source": "LOC_INTERNAL", "longitude": -107.015442, "time_offset_sec": 1996}, "public_key_hex": "e7b6c54f0d2b8d129baad7ad2370629dd0a8a969799b4edad53b28c5d70a137a", "role": "CLIENT", "short_name": "LW2P", "snr": 2.96, "status": null, "telemetry": {"air_util_tx": 1.042, "battery_level": 101, "channel_utilization": 8.36, "uptime_seconds": 170554, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3738, "long_name": "Drifting Mamba", "next_hop": 0, "num": "0x3a7a9d31", "position": {"altitude": 1324, "latitude": 32.805193, "location_source": "LOC_INTERNAL", "longitude": -107.892675, "time_offset_sec": 3975}, "public_key_hex": "8792509c722d7ce22641ad6eeaf4d49c0990d572a660c8a9b4866ad818e99518", "role": "CLIENT_MUTE", "short_name": "DXZL", "snr": 5.37, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.616, "battery_level": 52, "channel_utilization": 13.15, "uptime_seconds": 19131, "voltage": 3.768}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 694, "long_name": "Bright Pony", "next_hop": 0, "num": "0x3a9ebc7a", "position": {"altitude": 1679, "latitude": 33.197556, "location_source": "LOC_INTERNAL", "longitude": -107.739604, "time_offset_sec": 705}, "public_key_hex": "bcf5471fc71cf14cda41b23fb2bdbe2a0ad0d9545130faabcb8868094d58ed6d", "role": "TAK_TRACKER", "short_name": "BPWE", "snr": 10.59, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.494, "battery_level": 86, "channel_utilization": 15.79, "uptime_seconds": 5144, "voltage": 4.074}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 6627, "long_name": "Roving Shark", "next_hop": 0, "num": "0x3c626203", "position": {"altitude": 1389, "latitude": 32.858857, "location_source": "LOC_INTERNAL", "longitude": -107.351624, "time_offset_sec": 6770}, "public_key_hex": "425316a371780a5d7cd4c0f286e8c2ca392ed59eb2ee7164282b4f000fd8c98d", "role": "CLIENT", "short_name": "RBC5", "snr": 7.03, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 3404, "long_name": "Quick Falcon", "next_hop": 0, "num": "0x3cd1fc8b", "position": {"altitude": 1465, "latitude": 32.944934, "location_source": "LOC_INTERNAL", "longitude": -107.49285, "time_offset_sec": 3444}, "public_key_hex": "", "role": "CLIENT", "short_name": "QLVF", "snr": 12.0, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.122, "battery_level": 33, "channel_utilization": 5.63, "uptime_seconds": 104974, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 3961, "long_name": "Frozen Bronco", "next_hop": 0, "num": "0x3d841286", "position": null, "public_key_hex": "4808b539f3d118bcf2ed4b9b90d28b11ef7b8840e0e9edd5cc7706b51c906125", "role": "CLIENT", "short_name": "FFER", "snr": 6.24, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.634, "battery_level": 20, "channel_utilization": 17.12, "uptime_seconds": 7949, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4991, "long_name": "Lone Coyote", "next_hop": 0, "num": "0x3f08ef02", "position": {"altitude": 1232, "latitude": 33.103679, "location_source": "LOC_INTERNAL", "longitude": -106.900331, "time_offset_sec": 5175}, "public_key_hex": "6525d25dc21d4b76bd54da497bad80a83f0e5491756a1a0344a479f39eb0ba71", "role": "CLIENT", "short_name": "LLVT", "snr": 7.79, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 3286, "long_name": "Iron Viper", "next_hop": 0, "num": "0x3f677662", "position": {"altitude": 1848, "latitude": 33.278539, "location_source": "LOC_INTERNAL", "longitude": -108.310349, "time_offset_sec": 3409}, "public_key_hex": "c413d2c51a6764b0589503e1bda72c9840f3fd0d5687e0b5df6dc04640b662c7", "role": "CLIENT", "short_name": "I0D3", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.179, "battery_level": 22, "channel_utilization": 8.54, "uptime_seconds": 220137, "voltage": 3.498}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAG", "last_heard_offset_sec": 5466, "long_name": "Black Lynx AB8ET", "next_hop": 0, "num": "0x3f7ea7eb", "position": {"altitude": 1676, "latitude": 32.76055, "location_source": "LOC_INTERNAL", "longitude": -106.901877, "time_offset_sec": 5692}, "public_key_hex": "f7e96bc6a9e0214c7e3fda88b27f4969e291adce95396869c42ec77126587cd9", "role": "CLIENT", "short_name": "BBUC", "snr": 9.53, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 1.233, "battery_level": 101, "channel_utilization": 6.48, "uptime_seconds": 36311, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.36, "iaq": 44, "relative_humidity": 72.23, "temperature": 20.48}, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 2354, "long_name": "Dawn Tortoise", "next_hop": 153, "num": "0x3fc5bdc2", "position": null, "public_key_hex": "fda1f9f1e8ed7a0c5b37bff3d18c5d15aaf72b17e03e2248c7565785671247eb", "role": "CLIENT", "short_name": "DETB", "snr": 6.68, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 231, "long_name": "Silver Bass", "next_hop": 7, "num": "0x3ff95e93", "position": {"altitude": 1203, "latitude": 32.849007, "location_source": "LOC_INTERNAL", "longitude": -108.197204, "time_offset_sec": 521}, "public_key_hex": "849a63f901ce989581c4939d4fc3ad466203b6a02c1638a8fa8a5e504b21f96e", "role": "CLIENT", "short_name": "SENN", "snr": 4.24, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.876, "battery_level": 20, "channel_utilization": 2.39, "uptime_seconds": 179024, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.48, "iaq": 0, "relative_humidity": 16.24, "temperature": 34.19}, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 8035, "long_name": "Mountain Trout", "next_hop": 184, "num": "0x417a5306", "position": {"altitude": 1503, "latitude": 33.624464, "location_source": "LOC_INTERNAL", "longitude": -106.72661, "time_offset_sec": 8119}, "public_key_hex": "35de117ffe9f5589301f410d8b721a21e7fc4e3a2893eaac77fdf74d3afd98c9", "role": "CLIENT", "short_name": "M97I", "snr": 9.69, "status": {"status": "no-gps"}, "telemetry": {"air_util_tx": 0.781, "battery_level": 85, "channel_utilization": 7.93, "uptime_seconds": 84523, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.45, "iaq": 97, "relative_humidity": 43.82, "temperature": 7.08}, "hops_away": 0, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 1671, "long_name": "Howling Falcon", "next_hop": 0, "num": "0x41840415", "position": {"altitude": 1497, "latitude": 32.148268, "location_source": "LOC_INTERNAL", "longitude": -107.216316, "time_offset_sec": 1867}, "public_key_hex": "c6dd6006e0a5c8161af6a399b638f234a6a9a1aa4cc49f88a86a05598d6f0b82", "role": "CLIENT", "short_name": "HKBX", "snr": 12.0, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "T_DECK", "last_heard_offset_sec": 2561, "long_name": "Happy Iguana", "next_hop": 112, "num": "0x41e5b63a", "position": {"altitude": 1296, "latitude": 32.452598, "location_source": "LOC_INTERNAL", "longitude": -106.65747, "time_offset_sec": 2656}, "public_key_hex": "e40bef49256a922269b637c229b4cbfec4bcb93111fc93df36d58c28235c60d0", "role": "CLIENT", "short_name": "HCQ1", "snr": 6.42, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 378, "long_name": "Sleepy Pony", "next_hop": 110, "num": "0x42827046", "position": {"altitude": 1571, "latitude": 33.761147, "location_source": "LOC_INTERNAL", "longitude": -108.038104, "time_offset_sec": 493}, "public_key_hex": "8675ad01e7bef086d31a9de38cabe2990be1c1fbe6c9070b1114f22fc1c3ab9b", "role": "CLIENT", "short_name": "SZQ4", "snr": 8.86, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.245, "battery_level": 30, "channel_utilization": 2.76, "uptime_seconds": 32001, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1004.27, "iaq": 64, "relative_humidity": 67.28, "temperature": 23.25}, "hops_away": 1, "hw_model": "SENSECAP_INDICATOR", "last_heard_offset_sec": 7780, "long_name": "Smooth Heron", "next_hop": 149, "num": "0x43098402", "position": {"altitude": 1709, "latitude": 33.548948, "location_source": "LOC_INTERNAL", "longitude": -107.227654, "time_offset_sec": 7782}, "public_key_hex": "30bbdb755f48cb79b58ab77c854d4ee8ba5d74bb8be93c3abfe8f2a0cb765ec6", "role": "CLIENT", "short_name": "SJ03", "snr": 7.38, "status": null, "telemetry": {"air_util_tx": 0.942, "battery_level": 66, "channel_utilization": 9.03, "uptime_seconds": 51036, "voltage": 3.894}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 396, "long_name": "Steel Bronco", "next_hop": 0, "num": "0x435d2911", "position": {"altitude": 1673, "latitude": 32.580277, "location_source": "LOC_INTERNAL", "longitude": -106.975968, "time_offset_sec": 564}, "public_key_hex": "72d1139e64da66ab88fe4509ef2fafd974b1ffaca6011c2e3bd45001adf39435", "role": "CLIENT", "short_name": "S1YB", "snr": 2.23, "status": null, "telemetry": {"air_util_tx": 2.157, "battery_level": 74, "channel_utilization": 5.14, "uptime_seconds": 164568, "voltage": 3.966}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 835, "long_name": "Howling Dolphin", "next_hop": 0, "num": "0x43eb37a7", "position": {"altitude": 1020, "latitude": 32.758911, "location_source": "LOC_INTERNAL", "longitude": -107.320715, "time_offset_sec": 1086}, "public_key_hex": "095341f06bac766786c813771f272925637b520d163e44d0683a156ef98722b2", "role": "CLIENT", "short_name": "HT3M", "snr": 2.25, "status": null, "telemetry": {"air_util_tx": 1.207, "battery_level": 30, "channel_utilization": 23.12, "uptime_seconds": 49884, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 362, "long_name": "Copper Falcon", "next_hop": 0, "num": "0x447c1421", "position": {"altitude": 1398, "latitude": 33.482628, "location_source": "LOC_INTERNAL", "longitude": -106.782732, "time_offset_sec": 501}, "public_key_hex": "b51c82595a0ba524f559479ce0ca39f6a7b5dbcd9f1c8342021a6b666d4bb598", "role": "CLIENT", "short_name": "🌙", "snr": 9.3, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.389, "battery_level": 100, "channel_utilization": 13.31, "uptime_seconds": 164327, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 2034, "long_name": "Storm Hare", "next_hop": 212, "num": "0x455852df", "position": {"altitude": 1411, "latitude": 33.160165, "location_source": "LOC_INTERNAL", "longitude": -106.978518, "time_offset_sec": 2200}, "public_key_hex": "663033cb89273d29f0fd905dc9133b81196d6ae87bac26f5753bfb131854db42", "role": "CLIENT", "short_name": "S7JT", "snr": 5.06, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1006.1, "iaq": 59, "relative_humidity": 46.21, "temperature": 20.36}, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 1003, "long_name": "Green Dolphin", "next_hop": 0, "num": "0x465af007", "position": null, "public_key_hex": "e78e261f75aafb55d6bbba0e9edd7cc11badfae3eb4186beb779c5dcb3255cd8", "role": "CLIENT", "short_name": "GI2G", "snr": 1.93, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 418, "long_name": "Brave Heron", "next_hop": 0, "num": "0x48134994", "position": {"altitude": 1581, "latitude": 33.071357, "location_source": "LOC_INTERNAL", "longitude": -108.099084, "time_offset_sec": 565}, "public_key_hex": "76a6ad472a5cff57ed41eb49c1816811c240fad47b9af833300228d122aa18f5", "role": "CLIENT_HIDDEN", "short_name": "BWKH", "snr": 6.59, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.187, "battery_level": 23, "channel_utilization": 2.78, "uptime_seconds": 34162, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1008.42, "iaq": 61, "relative_humidity": 55.86, "temperature": 1.38}, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 4712, "long_name": "Tall Bear", "next_hop": 0, "num": "0x48bda4f9", "position": {"altitude": 1327, "latitude": 31.889102, "location_source": "LOC_INTERNAL", "longitude": -107.933255, "time_offset_sec": 4967}, "public_key_hex": "3aa01e4ffd3b8b7e47642303a170636cb7de191e004e122ad7e7675eef2fda6f", "role": "CLIENT", "short_name": "TFGL", "snr": -1.71, "status": null, "telemetry": {"air_util_tx": 0.461, "battery_level": 83, "channel_utilization": 18.67, "uptime_seconds": 100258, "voltage": 4.047}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 258, "long_name": "White Bison", "next_hop": 0, "num": "0x48d0b194", "position": {"altitude": 1459, "latitude": 33.782262, "location_source": "LOC_INTERNAL", "longitude": -107.509689, "time_offset_sec": 295}, "public_key_hex": "49e0f1b4d280f33198462cc127e555a1b22c6114145d18e9a14299511b230d9c", "role": "CLIENT_MUTE", "short_name": "WG10", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 1.751, "battery_level": 100, "channel_utilization": 26.99, "uptime_seconds": 7542, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1003.81, "iaq": 124, "relative_humidity": 93.64, "temperature": 27.01}, "hops_away": 0, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 868, "long_name": "Found Bluff", "next_hop": 0, "num": "0x49e59f8b", "position": {"altitude": 1285, "latitude": 32.324249, "location_source": "LOC_INTERNAL", "longitude": -106.922861, "time_offset_sec": 1022}, "public_key_hex": "7d26af47afa14a475a43c0d3729ae78c06b25eb4c510e7a9b2a20a0480531dc5", "role": "CLIENT", "short_name": "F62Q", "snr": 2.03, "status": null, "telemetry": {"air_util_tx": 0.093, "battery_level": 36, "channel_utilization": 11.36, "uptime_seconds": 18990, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.75, "iaq": 34, "relative_humidity": 36.1, "temperature": 27.18}, "hops_away": 1, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 5593, "long_name": "Blue Bronco", "next_hop": 203, "num": "0x4a07175b", "position": null, "public_key_hex": "ffcf68b0815970081d634563ff83bde989bcb1f9cd5d61f6d6cc3d2ff1fad152", "role": "CLIENT", "short_name": "🌙", "snr": 10.77, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.56, "battery_level": 66, "channel_utilization": 11.41, "uptime_seconds": 19830, "voltage": 3.894}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 1260, "long_name": "Frozen Cobra", "next_hop": 23, "num": "0x4a440efd", "position": {"altitude": 1458, "latitude": 33.287147, "location_source": "LOC_INTERNAL", "longitude": -107.423088, "time_offset_sec": 1271}, "public_key_hex": "d2b9da3fa597cad62300e868e5f3f9f5bcbf470d4de800b67d21d752cca5b033", "role": "CLIENT", "short_name": "FJJK", "snr": 4.15, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 3201, "long_name": "Frosty Whale", "next_hop": 30, "num": "0x4a65ed60", "position": {"altitude": 1440, "latitude": 33.617218, "location_source": "LOC_INTERNAL", "longitude": -107.490683, "time_offset_sec": 3323}, "public_key_hex": "2a54ca7e0ca678ad6c80cf14e49ea9d04fe0d7197e281125800c6d8a78dcfb15", "role": "CLIENT", "short_name": "🌙", "snr": 12.0, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 4077, "long_name": "White Oak KQ6JZ", "next_hop": 0, "num": "0x4ab70ba8", "position": {"altitude": 1469, "latitude": 33.384405, "location_source": "LOC_INTERNAL", "longitude": -107.365826, "time_offset_sec": 4124}, "public_key_hex": "95d3ff7660fc0f84136aa457178490c7a80c8a442696b77490b14ce708bf6343", "role": "ROUTER", "short_name": "WCCR", "snr": 2.33, "status": null, "telemetry": {"air_util_tx": 0.23, "battery_level": 27, "channel_utilization": 13.09, "uptime_seconds": 58027, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": {"barometric_pressure": 1016.03, "iaq": 54, "relative_humidity": 67.96, "temperature": 16.03}, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 2928, "long_name": "Tiny Mamba", "next_hop": 235, "num": "0x4aedcfb7", "position": {"altitude": 1754, "latitude": 34.012849, "location_source": "LOC_INTERNAL", "longitude": -106.947321, "time_offset_sec": 3160}, "public_key_hex": "12890fb733850d94ded99326d5675cfddc5d9a133082a749fc56db0de5ec6fac", "role": "SENSOR", "short_name": "TQNJ", "snr": 4.78, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.222, "battery_level": 97, "channel_utilization": 13.6, "uptime_seconds": 47867, "voltage": 4.173}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": {"barometric_pressure": 1012.81, "iaq": 28, "relative_humidity": 40.75, "temperature": 8.84}, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 1916, "long_name": "Dawn Trout", "next_hop": 52, "num": "0x4d187e0c", "position": {"altitude": 1222, "latitude": 33.05008, "location_source": "LOC_INTERNAL", "longitude": -108.01885, "time_offset_sec": 1924}, "public_key_hex": "813f81fd4523b85fc3cf532d515c7c26d17cec31ffac8c79ffb47f4acc1e4974", "role": "CLIENT", "short_name": "D9JM", "snr": 2.33, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.038, "battery_level": 73, "channel_utilization": 8.21, "uptime_seconds": 49948, "voltage": 3.957}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2519, "long_name": "Quick Viper", "next_hop": 53, "num": "0x4d58a77a", "position": {"altitude": 1692, "latitude": 33.217413, "location_source": "LOC_INTERNAL", "longitude": -105.91945, "time_offset_sec": 2662}, "public_key_hex": "", "role": "CLIENT", "short_name": "QVG4", "snr": 9.9, "status": null, "telemetry": {"air_util_tx": 1.169, "battery_level": 80, "channel_utilization": 7.86, "uptime_seconds": 8886, "voltage": 4.02}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 956, "long_name": "Forest Elk", "next_hop": 0, "num": "0x4de415a9", "position": {"altitude": 1312, "latitude": 33.522763, "location_source": "LOC_INTERNAL", "longitude": -107.09793, "time_offset_sec": 1044}, "public_key_hex": "13ec2f9813b533355170fb10f7b9edf6968cfa202f05c239991f510b95c8c407", "role": "CLIENT", "short_name": "FXPV", "snr": 7.91, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1005.22, "iaq": 75, "relative_humidity": 59.03, "temperature": 13.82}, "hops_away": 1, "hw_model": "RAK3401", "last_heard_offset_sec": 7379, "long_name": "Giant Iguana", "next_hop": 182, "num": "0x4dfe4aca", "position": {"altitude": 1564, "latitude": 33.87132, "location_source": "LOC_INTERNAL", "longitude": -107.840595, "time_offset_sec": 7664}, "public_key_hex": "", "role": "CLIENT", "short_name": "GZ9E", "snr": 4.22, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.223, "battery_level": 17, "channel_utilization": 11.34, "uptime_seconds": 59951, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1002.46, "iaq": 82, "relative_humidity": 100.0, "temperature": 13.55}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 3541, "long_name": "Frosty Otter", "next_hop": 0, "num": "0x4eb45c1b", "position": {"altitude": 1558, "latitude": 33.765757, "location_source": "LOC_INTERNAL", "longitude": -107.524716, "time_offset_sec": 3795}, "public_key_hex": "51b4aa27f341a7fec39219763ac33a36632089e7791650baeaa6c3bd7667cb8b", "role": "CLIENT", "short_name": "FMHL", "snr": 2.7, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 2403, "long_name": "Canyon Pike", "next_hop": 0, "num": "0x4f25ffaf", "position": {"altitude": 978, "latitude": 33.295073, "location_source": "LOC_INTERNAL", "longitude": -107.935912, "time_offset_sec": 2565}, "public_key_hex": "21f12d839251e7f55a50977347c0af93868e95069eab8a009570663787d55725", "role": "CLIENT", "short_name": "CHTT", "snr": 5.71, "status": null, "telemetry": {"air_util_tx": 0.173, "battery_level": 32, "channel_utilization": 19.04, "uptime_seconds": 37771, "voltage": 3.588}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 1444, "long_name": "Howling Tortoise W52LP", "next_hop": 0, "num": "0x4fdbfa4e", "position": {"altitude": 1521, "latitude": 31.835226, "location_source": "LOC_INTERNAL", "longitude": -107.13257, "time_offset_sec": 1486}, "public_key_hex": "d473b075d25507367010facf4b34a5c144d239bc76506eee18143557850e5262", "role": "CLIENT", "short_name": "H19L", "snr": 0.59, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3414, "long_name": "Found Aspen", "next_hop": 0, "num": "0x52ed71ee", "position": {"altitude": 1309, "latitude": 33.404487, "location_source": "LOC_INTERNAL", "longitude": -107.502565, "time_offset_sec": 3426}, "public_key_hex": "", "role": "CLIENT", "short_name": "FJ4E", "snr": 12.0, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 716, "long_name": "River Crane", "next_hop": 0, "num": "0x54feae48", "position": {"altitude": 1529, "latitude": 32.829459, "location_source": "LOC_INTERNAL", "longitude": -107.885714, "time_offset_sec": 764}, "public_key_hex": "775ebe272d85d4cf4aedf637cffff0cc46855f0be5f3bde6955c223b122b9efa", "role": "CLIENT", "short_name": "ROMG", "snr": 5.32, "status": null, "telemetry": {"air_util_tx": 1.047, "battery_level": 63, "channel_utilization": 15.17, "uptime_seconds": 73126, "voltage": 3.867}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "NOMADSTAR_METEOR_PRO", "last_heard_offset_sec": 4286, "long_name": "White Adder", "next_hop": 155, "num": "0x5542b82e", "position": {"altitude": 1199, "latitude": 33.325201, "location_source": "LOC_INTERNAL", "longitude": -107.359853, "time_offset_sec": 4325}, "public_key_hex": "23e55c5b94a22177bd6b7b480e5e9a2a781366259e03d169fd5af83b17572937", "role": "CLIENT", "short_name": "WFIS", "snr": 7.24, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 8886, "long_name": "Roving Shark", "next_hop": 0, "num": "0x556fe77a", "position": null, "public_key_hex": "200a37f6b73e3c525cd6cc8cad5af856428c4234d491ab404754739e93f4eca8", "role": "CLIENT", "short_name": "RJKM", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 1.168, "battery_level": 79, "channel_utilization": 7.74, "uptime_seconds": 64718, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 476, "long_name": "Lost Adder", "next_hop": 23, "num": "0x55daf3c7", "position": {"altitude": 1141, "latitude": 33.477638, "location_source": "LOC_INTERNAL", "longitude": -107.152887, "time_offset_sec": 670}, "public_key_hex": "63867a7544c551fc3e97436e9a2c9a4e0d508ee5d43367b9441108835c23c0de", "role": "CLIENT", "short_name": "LGUR", "snr": 3.8, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 2083, "long_name": "Sunny Aspen", "next_hop": 40, "num": "0x560289a0", "position": null, "public_key_hex": "758c818600d3dcf61e33702311a7e78d8d5ff3a5c2c0a0cc281537b0c32aa9d4", "role": "CLIENT", "short_name": "SC6I", "snr": 6.55, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.365, "battery_level": 90, "channel_utilization": 12.33, "uptime_seconds": 171767, "voltage": 4.11}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 1, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 241, "long_name": "Wandering Bear", "next_hop": 125, "num": "0x5614cdff", "position": {"altitude": 1380, "latitude": 33.963666, "location_source": "LOC_INTERNAL", "longitude": -108.530761, "time_offset_sec": 390}, "public_key_hex": "e7b26726240c6b8b457842831bcb1a82dd1e69215644d1e0adbae406bcc95010", "role": "ROUTER", "short_name": "WIMK", "snr": -1.84, "status": null, "telemetry": {"air_util_tx": 0.547, "battery_level": 46, "channel_utilization": 1.46, "uptime_seconds": 163671, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 7032, "long_name": "Sneaky Aspen", "next_hop": 94, "num": "0x561cfd98", "position": {"altitude": 1380, "latitude": 33.055831, "location_source": "LOC_INTERNAL", "longitude": -107.450441, "time_offset_sec": 7189}, "public_key_hex": "3a0f320e86669da351f6ba7b62df332050d30bc8b37332d1ef9c841a85d265e1", "role": "CLIENT", "short_name": "SSKN", "snr": 9.77, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 6234, "long_name": "Drowsy Whale", "next_hop": 245, "num": "0x56e1cb9d", "position": {"altitude": 1750, "latitude": 33.794131, "location_source": "LOC_INTERNAL", "longitude": -107.239442, "time_offset_sec": 6447}, "public_key_hex": "db63270d2c6cf45ef9f76f16bccbf17c1a07329fc5cceeec58924383e673b40b", "role": "CLIENT", "short_name": "DYTA", "snr": 9.73, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 8604, "long_name": "Tiny Doe", "next_hop": 0, "num": "0x575f0d95", "position": {"altitude": 1546, "latitude": 33.873224, "location_source": "LOC_INTERNAL", "longitude": -107.630514, "time_offset_sec": 8652}, "public_key_hex": "8f933aa44310ebcc8e988f2b180e3aad23fa7a8554b4762b9c645d3b833b6358", "role": "SENSOR", "short_name": "TIH4", "snr": 10.42, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.062, "battery_level": 21, "channel_utilization": 5.18, "uptime_seconds": 8818, "voltage": 3.489}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 349, "long_name": "Frosty Bear", "next_hop": 0, "num": "0x57c19004", "position": null, "public_key_hex": "", "role": "ROUTER", "short_name": "🌵", "snr": 6.04, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 601, "long_name": "Dusk Adder", "next_hop": 207, "num": "0x57e60523", "position": {"altitude": 1549, "latitude": 32.829103, "location_source": "LOC_INTERNAL", "longitude": -107.560567, "time_offset_sec": 830}, "public_key_hex": "56c6eb6548952819973855d9771675bd6b7d558d4a2266016e31d5737e792c07", "role": "CLIENT_MUTE", "short_name": "DDM3", "snr": 9.71, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.036, "battery_level": 28, "channel_utilization": 10.8, "uptime_seconds": 259221, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1013.6, "iaq": 84, "relative_humidity": 27.27, "temperature": 13.97}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1478, "long_name": "Dawn Turtle", "next_hop": 0, "num": "0x5896a943", "position": {"altitude": 1167, "latitude": 33.168007, "location_source": "LOC_INTERNAL", "longitude": -107.364102, "time_offset_sec": 1491}, "public_key_hex": "d0b326bc3c6cb2bf029fae9c194080c65224a09371d2c69be954d4198f039f89", "role": "CLIENT", "short_name": "DHR5", "snr": 6.29, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1012.44, "iaq": 14, "relative_humidity": 63.52, "temperature": 30.46}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 1140, "long_name": "Solar Juniper", "next_hop": 0, "num": "0x5a4b7fad", "position": null, "public_key_hex": "03daa9821e8e2aa97c0f48637ebef53d057a4a5d48dd71e6350577c665ac6e58", "role": "CLIENT", "short_name": "SFNK", "snr": 8.01, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 2454, "long_name": "Canyon Mole", "next_hop": 204, "num": "0x5a7e7001", "position": {"altitude": 1350, "latitude": 33.054618, "location_source": "LOC_INTERNAL", "longitude": -107.149237, "time_offset_sec": 2705}, "public_key_hex": "984d1c5f9099ae076b3ea4729001af8ce4ef8fbd444a3a390d6de8dc245f2c78", "role": "CLIENT", "short_name": "C5DS", "snr": -2.29, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.709, "battery_level": 13, "channel_utilization": 18.33, "uptime_seconds": 338757, "voltage": 3.417}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1018.96, "iaq": 65, "relative_humidity": 45.12, "temperature": 17.17}, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 655, "long_name": "Slow Bear", "next_hop": 0, "num": "0x5ab0ef52", "position": {"altitude": 1458, "latitude": 33.247835, "location_source": "LOC_INTERNAL", "longitude": -106.650083, "time_offset_sec": 729}, "public_key_hex": "4333ec040b37aa1b83c3bc243af0fe1af308e9abf22241cbde4f15cbf389b8a7", "role": "CLIENT", "short_name": "🐢", "snr": 4.76, "status": null, "telemetry": {"air_util_tx": 1.372, "battery_level": 63, "channel_utilization": 13.22, "uptime_seconds": 39950, "voltage": 3.867}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 2380, "long_name": "Roving Trout", "next_hop": 0, "num": "0x5b53b025", "position": {"altitude": 1058, "latitude": 33.419824, "location_source": "LOC_INTERNAL", "longitude": -106.100673, "time_offset_sec": 2647}, "public_key_hex": "3b5f5e5a541107f3d05babc1b1e67b08d5bd603e1897fbb3f904a0020717b793", "role": "ROUTER", "short_name": "RDI5", "snr": 7.3, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.474, "battery_level": 46, "channel_utilization": 13.57, "uptime_seconds": 6168, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 1672, "long_name": "Red Heron KQ5BO", "next_hop": 43, "num": "0x5d303a81", "position": {"altitude": 1066, "latitude": 33.490828, "location_source": "LOC_INTERNAL", "longitude": -106.612674, "time_offset_sec": 1834}, "public_key_hex": "17e0b9248eaf07c217234ab685b331cceb5223fbabdd8448c630353803ef883b", "role": "CLIENT", "short_name": "R8YI", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 1.633, "battery_level": 75, "channel_utilization": 11.71, "uptime_seconds": 161845, "voltage": 3.975}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1019.33, "iaq": 23, "relative_humidity": 41.44, "temperature": 24.44}, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 2583, "long_name": "Whispering Crane", "next_hop": 93, "num": "0x5d419cc9", "position": {"altitude": 2030, "latitude": 33.687682, "location_source": "LOC_INTERNAL", "longitude": -106.988016, "time_offset_sec": 2854}, "public_key_hex": "205e7bccba09d6670edf6b8ac10cacb1814f5d090f8e6117301ebf5f52af6172", "role": "CLIENT", "short_name": "W2LP", "snr": 8.4, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.544, "battery_level": 71, "channel_utilization": 28.41, "uptime_seconds": 12805, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_SOLAR_NODE", "last_heard_offset_sec": 6978, "long_name": "Burning Mesa", "next_hop": 0, "num": "0x5d884220", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "🌙", "snr": 7.23, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 2532, "long_name": "Lone Juniper", "next_hop": 0, "num": "0x5df06225", "position": {"altitude": 1459, "latitude": 33.67153, "location_source": "LOC_INTERNAL", "longitude": -108.298245, "time_offset_sec": 2709}, "public_key_hex": "8e96a3a4c8c92d3a6bdca70311296555f9673de6589f53a7c1bbf5025203663f", "role": "CLIENT", "short_name": "L4J5", "snr": 7.22, "status": {"status": "low-batt"}, "telemetry": {"air_util_tx": 1.076, "battery_level": 74, "channel_utilization": 14.44, "uptime_seconds": 49677, "voltage": 3.966}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 533, "long_name": "Silver Beaver", "next_hop": 0, "num": "0x5e2a849f", "position": {"altitude": 1205, "latitude": 31.904079, "location_source": "LOC_INTERNAL", "longitude": -106.811678, "time_offset_sec": 629}, "public_key_hex": "2595fac54c897f642e2401c5bc531e8fda9f093303e314ca10c3d71a9765ba99", "role": "CLIENT", "short_name": "SMRO", "snr": 9.05, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 10743, "long_name": "Loud Ridge", "next_hop": 0, "num": "0x5ee7b9ab", "position": {"altitude": 1458, "latitude": 32.804323, "location_source": "LOC_INTERNAL", "longitude": -107.157219, "time_offset_sec": 10931}, "public_key_hex": "324fe432faf69f8542e27a4f842930cc5427c6506c43d223c1327b9b450ab218", "role": "CLIENT", "short_name": "L4S6", "snr": 3.08, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1018.57, "iaq": 0, "relative_humidity": 30.0, "temperature": 15.21}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 291, "long_name": "Stone Juniper", "next_hop": 0, "num": "0x5eed232e", "position": null, "public_key_hex": "25819aa7eb792ba9c7536908ce600978222847123ec836dd5efffb4a99042fe5", "role": "CLIENT", "short_name": "SDK1", "snr": 9.23, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.338, "battery_level": 29, "channel_utilization": 11.26, "uptime_seconds": 43857, "voltage": 3.561}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1005.29, "iaq": 0, "relative_humidity": 73.52, "temperature": 17.84}, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 3582, "long_name": "Sunny Doe", "next_hop": 0, "num": "0x5f3a27b9", "position": null, "public_key_hex": "b650660e551a64ba46e1dc907598af9a63c830004ea1b58f4fa2f8d2981928c2", "role": "CLIENT", "short_name": "SY3A", "snr": 9.44, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1024.32, "iaq": 55, "relative_humidity": 54.13, "temperature": 27.45}, "hops_away": 0, "hw_model": "NOMADSTAR_METEOR_PRO", "last_heard_offset_sec": 4388, "long_name": "Bright Juniper", "next_hop": 0, "num": "0x60d24c47", "position": {"altitude": 1787, "latitude": 33.333417, "location_source": "LOC_INTERNAL", "longitude": -107.568488, "time_offset_sec": 4652}, "public_key_hex": "cb7db9874d97fb0ac506c3fd41b0c8c7bd2eb559826276c36e74e2e7555f5a81", "role": "CLIENT", "short_name": "🦉", "snr": 8.43, "status": null, "telemetry": {"air_util_tx": 1.427, "battery_level": 90, "channel_utilization": 14.19, "uptime_seconds": 76369, "voltage": 4.11}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1056, "long_name": "Wild Badger", "next_hop": 77, "num": "0x6200f9ce", "position": {"altitude": 1253, "latitude": 33.041987, "location_source": "LOC_INTERNAL", "longitude": -106.950457, "time_offset_sec": 1202}, "public_key_hex": "e23be3dd4813837634a58c9d1854da85f3dbd150ae89174b27682acc486193da", "role": "CLIENT", "short_name": "🔥", "snr": 4.7, "status": null, "telemetry": {"air_util_tx": 0.535, "battery_level": 82, "channel_utilization": 10.39, "uptime_seconds": 59624, "voltage": 4.038}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 6752, "long_name": "Forest Adder", "next_hop": 28, "num": "0x63013b03", "position": {"altitude": 1583, "latitude": 33.190369, "location_source": "LOC_INTERNAL", "longitude": -106.809159, "time_offset_sec": 6781}, "public_key_hex": "58aa10becbc7ede30777f73b3ed202f8450ad4e4437adf4cdd8e8f80e3712cd0", "role": "CLIENT", "short_name": "🌊", "snr": 9.73, "status": null, "telemetry": {"air_util_tx": 0.868, "battery_level": 17, "channel_utilization": 4.02, "uptime_seconds": 34171, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 66, "long_name": "Misty Crow", "next_hop": 0, "num": "0x634d6509", "position": null, "public_key_hex": "a1b2605f00d145be4708ced109705732bd361a0c8007de5a7b9ff0d6f51d8e18", "role": "CLIENT", "short_name": "MBRM", "snr": 7.44, "status": null, "telemetry": {"air_util_tx": 0.281, "battery_level": 63, "channel_utilization": 15.75, "uptime_seconds": 127038, "voltage": 3.867}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 7252, "long_name": "Found Gecko", "next_hop": 0, "num": "0x637a7112", "position": {"altitude": 1446, "latitude": 32.690082, "location_source": "LOC_INTERNAL", "longitude": -107.860767, "time_offset_sec": 7428}, "public_key_hex": "8846b0dbc05917aeb4705ad55a561bdce07fd33292ea833420fdad02af31e165", "role": "CLIENT", "short_name": "FMBH", "snr": 4.12, "status": null, "telemetry": {"air_util_tx": 0.813, "battery_level": 65, "channel_utilization": 10.12, "uptime_seconds": 3331, "voltage": 3.885}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 4011, "long_name": "Smooth Doe", "next_hop": 0, "num": "0x64527cb3", "position": {"altitude": 1352, "latitude": 33.789084, "location_source": "LOC_INTERNAL", "longitude": -107.13058, "time_offset_sec": 4044}, "public_key_hex": "5e2df0ded253ee2ef12d3a480bbc7d5224c32a1a10f031a5f4767929dd51c957", "role": "ROUTER", "short_name": "SSCW", "snr": 12.0, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.042, "battery_level": 98, "channel_utilization": 5.9, "uptime_seconds": 373425, "voltage": 4.182}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 3443, "long_name": "River Pike", "next_hop": 0, "num": "0x645fe930", "position": {"altitude": 1695, "latitude": 33.371402, "location_source": "LOC_INTERNAL", "longitude": -108.077662, "time_offset_sec": 3707}, "public_key_hex": "2b53f8e1f6d917da69b84232cf02ef52d63c3110d243a6365ca0d9f624a9676a", "role": "CLIENT_MUTE", "short_name": "RYR4", "snr": 9.34, "status": null, "telemetry": {"air_util_tx": 0.699, "battery_level": 55, "channel_utilization": 15.11, "uptime_seconds": 47524, "voltage": 3.795}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 7136, "long_name": "Blue Mamba", "next_hop": 75, "num": "0x64a95e31", "position": {"altitude": 953, "latitude": 33.832252, "location_source": "LOC_INTERNAL", "longitude": -108.054814, "time_offset_sec": 7336}, "public_key_hex": "6b53989af627f43df024b8cc2af77b8807e116d529a4f2a935f4841f115cd2f7", "role": "CLIENT", "short_name": "B41R", "snr": 2.61, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1273, "long_name": "River Coyote", "next_hop": 0, "num": "0x64cc9bac", "position": null, "public_key_hex": "93157fedd5c540dd2dba4723d1ac996e48a4a821b5a5c92e2c032f74f62f3cf2", "role": "CLIENT", "short_name": "RIS0", "snr": 3.55, "status": null, "telemetry": {"air_util_tx": 1.163, "battery_level": 89, "channel_utilization": 16.15, "uptime_seconds": 62238, "voltage": 4.101}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M5", "last_heard_offset_sec": 1921, "long_name": "Dusk Squirrel", "next_hop": 0, "num": "0x65bd58c3", "position": {"altitude": 1254, "latitude": 33.254787, "location_source": "LOC_INTERNAL", "longitude": -107.104805, "time_offset_sec": 2207}, "public_key_hex": "66c55dd5187047a62840c5dbc4609548c111433a75f9e871de15fe8fa8f618d8", "role": "CLIENT", "short_name": "DUYQ", "snr": 2.32, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1009.51, "iaq": 68, "relative_humidity": 47.61, "temperature": 32.73}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 8470, "long_name": "Sleepy Cobra", "next_hop": 0, "num": "0x6630f717", "position": {"altitude": 806, "latitude": 33.128898, "location_source": "LOC_INTERNAL", "longitude": -107.493292, "time_offset_sec": 8739}, "public_key_hex": "8f0b633549dc4dc8293407769a55bf0e85cf3c08b158d76a89ca5c0b10545431", "role": "CLIENT", "short_name": "SMQ1", "snr": 7.84, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.08, "battery_level": 83, "channel_utilization": 21.33, "uptime_seconds": 108301, "voltage": 4.047}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 7996, "long_name": "Silent Phoenix", "next_hop": 0, "num": "0x6644ef0a", "position": {"altitude": 1187, "latitude": 33.112567, "location_source": "LOC_INTERNAL", "longitude": -107.827152, "time_offset_sec": 8174}, "public_key_hex": "1b93a24c71ee7ea1b995d78094fdb96358abebd9217b88cc780752a933d89239", "role": "CLIENT", "short_name": "SBGO", "snr": 0.65, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2863, "long_name": "Dusk Hare", "next_hop": 0, "num": "0x6726f381", "position": {"altitude": 1010, "latitude": 32.705604, "location_source": "LOC_INTERNAL", "longitude": -106.046648, "time_offset_sec": 3132}, "public_key_hex": "181c2327d931a05576a5de436b0a31fb67542f0712c5cfde5c456a17b370f89e", "role": "CLIENT", "short_name": "DOM5", "snr": 4.13, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1018.76, "iaq": 39, "relative_humidity": 99.59, "temperature": 22.67}, "hops_away": 0, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 750, "long_name": "Drowsy Mamba", "next_hop": 0, "num": "0x675d77f2", "position": {"altitude": 1325, "latitude": 33.642278, "location_source": "LOC_INTERNAL", "longitude": -107.295189, "time_offset_sec": 837}, "public_key_hex": "cee4b8911b3920af5c95a121d34a201df99a6056909c028395064bdd7303907a", "role": "ROUTER", "short_name": "D1SL", "snr": 8.82, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.992, "battery_level": 11, "channel_utilization": 14.51, "uptime_seconds": 6720, "voltage": 3.399}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1315, "long_name": "Mountain Mole", "next_hop": 0, "num": "0x675e586d", "position": {"altitude": 1221, "latitude": 33.30228, "location_source": "LOC_INTERNAL", "longitude": -107.004475, "time_offset_sec": 1318}, "public_key_hex": "787716e0fe5232c05fd38d208b996e83d6d20b618ce8358ecc8c31725c6b579a", "role": "CLIENT", "short_name": "MGNO", "snr": 2.54, "status": null, "telemetry": {"air_util_tx": 0.117, "battery_level": 16, "channel_utilization": 8.72, "uptime_seconds": 198097, "voltage": 3.444}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 4, "hw_model": "T_DECK", "last_heard_offset_sec": 3622, "long_name": "Lunar Adder", "next_hop": 28, "num": "0x679bda37", "position": {"altitude": 1045, "latitude": 33.072766, "location_source": "LOC_INTERNAL", "longitude": -107.309558, "time_offset_sec": 3683}, "public_key_hex": "e5972098bc4c8ca34697e9696ab413b34113f251d3e796b1fa530f18a5b4f1bd", "role": "TRACKER", "short_name": "LIHE", "snr": 2.11, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.537, "battery_level": 17, "channel_utilization": 8.68, "uptime_seconds": 135160, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 3914, "long_name": "Roving Lynx", "next_hop": 0, "num": "0x68725ce0", "position": {"altitude": 832, "latitude": 32.945027, "location_source": "LOC_INTERNAL", "longitude": -107.479834, "time_offset_sec": 4072}, "public_key_hex": "ecd43f13c918a4f7209806d2c559c3aed2b9e5d5a7c77c0efa288eefe27ca02c", "role": "CLIENT", "short_name": "RE96", "snr": 6.58, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 13132, "long_name": "Mountain Turtle", "next_hop": 0, "num": "0x68c6bb7d", "position": {"altitude": 1143, "latitude": 33.711301, "location_source": "LOC_INTERNAL", "longitude": -107.708401, "time_offset_sec": 13212}, "public_key_hex": "e8548136b1d7de28fd487fae5c42e5e260717df2bf12792f383026e426ad067e", "role": "CLIENT", "short_name": "M215", "snr": 9.88, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.45, "battery_level": 49, "channel_utilization": 14.85, "uptime_seconds": 145984, "voltage": 3.741}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 1235, "long_name": "Drifting Owl", "next_hop": 0, "num": "0x68e7d58a", "position": {"altitude": 1415, "latitude": 33.558474, "location_source": "LOC_INTERNAL", "longitude": -107.839134, "time_offset_sec": 1430}, "public_key_hex": "01333b1228fd5e6d5cf18b0c6aae8fd6607251652c7f1a43f8846f3ac477dd15", "role": "CLIENT", "short_name": "D0H7", "snr": 4.19, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.244, "battery_level": 13, "channel_utilization": 26.08, "uptime_seconds": 72799, "voltage": 3.417}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "RAK4631", "last_heard_offset_sec": 2887, "long_name": "Red Pine", "next_hop": 197, "num": "0x69348f05", "position": {"altitude": 1216, "latitude": 33.204311, "location_source": "LOC_INTERNAL", "longitude": -106.604498, "time_offset_sec": 3187}, "public_key_hex": "89e55fe503cb45232d898096b28af07ed4bef11e92c21c928d4650d2c71501d9", "role": "CLIENT_HIDDEN", "short_name": "RO7M", "snr": 10.35, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4817, "long_name": "Burning Seal", "next_hop": 0, "num": "0x69998187", "position": {"altitude": 1293, "latitude": 32.392812, "location_source": "LOC_INTERNAL", "longitude": -106.344819, "time_offset_sec": 4831}, "public_key_hex": "1a4931a427d05e1bdaefa99f70dd2b2a220bfa2e8dec553847d9712b0c70b8d5", "role": "CLIENT", "short_name": "BSS4", "snr": -0.02, "status": null, "telemetry": {"air_util_tx": 0.239, "battery_level": 35, "channel_utilization": 6.97, "uptime_seconds": 204896, "voltage": 3.615}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 10076, "long_name": "Blue Squirrel", "next_hop": 212, "num": "0x6a7fcd9f", "position": {"altitude": 1505, "latitude": 32.932357, "location_source": "LOC_INTERNAL", "longitude": -107.01105, "time_offset_sec": 10153}, "public_key_hex": "1bdafc49306dbfb207f4ee164db19b4cb0c1135bb6b63fa03eb007d0dbb2da9b", "role": "ROUTER_LATE", "short_name": "🗻", "snr": 6.42, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1006.82, "iaq": 102, "relative_humidity": 81.51, "temperature": 13.71}, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 61, "long_name": "Sky Mesa", "next_hop": 0, "num": "0x6a9a8728", "position": {"altitude": 1638, "latitude": 33.079767, "location_source": "LOC_INTERNAL", "longitude": -106.860994, "time_offset_sec": 262}, "public_key_hex": "e39040ae3ea3066dbf14b8cf387e1b5d9fdb09bd077b6469c1d2a66b0d0219dc", "role": "TAK_TRACKER", "short_name": "SE1H", "snr": 5.92, "status": null, "telemetry": {"air_util_tx": 0.459, "battery_level": 101, "channel_utilization": 4.93, "uptime_seconds": 56564, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1016.22, "iaq": 62, "relative_humidity": 26.67, "temperature": 11.62}, "hops_away": 2, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 170, "long_name": "River Oak", "next_hop": 103, "num": "0x6b3d3aa3", "position": {"altitude": 1571, "latitude": 33.14479, "location_source": "LOC_INTERNAL", "longitude": -107.376011, "time_offset_sec": 200}, "public_key_hex": "d41101385568b35c0c170c5e2098fa3e11b88bde31402a021e9cb481f8933f21", "role": "CLIENT", "short_name": "RYK6", "snr": 8.07, "status": null, "telemetry": {"air_util_tx": 1.217, "battery_level": 32, "channel_utilization": 6.0, "uptime_seconds": 84071, "voltage": 3.588}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 50, "long_name": "River Hawk", "next_hop": 194, "num": "0x6bb1ca2b", "position": {"altitude": 1110, "latitude": 32.829006, "location_source": "LOC_INTERNAL", "longitude": -106.27801, "time_offset_sec": 295}, "public_key_hex": "2bba507bbb6153f5a25d4cb9d186ce98c3e93e9dfc5eccaa98125dd437c1b196", "role": "CLIENT", "short_name": "RYWL", "snr": 0.44, "status": null, "telemetry": {"air_util_tx": 0.346, "battery_level": 87, "channel_utilization": 10.21, "uptime_seconds": 421, "voltage": 4.083}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4785, "long_name": "Black Whale", "next_hop": 127, "num": "0x6bb4d10a", "position": {"altitude": 1237, "latitude": 33.509274, "location_source": "LOC_INTERNAL", "longitude": -106.277284, "time_offset_sec": 4880}, "public_key_hex": "7de62156e43c349c6a67dcc5a3afb96c4f088dcf59854561594eebb0280759a8", "role": "CLIENT", "short_name": "BFHZ", "snr": 1.01, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.162, "battery_level": 82, "channel_utilization": 10.28, "uptime_seconds": 20090, "voltage": 4.038}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 3, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 4229, "long_name": "Iron Tortoise", "next_hop": 0, "num": "0x6c43002f", "position": {"altitude": 1582, "latitude": 33.864042, "location_source": "LOC_INTERNAL", "longitude": -107.226095, "time_offset_sec": 4305}, "public_key_hex": "e56dfc70a9f0b54b0a21d867b7b9efeb1859fade19a8bc178becee94549646f7", "role": "CLIENT", "short_name": "I3HH", "snr": 8.44, "status": null, "telemetry": {"air_util_tx": 0.307, "battery_level": 24, "channel_utilization": 13.72, "uptime_seconds": 23775, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 298, "long_name": "Brave Doe", "next_hop": 182, "num": "0x6cc6ba99", "position": {"altitude": 1194, "latitude": 32.579495, "location_source": "LOC_INTERNAL", "longitude": -106.163977, "time_offset_sec": 572}, "public_key_hex": "01a7d519845227b7f66960aa742159c8258c155ab55aa628eab78726d39d4cc8", "role": "ROUTER", "short_name": "BMOQ", "snr": 4.42, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.106, "battery_level": 46, "channel_utilization": 5.93, "uptime_seconds": 15221, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 1556, "long_name": "Wandering Phoenix", "next_hop": 0, "num": "0x6d0c22c9", "position": {"altitude": 1703, "latitude": 32.702117, "location_source": "LOC_INTERNAL", "longitude": -106.689231, "time_offset_sec": 1797}, "public_key_hex": "4c41a2ca4984fd5632ca82f398454fcb1702528255edeefdf2da4a237fb3239f", "role": "CLIENT", "short_name": "🦋", "snr": 3.31, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 6253, "long_name": "Drowsy Raven KE7YJ", "next_hop": 0, "num": "0x6d39e1de", "position": {"altitude": 1292, "latitude": 32.404734, "location_source": "LOC_INTERNAL", "longitude": -107.157604, "time_offset_sec": 6487}, "public_key_hex": "fc6ee6e0f7c7960932b081f1b00c18fcb8e423f20c6f0e4fca30062c419bcaa1", "role": "SENSOR", "short_name": "DA49", "snr": 4.41, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.475, "battery_level": 49, "channel_utilization": 8.17, "uptime_seconds": 25790, "voltage": 3.741}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 12232, "long_name": "Fast Lynx", "next_hop": 48, "num": "0x6e0bad26", "position": null, "public_key_hex": "66930b442ce2a258b51c21dc63651a4ecc466b0ec25378ed28d7220beb586c4a", "role": "CLIENT", "short_name": "FNQ9", "snr": 3.75, "status": null, "telemetry": {"air_util_tx": 0.872, "battery_level": 33, "channel_utilization": 31.18, "uptime_seconds": 165544, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 8933, "long_name": "Green Falcon", "next_hop": 153, "num": "0x6f95c8de", "position": {"altitude": 1507, "latitude": 33.058043, "location_source": "LOC_INTERNAL", "longitude": -107.753248, "time_offset_sec": 9029}, "public_key_hex": "4a0fd161559916272677d7be03a4385deee355bca63ede5f2e89ac17b4544cc6", "role": "CLIENT", "short_name": "GG11", "snr": 2.21, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 3961, "long_name": "Desert Arroyo", "next_hop": 104, "num": "0x70672210", "position": {"altitude": 2110, "latitude": 33.806679, "location_source": "LOC_INTERNAL", "longitude": -108.245578, "time_offset_sec": 4111}, "public_key_hex": "5f76a5eb313191ea039acdb18eb537840b25569c0605981c8edbb7e2c484b50d", "role": "CLIENT_MUTE", "short_name": "DTNH", "snr": 7.35, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.148, "battery_level": 31, "channel_utilization": 12.08, "uptime_seconds": 202950, "voltage": 3.579}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1016.01, "iaq": 19, "relative_humidity": 46.48, "temperature": 25.33}, "hops_away": 3, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1898, "long_name": "Sleepy Moose", "next_hop": 135, "num": "0x70b79b40", "position": {"altitude": 1072, "latitude": 33.477423, "location_source": "LOC_INTERNAL", "longitude": -107.485895, "time_offset_sec": 1982}, "public_key_hex": "23f70e1dd5dd6191ac0d07dc43186a8bb3cae86918212db4a90cd65e4bec27fc", "role": "CLIENT", "short_name": "SEJI", "snr": 8.49, "status": null, "telemetry": {"air_util_tx": 0.426, "battery_level": 92, "channel_utilization": 5.77, "uptime_seconds": 34594, "voltage": 4.128}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.78, "iaq": 88, "relative_humidity": 78.78, "temperature": 17.98}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 81, "long_name": "Iron Dolphin", "next_hop": 0, "num": "0x71f35893", "position": {"altitude": 1195, "latitude": 33.158653, "location_source": "LOC_INTERNAL", "longitude": -106.688519, "time_offset_sec": 179}, "public_key_hex": "6f5d9f31615955d38cc92366808bd822a5754c33fcf5b22f2474952711b333a0", "role": "CLIENT_MUTE", "short_name": "I8FE", "snr": 8.95, "status": null, "telemetry": {"air_util_tx": 0.104, "battery_level": 37, "channel_utilization": 11.73, "uptime_seconds": 200720, "voltage": 3.633}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 3827, "long_name": "Drowsy Pony", "next_hop": 0, "num": "0x726683a9", "position": {"altitude": 1471, "latitude": 34.724546, "location_source": "LOC_INTERNAL", "longitude": -107.151964, "time_offset_sec": 4047}, "public_key_hex": "ae5af96e0c00ec919f651fa6da80144a28b8ec69ac33f5b0de3282f19c1c1e7a", "role": "CLIENT", "short_name": "DDUV", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 2.128, "battery_level": 10, "channel_utilization": 3.03, "uptime_seconds": 145294, "voltage": 3.39}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 1763, "long_name": "Steel Yucca", "next_hop": 0, "num": "0x73341f37", "position": {"altitude": 1716, "latitude": 33.486852, "location_source": "LOC_INTERNAL", "longitude": -108.240058, "time_offset_sec": 1912}, "public_key_hex": "f6cea0dd788cba03ac16d70b0bd99ae41018ff0be20d67497abb12d7327a41ba", "role": "CLIENT", "short_name": "SHCI", "snr": 3.0, "status": null, "telemetry": {"air_util_tx": 0.36, "battery_level": 38, "channel_utilization": 15.8, "uptime_seconds": 134943, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 139, "long_name": "Tiny Mole", "next_hop": 0, "num": "0x7348832d", "position": {"altitude": 1543, "latitude": 33.096162, "location_source": "LOC_INTERNAL", "longitude": -107.278135, "time_offset_sec": 297}, "public_key_hex": "1b0d2d4d35da0ced6fa31182ef5423eb536b7e3e53bdf5f98e58c44f54dc1530", "role": "TRACKER", "short_name": "TKFB", "snr": 11.46, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1017.26, "iaq": 66, "relative_humidity": 64.85, "temperature": 19.22}, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 780, "long_name": "Tall Crane", "next_hop": 0, "num": "0x738e72e8", "position": {"altitude": 1695, "latitude": 32.448476, "location_source": "LOC_INTERNAL", "longitude": -106.519086, "time_offset_sec": 947}, "public_key_hex": "c3019685ef33305cfc329b54740d4ada92b4a40fb535425a089f1e3d0b4d0053", "role": "TAK", "short_name": "TV6K", "snr": 0.74, "status": null, "telemetry": {"air_util_tx": 1.299, "battery_level": 38, "channel_utilization": 12.46, "uptime_seconds": 51020, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1033.06, "iaq": 7, "relative_humidity": 65.48, "temperature": 25.7}, "hops_away": 0, "hw_model": "HELTEC_HT62", "last_heard_offset_sec": 4821, "long_name": "Hidden Trout", "next_hop": 0, "num": "0x7491806d", "position": {"altitude": 1434, "latitude": 33.056575, "location_source": "LOC_INTERNAL", "longitude": -107.720741, "time_offset_sec": 5075}, "public_key_hex": "7c8691bfc6658d31d67acd477f09750318317ce021dee1599bb108ed25cdf0e3", "role": "CLIENT", "short_name": "🦉", "snr": 11.07, "status": null, "telemetry": {"air_util_tx": 1.117, "battery_level": 49, "channel_utilization": 14.84, "uptime_seconds": 11493, "voltage": 3.741}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 5, "environment": null, "hops_away": 1, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 834, "long_name": "Hidden Bronco", "next_hop": 97, "num": "0x749590b2", "position": null, "public_key_hex": "522be6ad7b0c0737d1080a2dd82f8972aba976c16596884ce7e2a8f58e4e0dc1", "role": "CLIENT", "short_name": "H2R2", "snr": 7.6, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 3119, "long_name": "Bright Bluff", "next_hop": 0, "num": "0x7629ea15", "position": {"altitude": 1657, "latitude": 32.845151, "location_source": "LOC_INTERNAL", "longitude": -107.295757, "time_offset_sec": 3314}, "public_key_hex": "e3fcb20d29c60cffaac484bc143758079667bd954af5dfb57e2f125a216379d8", "role": "CLIENT_BASE", "short_name": "B1SA", "snr": 6.42, "status": null, "telemetry": {"air_util_tx": 0.154, "battery_level": 28, "channel_utilization": 10.1, "uptime_seconds": 102430, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 749, "long_name": "Drowsy Mustang", "next_hop": 0, "num": "0x768eeba7", "position": {"altitude": 1345, "latitude": 32.71891, "location_source": "LOC_INTERNAL", "longitude": -106.516389, "time_offset_sec": 804}, "public_key_hex": "18ad33e52e42b79a698639dc4cd32e651f0a5fb5bd672f76381b0193fd9db55f", "role": "CLIENT", "short_name": "DV2L", "snr": 7.02, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1004.39, "iaq": 35, "relative_humidity": 55.44, "temperature": 29.33}, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 554, "long_name": "Drowsy Crow", "next_hop": 65, "num": "0x76dc5c41", "position": {"altitude": 844, "latitude": 33.041994, "location_source": "LOC_INTERNAL", "longitude": -107.408948, "time_offset_sec": 822}, "public_key_hex": "5304dd65402a959318fa4c834d9e03128c6c0ced8ac983d3666d33e9762c41e1", "role": "CLIENT", "short_name": "DMAJ", "snr": 6.41, "status": null, "telemetry": {"air_util_tx": 0.826, "battery_level": 64, "channel_utilization": 7.58, "uptime_seconds": 90535, "voltage": 3.876}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 6010, "long_name": "Iron Fox", "next_hop": 172, "num": "0x7723d1a0", "position": {"altitude": 1262, "latitude": 33.212945, "location_source": "LOC_INTERNAL", "longitude": -107.64994, "time_offset_sec": 6239}, "public_key_hex": "04ba223a1cd802a0bf24cf805578318d66509cae17d34ae5397e5b2b5837bb14", "role": "CLIENT", "short_name": "ITHM", "snr": 4.81, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 393, "long_name": "Quick Heron", "next_hop": 126, "num": "0x77fbcdf6", "position": {"altitude": 1617, "latitude": 33.585965, "location_source": "LOC_INTERNAL", "longitude": -106.371643, "time_offset_sec": 397}, "public_key_hex": "d0d19a00abd92f2bcf1592962a1313138225a83a8e87064cdb8114ecfba39ce3", "role": "CLIENT", "short_name": "🔥", "snr": 5.24, "status": null, "telemetry": {"air_util_tx": 0.794, "battery_level": 43, "channel_utilization": 21.17, "uptime_seconds": 58781, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 7221, "long_name": "Sleepy Colt", "next_hop": 0, "num": "0x790493d5", "position": {"altitude": 1295, "latitude": 33.4132, "location_source": "LOC_INTERNAL", "longitude": -106.63144, "time_offset_sec": 7510}, "public_key_hex": "", "role": "CLIENT", "short_name": "SCHP", "snr": 5.7, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 2110, "long_name": "Drifting Mesa KE0ZH", "next_hop": 49, "num": "0x79d393b0", "position": {"altitude": 1682, "latitude": 32.968426, "location_source": "LOC_INTERNAL", "longitude": -107.457182, "time_offset_sec": 2339}, "public_key_hex": "6e0ae215f2384f9122ece761c69ba9e1a42073a3470047274fcdd72a0248cad4", "role": "CLIENT", "short_name": "DA8J", "snr": -0.97, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1759, "long_name": "Red Hare KX2EP", "next_hop": 70, "num": "0x7ad3664f", "position": {"altitude": 2141, "latitude": 33.229175, "location_source": "LOC_INTERNAL", "longitude": -107.993856, "time_offset_sec": 2018}, "public_key_hex": "b2bc9c7db94f5f5f0f6753219c59fdf7ab659d649d1c63bc059983b5025d7d51", "role": "CLIENT", "short_name": "R1OR", "snr": 12.0, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.352, "battery_level": 27, "channel_utilization": 4.5, "uptime_seconds": 25899, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 8573, "long_name": "Floating Stag", "next_hop": 0, "num": "0x7bb70bb7", "position": {"altitude": 1272, "latitude": 33.168645, "location_source": "LOC_INTERNAL", "longitude": -107.684837, "time_offset_sec": 8756}, "public_key_hex": "b6b88b3e8a9e389b8c41dd7b6a26bf2180090f59d4f1d8e577297aebe4b34562", "role": "CLIENT", "short_name": "FZ3H", "snr": 4.97, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.936, "battery_level": 27, "channel_utilization": 7.47, "uptime_seconds": 76225, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 2148, "long_name": "Rough Bear", "next_hop": 241, "num": "0x7c224653", "position": {"altitude": 1438, "latitude": 34.000152, "location_source": "LOC_INTERNAL", "longitude": -106.625412, "time_offset_sec": 2152}, "public_key_hex": "331ea14519572dfc8abde388ba5d1c29810e4c1934d08f9bf43f49cc8505a54b", "role": "CLIENT", "short_name": "RNUC", "snr": 7.3, "status": {"status": "offline-soon"}, "telemetry": {"air_util_tx": 0.75, "battery_level": 38, "channel_utilization": 9.21, "uptime_seconds": 407434, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 432, "long_name": "Burning Bronco", "next_hop": 0, "num": "0x7ccb0a96", "position": {"altitude": 1365, "latitude": 33.576907, "location_source": "LOC_INTERNAL", "longitude": -107.563729, "time_offset_sec": 581}, "public_key_hex": "8cca6b93f5b2f58f481c81480578391486d8f0e5bda344fe5dc6a29c447c10e7", "role": "TRACKER", "short_name": "BGCJ", "snr": 6.05, "status": null, "telemetry": {"air_util_tx": 0.056, "battery_level": 93, "channel_utilization": 7.59, "uptime_seconds": 165200, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 1428, "long_name": "Shady Lion", "next_hop": 0, "num": "0x7ce782e2", "position": {"altitude": 1380, "latitude": 32.431543, "location_source": "LOC_INTERNAL", "longitude": -107.604725, "time_offset_sec": 1458}, "public_key_hex": "0daf87c9019c3bb9741fd05905f67682b647dc97733fa5078e27df5fa05b93c5", "role": "CLIENT", "short_name": "SWX9", "snr": 8.03, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 1804, "long_name": "Mountain Cedar", "next_hop": 0, "num": "0x7e0d0b69", "position": {"altitude": 1321, "latitude": 33.11493, "location_source": "LOC_INTERNAL", "longitude": -107.449334, "time_offset_sec": 2074}, "public_key_hex": "bf5042d4e85efc712dd1e4681db857f2b3484e1739e897f2a49792ee0f18c0bc", "role": "CLIENT", "short_name": "M7J1", "snr": 0.98, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.639, "battery_level": 81, "channel_utilization": 3.58, "uptime_seconds": 19425, "voltage": 4.029}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 882, "long_name": "Rough Hawk", "next_hop": 32, "num": "0x7e39ee69", "position": {"altitude": 1278, "latitude": 33.405852, "location_source": "LOC_INTERNAL", "longitude": -106.491004, "time_offset_sec": 943}, "public_key_hex": "521e42d928118b4cdafb25bc69f8974f03ffc910c991069ec726dbb02ec7778c", "role": "CLIENT", "short_name": "RHCK", "snr": 8.01, "status": null, "telemetry": {"air_util_tx": 0.672, "battery_level": 55, "channel_utilization": 29.49, "uptime_seconds": 105577, "voltage": 3.795}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 788, "long_name": "Sleepy Iguana", "next_hop": 0, "num": "0x7e49f748", "position": {"altitude": 1316, "latitude": 33.409957, "location_source": "LOC_INTERNAL", "longitude": -107.430865, "time_offset_sec": 891}, "public_key_hex": "174cdc5204bdf752801c9abd6aaf17a5b9602b484f9ba55e4ec9a8b2e01f6adb", "role": "CLIENT", "short_name": "SDJ2", "snr": -5.74, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 11666, "long_name": "Howling Squirrel", "next_hop": 0, "num": "0x7eb8bc45", "position": {"altitude": 1520, "latitude": 32.659288, "location_source": "LOC_INTERNAL", "longitude": -106.233421, "time_offset_sec": 11833}, "public_key_hex": "d804b803ddb8b9a6bb456b2965da9eef06a6bc1db080049c4e278ed4860f292e", "role": "CLIENT_MUTE", "short_name": "H9UH", "snr": 8.35, "status": null, "telemetry": {"air_util_tx": 1.476, "battery_level": 32, "channel_utilization": 18.0, "uptime_seconds": 145120, "voltage": 3.588}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 6, "environment": {"barometric_pressure": 992.43, "iaq": 26, "relative_humidity": 70.77, "temperature": 16.27}, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1291, "long_name": "Tiny Seal", "next_hop": 242, "num": "0x7f039d52", "position": {"altitude": 1391, "latitude": 33.312521, "location_source": "LOC_INTERNAL", "longitude": -107.046926, "time_offset_sec": 1350}, "public_key_hex": "51db617b30735e34a4d75ad1725ef1b002ec1a9a38ef32d4b51acf9e8c7b146f", "role": "CLIENT", "short_name": "T82O", "snr": 9.81, "status": null, "telemetry": {"air_util_tx": 1.794, "battery_level": 68, "channel_utilization": 14.75, "uptime_seconds": 68126, "voltage": 3.912}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 356, "long_name": "Green Tortoise", "next_hop": 0, "num": "0x7f95833e", "position": {"altitude": 1431, "latitude": 32.123231, "location_source": "LOC_INTERNAL", "longitude": -107.638817, "time_offset_sec": 405}, "public_key_hex": "c925ceda2f3e4bbbf987e13974a3d3fa532794dd994730a4b784d9fbebd09784", "role": "CLIENT", "short_name": "GK1S", "snr": 1.37, "status": null, "telemetry": {"air_util_tx": 1.209, "battery_level": 94, "channel_utilization": 16.27, "uptime_seconds": 136843, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 3472, "long_name": "Sleepy Aspen", "next_hop": 0, "num": "0x7f98caa8", "position": {"altitude": 1866, "latitude": 33.495868, "location_source": "LOC_INTERNAL", "longitude": -108.063052, "time_offset_sec": 3488}, "public_key_hex": "0b2dc28d0c3b5d165ec9b161a0943737d6e2d88b545d5da717182f8f152e9e43", "role": "CLIENT", "short_name": "SX11", "snr": 8.03, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.845, "battery_level": 25, "channel_utilization": 16.27, "uptime_seconds": 165688, "voltage": 3.525}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 4141, "long_name": "Happy Arroyo", "next_hop": 111, "num": "0x7fe40bcc", "position": {"altitude": 1958, "latitude": 32.443587, "location_source": "LOC_INTERNAL", "longitude": -106.084226, "time_offset_sec": 4285}, "public_key_hex": "", "role": "CLIENT", "short_name": "HZAG", "snr": 8.71, "status": null, "telemetry": null}
+501
View File
@@ -0,0 +1,501 @@
{"_meta": {"centroid": [33.1284, -107.2528], "count": 500, "coverage": {"environment": 0.25, "position": 0.85, "status": 0.4, "telemetry": 0.7}, "generated_at_iso": "1970-08-23T11:55:12Z", "last_heard_max_sec": 604800, "last_heard_mean_sec": 3600, "my_node_num_excluded": null, "seed": 20260512, "spread_km": 60.0, "version": 25}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 3197, "long_name": "Frosty Whale", "next_hop": 173, "num": "0x00b40906", "position": {"altitude": 1519, "latitude": 32.151666, "location_source": "LOC_INTERNAL", "longitude": -107.6939, "time_offset_sec": 3317}, "public_key_hex": "3be3f3db2ea4843edb428e1d50d5f7096daf217bd4259709c44b7c5f7031a1c8", "role": "CLIENT", "short_name": "FL7K", "snr": 5.16, "status": null, "telemetry": {"air_util_tx": 0.197, "battery_level": 71, "channel_utilization": 2.45, "uptime_seconds": 61699, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": null, "hops_away": 0, "hw_model": "TBEAM_1_WATT", "last_heard_offset_sec": 17404, "long_name": "Drifting Yucca", "next_hop": 0, "num": "0x011e2fed", "position": {"altitude": 1597, "latitude": 33.929344, "location_source": "LOC_INTERNAL", "longitude": -107.48397, "time_offset_sec": 17610}, "public_key_hex": "5e83f0b1e902e0609e31daa68131955ca54601b6a401ef40f3dd3075578e1d26", "role": "CLIENT", "short_name": "DGNX", "snr": 6.01, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 998.92, "iaq": 1, "relative_humidity": 41.97, "temperature": 37.71}, "hops_away": 2, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 3471, "long_name": "Shady Pike", "next_hop": 173, "num": "0x0189ac5e", "position": {"altitude": 1726, "latitude": 33.013084, "location_source": "LOC_INTERNAL", "longitude": -107.196206, "time_offset_sec": 3607}, "public_key_hex": "d7941aebdd024277a3c21efc85e57993d8619bae9d020e48a10698a63999009d", "role": "TRACKER", "short_name": "SVCS", "snr": 6.77, "status": {"status": "offline-soon"}, "telemetry": {"air_util_tx": 0.18, "battery_level": 88, "channel_utilization": 15.72, "uptime_seconds": 104301, "voltage": 4.092}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.77, "iaq": 66, "relative_humidity": 60.03, "temperature": 16.12}, "hops_away": 3, "hw_model": "RAK4631", "last_heard_offset_sec": 1955, "long_name": "Lost Cactus", "next_hop": 142, "num": "0x01b84c91", "position": null, "public_key_hex": "928626e03eabe5f6236aab36347b40dd833ba7903cc16fbe4b3871900a4c81ee", "role": "CLIENT", "short_name": "🗻", "snr": 4.24, "status": null, "telemetry": {"air_util_tx": 0.866, "battery_level": 50, "channel_utilization": 31.43, "uptime_seconds": 58418, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.26, "iaq": 51, "relative_humidity": 60.87, "temperature": 25.07}, "hops_away": 1, "hw_model": "HELTEC_VISION_MASTER_T190", "last_heard_offset_sec": 63, "long_name": "Forest Shark", "next_hop": 172, "num": "0x01d003a2", "position": {"altitude": 1242, "latitude": 33.298407, "location_source": "LOC_INTERNAL", "longitude": -107.374181, "time_offset_sec": 348}, "public_key_hex": "c638bc498f50956b06bdadd5a155b5ffed4efd86d4edec9e2ef33e578b7dcb26", "role": "CLIENT", "short_name": "FTDK", "snr": 2.09, "status": null, "telemetry": {"air_util_tx": 0.196, "battery_level": 79, "channel_utilization": 19.63, "uptime_seconds": 25163, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 2213, "long_name": "Sneaky Viper", "next_hop": 119, "num": "0x021d5a39", "position": {"altitude": 1650, "latitude": 32.828212, "location_source": "LOC_INTERNAL", "longitude": -106.562505, "time_offset_sec": 2411}, "public_key_hex": "1e20cd9b42884ea7b5a13ed9474886d9841c9102408fefac5d426f14ab3c26e6", "role": "CLIENT", "short_name": "ST00", "snr": 8.44, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 2.146, "battery_level": 45, "channel_utilization": 33.11, "uptime_seconds": 4177, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 34, "long_name": "Solar Sage", "next_hop": 0, "num": "0x02486b0c", "position": {"altitude": 1566, "latitude": 33.25455, "location_source": "LOC_INTERNAL", "longitude": -108.276457, "time_offset_sec": 282}, "public_key_hex": "639100e236b166787ce42d49d5ab889f3d678bc11fa947250247f89c2659cdde", "role": "CLIENT", "short_name": "🦂", "snr": 2.71, "status": null, "telemetry": {"air_util_tx": 0.818, "battery_level": 15, "channel_utilization": 10.26, "uptime_seconds": 14197, "voltage": 3.435}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1004.55, "iaq": 93, "relative_humidity": 61.52, "temperature": 22.54}, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 5878, "long_name": "Whispering Cougar", "next_hop": 119, "num": "0x02554ce8", "position": {"altitude": 943, "latitude": 34.283555, "location_source": "LOC_INTERNAL", "longitude": -107.74003, "time_offset_sec": 5911}, "public_key_hex": "9cd4142858ee82e04b22ba3b33f7c032b40063f39bc5c5a0d3f492636b598d9e", "role": "CLIENT", "short_name": "WOT9", "snr": 6.19, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 1577, "long_name": "Iron Whale", "next_hop": 0, "num": "0x0430fd13", "position": {"altitude": 1620, "latitude": 32.657264, "location_source": "LOC_INTERNAL", "longitude": -107.204545, "time_offset_sec": 1871}, "public_key_hex": "c9a747534744cb9ee1bd2c5b253182175bee5e5f2a5284f9530889836593852e", "role": "CLIENT", "short_name": "I189", "snr": 5.64, "status": null, "telemetry": {"air_util_tx": 0.121, "battery_level": 50, "channel_utilization": 18.75, "uptime_seconds": 49495, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 4591, "long_name": "Sneaky Heron", "next_hop": 138, "num": "0x04b75b6d", "position": {"altitude": 1287, "latitude": 33.452725, "location_source": "LOC_INTERNAL", "longitude": -106.460239, "time_offset_sec": 4757}, "public_key_hex": "11afa777f0189e7bc7f93f065be232df98e21f8b9ecdde49d738201a2c4956fc", "role": "CLIENT", "short_name": "🌊", "snr": 5.38, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 174, "long_name": "Sunny Pony", "next_hop": 108, "num": "0x05267c0d", "position": {"altitude": 1003, "latitude": 33.195449, "location_source": "LOC_INTERNAL", "longitude": -106.986062, "time_offset_sec": 439}, "public_key_hex": "7a195aad3491a11143e61ab8201b4ce1a8552c37985fb4a7d4b885c5cd5323be", "role": "CLIENT", "short_name": "SRBM", "snr": 7.29, "status": null, "telemetry": {"air_util_tx": 0.668, "battery_level": 23, "channel_utilization": 9.39, "uptime_seconds": 117938, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 4, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 5294, "long_name": "Lunar Gecko", "next_hop": 157, "num": "0x054f2796", "position": null, "public_key_hex": "201aff9fd3405ff131e325f089a44ccd8ce67184dae2015b4a10e142a1c4550f", "role": "CLIENT", "short_name": "LESX", "snr": 7.12, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.598, "battery_level": 14, "channel_utilization": 16.05, "uptime_seconds": 475034, "voltage": 3.426}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 5, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 1380, "long_name": "Howling Eagle", "next_hop": 35, "num": "0x058f496a", "position": {"altitude": 1347, "latitude": 33.202974, "location_source": "LOC_INTERNAL", "longitude": -107.351541, "time_offset_sec": 1541}, "public_key_hex": "11955ea65b430f745ead784933c3ac04798aa1f9f094fe49cc7fb3c91e50f08e", "role": "CLIENT", "short_name": "HZDF", "snr": 9.38, "status": null, "telemetry": {"air_util_tx": 1.512, "battery_level": 55, "channel_utilization": 8.96, "uptime_seconds": 88941, "voltage": 3.795}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 7137, "long_name": "Sunny Shark", "next_hop": 21, "num": "0x05b218d2", "position": {"altitude": 1536, "latitude": 33.202605, "location_source": "LOC_INTERNAL", "longitude": -107.383081, "time_offset_sec": 7193}, "public_key_hex": "99784925060b03ef3230387e5b124d347a7308525c830a113a654df744c0e836", "role": "CLIENT", "short_name": "🦋", "snr": 6.96, "status": null, "telemetry": {"air_util_tx": 0.001, "battery_level": 73, "channel_utilization": 6.35, "uptime_seconds": 95615, "voltage": 3.957}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1014.17, "iaq": 34, "relative_humidity": 36.77, "temperature": 27.02}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4830, "long_name": "Found Eagle", "next_hop": 0, "num": "0x05d3737a", "position": {"altitude": 1757, "latitude": 34.578404, "location_source": "LOC_INTERNAL", "longitude": -106.975336, "time_offset_sec": 4918}, "public_key_hex": "2ea628e36802c997cca7426463e167fa75986add373452a27cfa0210242e5268", "role": "CLIENT", "short_name": "FXWZ", "snr": 3.57, "status": null, "telemetry": {"air_util_tx": 0.362, "battery_level": 70, "channel_utilization": 1.49, "uptime_seconds": 12694, "voltage": 3.93}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 9839, "long_name": "Wandering Marmot", "next_hop": 0, "num": "0x05fc1a3f", "position": {"altitude": 1129, "latitude": 32.659091, "location_source": "LOC_INTERNAL", "longitude": -107.505247, "time_offset_sec": 9923}, "public_key_hex": "a337f9ab3ea8333215289724cbad941ae7621da8b8d6e3d5ab57e71524e5709a", "role": "CLIENT", "short_name": "W250", "snr": 2.53, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.586, "battery_level": 56, "channel_utilization": 12.14, "uptime_seconds": 42260, "voltage": 3.804}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1018.99, "iaq": 0, "relative_humidity": 71.41, "temperature": 15.52}, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 408, "long_name": "New Gecko", "next_hop": 61, "num": "0x066d6e76", "position": {"altitude": 1747, "latitude": 32.773832, "location_source": "LOC_INTERNAL", "longitude": -107.220236, "time_offset_sec": 698}, "public_key_hex": "", "role": "CLIENT", "short_name": "N2ZX", "snr": 0.58, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.313, "battery_level": 92, "channel_utilization": 3.14, "uptime_seconds": 15258, "voltage": 4.128}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 2782, "long_name": "Fast Yucca KX5XX", "next_hop": 141, "num": "0x06c7ea9f", "position": {"altitude": 1472, "latitude": 33.093005, "location_source": "LOC_INTERNAL", "longitude": -107.511463, "time_offset_sec": 2851}, "public_key_hex": "12c1f6217e378cb6f61533272c9641fd6eaf282c3180a3a71b1c08b1a89ffbf0", "role": "CLIENT", "short_name": "FLXR", "snr": 7.65, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 997.01, "iaq": 35, "relative_humidity": 61.92, "temperature": 24.34}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 692, "long_name": "Found Ridge", "next_hop": 0, "num": "0x06cab439", "position": {"altitude": 933, "latitude": 33.474999, "location_source": "LOC_INTERNAL", "longitude": -107.067398, "time_offset_sec": 845}, "public_key_hex": "", "role": "CLIENT", "short_name": "FDF7", "snr": -0.59, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "RAK4631", "last_heard_offset_sec": 638, "long_name": "Copper Bass", "next_hop": 154, "num": "0x06dda523", "position": {"altitude": 1395, "latitude": 33.438741, "location_source": "LOC_INTERNAL", "longitude": -108.072906, "time_offset_sec": 873}, "public_key_hex": "", "role": "CLIENT", "short_name": "CVYO", "snr": 11.55, "status": null, "telemetry": {"air_util_tx": 1.484, "battery_level": 13, "channel_utilization": 6.1, "uptime_seconds": 98410, "voltage": 3.417}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 112, "long_name": "Green Gecko", "next_hop": 78, "num": "0x072e0237", "position": {"altitude": 853, "latitude": 34.012327, "location_source": "LOC_INTERNAL", "longitude": -107.188724, "time_offset_sec": 262}, "public_key_hex": "700d510170e7fe912da2da8cbf930e43c6710829c8faa89af423910945e6265e", "role": "CLIENT", "short_name": "GGC5", "snr": 10.05, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 1245, "long_name": "Brave Bear", "next_hop": 0, "num": "0x0783e8d1", "position": {"altitude": 1537, "latitude": 33.749784, "location_source": "LOC_INTERNAL", "longitude": -107.841257, "time_offset_sec": 1414}, "public_key_hex": "178879e3e697a4c3c52ec66fbe8dd216cfa64ade0135a634cc8687ea3ade7320", "role": "TRACKER", "short_name": "BFRT", "snr": 3.14, "status": null, "telemetry": {"air_util_tx": 1.759, "battery_level": 30, "channel_utilization": 14.5, "uptime_seconds": 78399, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 2045, "long_name": "Stone Bear", "next_hop": 0, "num": "0x078cfba6", "position": null, "public_key_hex": "467443a858386925299334fbf59f7754583f47a8731763404a98c9b30a74d90d", "role": "CLIENT", "short_name": "SORT", "snr": 6.29, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.588, "battery_level": 79, "channel_utilization": 6.6, "uptime_seconds": 53720, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 5613, "long_name": "Frosty Elk", "next_hop": 0, "num": "0x07948431", "position": {"altitude": 1186, "latitude": 32.122731, "location_source": "LOC_INTERNAL", "longitude": -106.693574, "time_offset_sec": 5803}, "public_key_hex": "7133e1eda8cf2b46701bb55a1cdc136f4dd4efa26c296f92188c770b6f6b11c5", "role": "CLIENT", "short_name": "F4ZQ", "snr": 6.09, "status": null, "telemetry": {"air_util_tx": 0.318, "battery_level": 101, "channel_utilization": 8.56, "uptime_seconds": 76257, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 4207, "long_name": "Frosty Elk", "next_hop": 0, "num": "0x079d9ed4", "position": {"altitude": 1431, "latitude": 33.80937, "location_source": "LOC_INTERNAL", "longitude": -107.229029, "time_offset_sec": 4335}, "public_key_hex": "8c7857ee2dc180990083b56b1114163bacad59fd8f324a7dd6a3c52ce13880a9", "role": "TRACKER", "short_name": "FNZ9", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.514, "battery_level": 87, "channel_utilization": 7.82, "uptime_seconds": 5846, "voltage": 4.083}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 102, "long_name": "Wandering Hawk", "next_hop": 0, "num": "0x0839477d", "position": {"altitude": 1244, "latitude": 33.568907, "location_source": "LOC_INTERNAL", "longitude": -107.90779, "time_offset_sec": 292}, "public_key_hex": "4e12b947441a7467ea24d8ec904d0525483c6f4a5f53b73fafe1e1a1bb55414d", "role": "CLIENT", "short_name": "WD7D", "snr": 5.47, "status": null, "telemetry": {"air_util_tx": 0.391, "battery_level": 94, "channel_utilization": 4.9, "uptime_seconds": 106184, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 3873, "long_name": "Sneaky Elk", "next_hop": 0, "num": "0x087eacd5", "position": {"altitude": 1012, "latitude": 32.148225, "location_source": "LOC_INTERNAL", "longitude": -106.891906, "time_offset_sec": 3959}, "public_key_hex": "5dd12b3b478e5b2e86998d3785934c71d80505a4d650d72fc8f1a2f4b83c61f9", "role": "CLIENT_MUTE", "short_name": "SS28", "snr": 7.13, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 402, "long_name": "Stone Lion", "next_hop": 138, "num": "0x08b8aa97", "position": {"altitude": 1643, "latitude": 33.526974, "location_source": "LOC_INTERNAL", "longitude": -107.248283, "time_offset_sec": 581}, "public_key_hex": "c7a7d65cd7befa04cc4cdd2a7923f43797fc07eeb7816dd0a71aa4376daa9a8a", "role": "ROUTER", "short_name": "S461", "snr": 5.4, "status": {"status": "offline-soon"}, "telemetry": {"air_util_tx": 0.831, "battery_level": 70, "channel_utilization": 7.46, "uptime_seconds": 510, "voltage": 3.93}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "NOMADSTAR_METEOR_PRO", "last_heard_offset_sec": 585, "long_name": "Dusk Eagle", "next_hop": 53, "num": "0x0942c7fa", "position": {"altitude": 1276, "latitude": 33.564835, "location_source": "LOC_INTERNAL", "longitude": -107.990751, "time_offset_sec": 635}, "public_key_hex": "33d6722868eb0b3446af8787b9d79446a8a3af0a85a50f4e94d7bfcf2567872c", "role": "CLIENT", "short_name": "DW3D", "snr": 1.03, "status": null, "telemetry": {"air_util_tx": 1.126, "battery_level": 84, "channel_utilization": 11.33, "uptime_seconds": 67579, "voltage": 4.056}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 4, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 5824, "long_name": "Sleepy Iguana", "next_hop": 181, "num": "0x09681313", "position": {"altitude": 1536, "latitude": 33.940617, "location_source": "LOC_INTERNAL", "longitude": -107.400953, "time_offset_sec": 5935}, "public_key_hex": "7e768501c7c0b27a253cad9dfe04de9ea9f0fb7178cc52e749613e7a2448aacc", "role": "CLIENT", "short_name": "SPCZ", "snr": 8.54, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 9057, "long_name": "Drifting Bear", "next_hop": 0, "num": "0x099cef2d", "position": {"altitude": 1154, "latitude": 32.927688, "location_source": "LOC_INTERNAL", "longitude": -107.983437, "time_offset_sec": 9311}, "public_key_hex": "df026c53580a0014d8d0b0acf05b0a7699129b38ef54b62a6ad6b459f80cde4c", "role": "CLIENT_BASE", "short_name": "DUM8", "snr": 4.26, "status": null, "telemetry": {"air_util_tx": 0.22, "battery_level": 10, "channel_utilization": 20.01, "uptime_seconds": 4610, "voltage": 3.39}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 5657, "long_name": "Steel Eagle KE0EN", "next_hop": 218, "num": "0x09c2d2c5", "position": {"altitude": 1432, "latitude": 34.093196, "location_source": "LOC_INTERNAL", "longitude": -107.180771, "time_offset_sec": 5761}, "public_key_hex": "4a013f9630e13615cba93620efa713f6eb856dd9a0889ebf6d538a3fc1d8905b", "role": "CLIENT", "short_name": "S7YX", "snr": 3.85, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.252, "battery_level": 83, "channel_utilization": 8.77, "uptime_seconds": 22235, "voltage": 4.047}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 2759, "long_name": "Lunar Crow", "next_hop": 0, "num": "0x09f3a0c9", "position": {"altitude": 1513, "latitude": 32.201649, "location_source": "LOC_INTERNAL", "longitude": -107.870751, "time_offset_sec": 2857}, "public_key_hex": "ffd5dd9578ff4a710f98bd3726af95ddd74c7ed48f6bc326dd8c82fea467c688", "role": "CLIENT", "short_name": "L71T", "snr": 5.65, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.45, "battery_level": 62, "channel_utilization": 12.01, "uptime_seconds": 13126, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 365, "long_name": "Sneaky Yucca", "next_hop": 0, "num": "0x0a227668", "position": {"altitude": 1357, "latitude": 33.858842, "location_source": "LOC_INTERNAL", "longitude": -107.968186, "time_offset_sec": 458}, "public_key_hex": "a82a9214cba439128a6c66746ef3657b91d20818ace487f368054430497cd801", "role": "CLIENT", "short_name": "STUO", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.185, "battery_level": 93, "channel_utilization": 1.96, "uptime_seconds": 304258, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T096", "last_heard_offset_sec": 59, "long_name": "Lone Hawk", "next_hop": 61, "num": "0x0a26c767", "position": {"altitude": 1736, "latitude": 33.066119, "location_source": "LOC_INTERNAL", "longitude": -107.365383, "time_offset_sec": 299}, "public_key_hex": "1325d09f2302a1a82f853963373de3719162f3029523553cacd9a8c8ff924e58", "role": "CLIENT", "short_name": "LUNM", "snr": 5.04, "status": null, "telemetry": {"air_util_tx": 0.599, "battery_level": 26, "channel_utilization": 18.17, "uptime_seconds": 39452, "voltage": 3.534}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 5198, "long_name": "Slow Whale", "next_hop": 0, "num": "0x0a4e9ac7", "position": {"altitude": 1324, "latitude": 33.512009, "location_source": "LOC_INTERNAL", "longitude": -107.240115, "time_offset_sec": 5468}, "public_key_hex": "9f5080010b809a79bf8326674391a223a0ab14ad189d57f1659e8ba88a9910b0", "role": "CLIENT", "short_name": "SVG3", "snr": 7.72, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 6777, "long_name": "Soft Moose", "next_hop": 0, "num": "0x0a5b2072", "position": {"altitude": 1405, "latitude": 33.166582, "location_source": "LOC_INTERNAL", "longitude": -106.571049, "time_offset_sec": 7036}, "public_key_hex": "5dabc625e1757b630efd1bbe1dd2f31089b0e1dfc3929d72e5c45419748b997b", "role": "CLIENT", "short_name": "SDXX", "snr": 9.36, "status": null, "telemetry": {"air_util_tx": 0.91, "battery_level": 19, "channel_utilization": 4.61, "uptime_seconds": 51974, "voltage": 3.471}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 6114, "long_name": "Blue Iguana", "next_hop": 140, "num": "0x0ae73f47", "position": {"altitude": 1565, "latitude": 32.903508, "location_source": "LOC_INTERNAL", "longitude": -107.918895, "time_offset_sec": 6394}, "public_key_hex": "4824b9ca37d9e316d315bb42cb2dedb6d75125da6d11a12a3227a1f60b145f11", "role": "CLIENT", "short_name": "BSL5", "snr": 6.76, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 293, "long_name": "Misty Wolf", "next_hop": 23, "num": "0x0b094c92", "position": {"altitude": 1016, "latitude": 33.315313, "location_source": "LOC_INTERNAL", "longitude": -107.122867, "time_offset_sec": 406}, "public_key_hex": "1d08505017b6456355c7670bd0ce8c6701ea43b67ca338140306ea6afb5a0df7", "role": "CLIENT", "short_name": "MJK1", "snr": 8.08, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 9125, "long_name": "Storm Phoenix", "next_hop": 224, "num": "0x0b24a78e", "position": null, "public_key_hex": "", "role": "ROUTER_LATE", "short_name": "SIFA", "snr": 4.14, "status": null, "telemetry": {"air_util_tx": 0.06, "battery_level": 20, "channel_utilization": 8.81, "uptime_seconds": 94121, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 4, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1016, "long_name": "Giant Doe", "next_hop": 121, "num": "0x0b6940c2", "position": {"altitude": 1321, "latitude": 33.478159, "location_source": "LOC_INTERNAL", "longitude": -107.629302, "time_offset_sec": 1142}, "public_key_hex": "9b2dcb301b031c955820f4ccd600248598d76e606df1e1654374cfe95f426d1c", "role": "SENSOR", "short_name": "GM0W", "snr": 3.34, "status": {"status": "weak-signal"}, "telemetry": {"air_util_tx": 1.146, "battery_level": 57, "channel_utilization": 25.09, "uptime_seconds": 159619, "voltage": 3.813}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1008.0, "iaq": 68, "relative_humidity": 82.96, "temperature": 28.08}, "hops_away": 1, "hw_model": "RAK3312", "last_heard_offset_sec": 8146, "long_name": "Mountain Whale", "next_hop": 18, "num": "0x0bd266b2", "position": null, "public_key_hex": "88d5229035bc6d41e800ce92858bb0a641626aae0415ab68ebce9a716b4608c1", "role": "ROUTER", "short_name": "MNX3", "snr": 3.2, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.49, "battery_level": 16, "channel_utilization": 14.79, "uptime_seconds": 9989, "voltage": 3.444}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 7991, "long_name": "Loud Squirrel", "next_hop": 102, "num": "0x0c008042", "position": {"altitude": 1286, "latitude": 33.407558, "location_source": "LOC_INTERNAL", "longitude": -107.246507, "time_offset_sec": 8012}, "public_key_hex": "dc12d958c362cba44f5e51cd494b2d5146a2bc27a49f00bbe52568b48b12c0b0", "role": "TRACKER", "short_name": "LK99", "snr": 4.49, "status": null, "telemetry": {"air_util_tx": 1.485, "battery_level": 73, "channel_utilization": 28.13, "uptime_seconds": 4958, "voltage": 3.957}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 920, "long_name": "Shady Lynx", "next_hop": 219, "num": "0x0cf9d526", "position": {"altitude": 1597, "latitude": 32.392711, "location_source": "LOC_INTERNAL", "longitude": -107.605544, "time_offset_sec": 1003}, "public_key_hex": "", "role": "CLIENT", "short_name": "S8XM", "snr": 7.37, "status": null, "telemetry": {"air_util_tx": 0.901, "battery_level": 40, "channel_utilization": 7.94, "uptime_seconds": 66704, "voltage": 3.66}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 3355, "long_name": "Sharp Mamba", "next_hop": 0, "num": "0x0cfb3f42", "position": {"altitude": 1362, "latitude": 32.872047, "location_source": "LOC_INTERNAL", "longitude": -106.062756, "time_offset_sec": 3597}, "public_key_hex": "d2466d6c7a0b2fcdbc3e9e031fb15e9823d49974a8827414a95864e60704b09b", "role": "CLIENT", "short_name": "SHHU", "snr": 6.36, "status": null, "telemetry": {"air_util_tx": 0.318, "battery_level": 12, "channel_utilization": 14.33, "uptime_seconds": 240511, "voltage": 3.408}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 4138, "long_name": "Soft Seal", "next_hop": 0, "num": "0x0d1114f7", "position": {"altitude": 1159, "latitude": 32.862239, "location_source": "LOC_INTERNAL", "longitude": -107.364042, "time_offset_sec": 4194}, "public_key_hex": "0904dcbd8806913637e185a58f0a9702fe1dfd7eb1a299752031d53e87f3472e", "role": "CLIENT", "short_name": "🦉", "snr": 1.54, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1014.19, "iaq": 39, "relative_humidity": 31.48, "temperature": 22.47}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 5500, "long_name": "Rough Mole AB6UD", "next_hop": 0, "num": "0x0d1134f2", "position": {"altitude": 1246, "latitude": 32.923274, "location_source": "LOC_INTERNAL", "longitude": -107.365595, "time_offset_sec": 5501}, "public_key_hex": "e6f5ad1ee2cca9af4e6964dd650337302bd9f53d123ec3873458bbafceb4e51d", "role": "CLIENT", "short_name": "R6Q0", "snr": 0.35, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.109, "battery_level": 24, "channel_utilization": 9.18, "uptime_seconds": 305791, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 948, "long_name": "Sneaky Gecko", "next_hop": 0, "num": "0x0d6592a2", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "SM2S", "snr": 0.81, "status": null, "telemetry": {"air_util_tx": 0.139, "battery_level": 92, "channel_utilization": 15.72, "uptime_seconds": 114522, "voltage": 4.128}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 366, "long_name": "Loud Mamba", "next_hop": 0, "num": "0x0d968387", "position": {"altitude": 1407, "latitude": 32.519848, "location_source": "LOC_INTERNAL", "longitude": -107.380676, "time_offset_sec": 417}, "public_key_hex": "", "role": "CLIENT", "short_name": "LC5U", "snr": 4.14, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.571, "battery_level": 100, "channel_utilization": 19.43, "uptime_seconds": 80280, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1008.03, "iaq": 27, "relative_humidity": 63.2, "temperature": 30.0}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 254, "long_name": "Canyon Doe", "next_hop": 0, "num": "0x0da58b20", "position": {"altitude": 1054, "latitude": 33.143337, "location_source": "LOC_INTERNAL", "longitude": -107.818269, "time_offset_sec": 289}, "public_key_hex": "4114b0445f6a57bc0faf565f772acb9571fbbd5d1a7df7755692413b3eb71ce4", "role": "TRACKER", "short_name": "CBZJ", "snr": 10.44, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1007.83, "iaq": 73, "relative_humidity": 47.03, "temperature": 16.81}, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1829, "long_name": "White Pine", "next_hop": 0, "num": "0x0e2eefbc", "position": {"altitude": 1436, "latitude": 33.443858, "location_source": "LOC_INTERNAL", "longitude": -108.82553, "time_offset_sec": 1883}, "public_key_hex": "c7e997350b80f8ac4c89a2e48b6afc0af224c50ed253842f31e4c2e82d7e6dcb", "role": "CLIENT", "short_name": "WSBP", "snr": 7.32, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.15, "iaq": 65, "relative_humidity": 58.13, "temperature": 21.44}, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2998, "long_name": "Black Lion", "next_hop": 25, "num": "0x0e40250b", "position": {"altitude": 1280, "latitude": 33.201427, "location_source": "LOC_INTERNAL", "longitude": -106.820707, "time_offset_sec": 3195}, "public_key_hex": "0c9a4734918a056d180a803e6ca48645062b6b44249dc9ccef860793be97f881", "role": "CLIENT", "short_name": "B0WQ", "snr": 9.36, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.527, "battery_level": 71, "channel_utilization": 16.14, "uptime_seconds": 155116, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 9399, "long_name": "Drowsy Mustang", "next_hop": 214, "num": "0x0ea265d7", "position": {"altitude": 1393, "latitude": 32.898121, "location_source": "LOC_INTERNAL", "longitude": -107.524646, "time_offset_sec": 9491}, "public_key_hex": "", "role": "CLIENT_MUTE", "short_name": "D8ME", "snr": 5.32, "status": {"status": "running"}, "telemetry": {"air_util_tx": 1.48, "battery_level": 65, "channel_utilization": 10.72, "uptime_seconds": 15078, "voltage": 3.885}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 360, "long_name": "Iron Crow", "next_hop": 0, "num": "0x0ef13332", "position": {"altitude": 1469, "latitude": 32.917393, "location_source": "LOC_INTERNAL", "longitude": -106.817302, "time_offset_sec": 485}, "public_key_hex": "b43b345c37ed2ac879d0c1449f7f4a5c10b3cf8cdf5135b2b37014e44b8dbaa6", "role": "CLIENT", "short_name": "I5SF", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.214, "battery_level": 35, "channel_utilization": 29.6, "uptime_seconds": 51980, "voltage": 3.615}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 4082, "long_name": "Smooth Doe", "next_hop": 0, "num": "0x0f446c80", "position": {"altitude": 1122, "latitude": 31.767256, "location_source": "LOC_INTERNAL", "longitude": -106.825891, "time_offset_sec": 4255}, "public_key_hex": "8e0f9b2b699d27476d8b5e5c9e1a5735359eb7b192932dbc107024f5e83b69e1", "role": "CLIENT_MUTE", "short_name": "ST7O", "snr": 3.14, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "WISMESH_TAG", "last_heard_offset_sec": 390, "long_name": "Canyon Phoenix", "next_hop": 165, "num": "0x0f630f75", "position": {"altitude": 1089, "latitude": 33.100863, "location_source": "LOC_INTERNAL", "longitude": -107.714667, "time_offset_sec": 404}, "public_key_hex": "d0fc8f0d06868c85f6e4b9d1efd2d3ed2e8fcb2ca39d0b344bf9bf3a26e7b259", "role": "CLIENT", "short_name": "C20S", "snr": 4.37, "status": null, "telemetry": {"air_util_tx": 0.57, "battery_level": 50, "channel_utilization": 4.35, "uptime_seconds": 237778, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 17446, "long_name": "Lost Sage", "next_hop": 0, "num": "0x0f78f772", "position": {"altitude": 1565, "latitude": 32.065953, "location_source": "LOC_INTERNAL", "longitude": -108.155905, "time_offset_sec": 17681}, "public_key_hex": "4ea922a38c62d176fa256ae06bd26f606d273a33768a338fad8b14427e1b1ffa", "role": "CLIENT", "short_name": "LQ9J", "snr": 7.09, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.13, "iaq": 81, "relative_humidity": 75.96, "temperature": 25.99}, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 1013, "long_name": "Blue Fox", "next_hop": 229, "num": "0x0f8e526f", "position": {"altitude": 1412, "latitude": 32.720316, "location_source": "LOC_INTERNAL", "longitude": -107.264431, "time_offset_sec": 1257}, "public_key_hex": "327554b2882cddbbdd82666aeb0b35b2037f63ca79e616fbbb53668ccbbe8c2b", "role": "ROUTER", "short_name": "B3HK", "snr": 5.69, "status": null, "telemetry": {"air_util_tx": 1.508, "battery_level": 25, "channel_utilization": 21.97, "uptime_seconds": 106202, "voltage": 3.525}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 6, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 2928, "long_name": "Sharp Aspen", "next_hop": 0, "num": "0x0fde1eec", "position": {"altitude": 1449, "latitude": 33.530237, "location_source": "LOC_INTERNAL", "longitude": -107.771161, "time_offset_sec": 3067}, "public_key_hex": "98d7f97f098e04fd3d92350ff9907094ff5f48ef20523280e064d4fdaacd8e16", "role": "CLIENT", "short_name": "SCMN", "snr": 2.42, "status": null, "telemetry": {"air_util_tx": 1.011, "battery_level": 88, "channel_utilization": 9.51, "uptime_seconds": 27684, "voltage": 4.092}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1014.62, "iaq": 72, "relative_humidity": 76.4, "temperature": 19.6}, "hops_away": 0, "hw_model": "NOMADSTAR_METEOR_PRO", "last_heard_offset_sec": 8518, "long_name": "Copper Pony", "next_hop": 0, "num": "0x1018994e", "position": {"altitude": 1570, "latitude": 33.624451, "location_source": "LOC_INTERNAL", "longitude": -107.627157, "time_offset_sec": 8580}, "public_key_hex": "", "role": "ROUTER", "short_name": "CNKI", "snr": 2.18, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 30, "long_name": "Floating Falcon", "next_hop": 0, "num": "0x101b6e63", "position": {"altitude": 1221, "latitude": 33.737624, "location_source": "LOC_INTERNAL", "longitude": -108.391569, "time_offset_sec": 72}, "public_key_hex": "e165537fda9c4c72a40c6c4859db82bc37daff03108de62043fadd3b40f459fe", "role": "SENSOR", "short_name": "FH7Y", "snr": 4.88, "status": null, "telemetry": {"air_util_tx": 0.321, "battery_level": 23, "channel_utilization": 15.8, "uptime_seconds": 186477, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 2121, "long_name": "Copper Otter", "next_hop": 0, "num": "0x10205b63", "position": {"altitude": 1284, "latitude": 34.863075, "location_source": "LOC_INTERNAL", "longitude": -106.550002, "time_offset_sec": 2382}, "public_key_hex": "763052e1aa56f5a160c1d63923414ea597bd0031d639017e64f296dbde851a75", "role": "CLIENT", "short_name": "🌵", "snr": -0.94, "status": null, "telemetry": {"air_util_tx": 1.534, "battery_level": 24, "channel_utilization": 1.95, "uptime_seconds": 6014, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 7778, "long_name": "Black Hawk", "next_hop": 0, "num": "0x10227727", "position": {"altitude": 1462, "latitude": 32.90932, "location_source": "LOC_INTERNAL", "longitude": -107.285806, "time_offset_sec": 7995}, "public_key_hex": "ad0fe604a7094f2f89a7fc987fedd6017b03114ed474791054a31896f9542612", "role": "CLIENT", "short_name": "BB18", "snr": 2.25, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.78, "battery_level": 101, "channel_utilization": 12.64, "uptime_seconds": 1932, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1_EINK", "last_heard_offset_sec": 786, "long_name": "Old Cactus N56DI", "next_hop": 0, "num": "0x10b40519", "position": {"altitude": 1504, "latitude": 33.104311, "location_source": "LOC_INTERNAL", "longitude": -107.434206, "time_offset_sec": 1004}, "public_key_hex": "533b17828a9ede6fa74f3edb846843e8446717435b3a1dc27269e11009bcef6a", "role": "TAK_TRACKER", "short_name": "OCQ8", "snr": 0.49, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.125, "battery_level": 74, "channel_utilization": 17.91, "uptime_seconds": 124718, "voltage": 3.966}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 7537, "long_name": "Green Cedar", "next_hop": 0, "num": "0x10de9aae", "position": {"altitude": 723, "latitude": 33.326766, "location_source": "LOC_INTERNAL", "longitude": -108.003463, "time_offset_sec": 7750}, "public_key_hex": "e2d62f46d725f2949002b1684d3426c529ad503310aa76c51280ec5c806d14b3", "role": "ROUTER", "short_name": "GEJ1", "snr": 2.28, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2688, "long_name": "Black Sage", "next_hop": 0, "num": "0x11cf9223", "position": {"altitude": 1398, "latitude": 32.813263, "location_source": "LOC_INTERNAL", "longitude": -108.097167, "time_offset_sec": 2947}, "public_key_hex": "f2eb8a2e7daa401077ee6974e307733d39f767072e1c5bed2fd8a91c78170e31", "role": "CLIENT", "short_name": "BQUV", "snr": 12.0, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.672, "battery_level": 73, "channel_utilization": 3.24, "uptime_seconds": 243864, "voltage": 3.957}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1004.57, "iaq": 30, "relative_humidity": 35.69, "temperature": 12.18}, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 1969, "long_name": "Frosty Bison", "next_hop": 0, "num": "0x11d59092", "position": null, "public_key_hex": "ecb4eeafca0fa40bed7355c5fd9aa3b1cf3b50a590053b9224b2a3d751320538", "role": "CLIENT", "short_name": "FHZ2", "snr": 4.53, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.48, "battery_level": 42, "channel_utilization": 15.48, "uptime_seconds": 88977, "voltage": 3.678}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 5949, "long_name": "Wild Mustang", "next_hop": 0, "num": "0x11d7f212", "position": {"altitude": 1024, "latitude": 33.272749, "location_source": "LOC_INTERNAL", "longitude": -107.297537, "time_offset_sec": 6240}, "public_key_hex": "f54d9988a8cd53c53ee267318e0cae68e4093e5e2e6c0ea6b958e62dcf54a6a3", "role": "TRACKER", "short_name": "W2A5", "snr": 1.3, "status": {"status": "running"}, "telemetry": {"air_util_tx": 1.042, "battery_level": 39, "channel_utilization": 14.9, "uptime_seconds": 17083, "voltage": 3.651}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 3414, "long_name": "Storm Crane", "next_hop": 0, "num": "0x11fcd2c7", "position": null, "public_key_hex": "cb700ea5209ced2ce7fb56e78498359db8d0b212bf344767233e6a16d4ad8c54", "role": "CLIENT", "short_name": "S5DG", "snr": -1.79, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1017.06, "iaq": 56, "relative_humidity": 64.5, "temperature": 21.15}, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 1961, "long_name": "Tiny Tortoise", "next_hop": 0, "num": "0x124293c9", "position": {"altitude": 1593, "latitude": 33.348839, "location_source": "LOC_INTERNAL", "longitude": -106.734719, "time_offset_sec": 2028}, "public_key_hex": "", "role": "CLIENT", "short_name": "🐢", "snr": 0.06, "status": null, "telemetry": {"air_util_tx": 0.603, "battery_level": 29, "channel_utilization": 4.14, "uptime_seconds": 83202, "voltage": 3.561}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1021.97, "iaq": 55, "relative_humidity": 47.9, "temperature": 27.96}, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3815, "long_name": "Quick Lynx", "next_hop": 0, "num": "0x12793b94", "position": null, "public_key_hex": "4b71268babbada3e398b200e02f4f502412aba779546f65b4f1d6390e3c11c71", "role": "CLIENT", "short_name": "🦅", "snr": 1.71, "status": null, "telemetry": {"air_util_tx": 0.15, "battery_level": 24, "channel_utilization": 6.86, "uptime_seconds": 37207, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1008.45, "iaq": 28, "relative_humidity": 29.78, "temperature": 24.0}, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 1265, "long_name": "Gold Aspen", "next_hop": 0, "num": "0x12b1a994", "position": null, "public_key_hex": "c10646601f2cc6d352787547ab609271a62f40eb40f5ec3ebb4cee0b877a7a94", "role": "CLIENT", "short_name": "GAUX", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.824, "battery_level": 72, "channel_utilization": 14.07, "uptime_seconds": 78788, "voltage": 3.948}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 4582, "long_name": "Rough Sage W59QH", "next_hop": 111, "num": "0x134b790b", "position": {"altitude": 1199, "latitude": 33.051761, "location_source": "LOC_INTERNAL", "longitude": -107.200236, "time_offset_sec": 4881}, "public_key_hex": "5505535ae415d55b775ea3d8677bcc16a4362ce1534f3d95be20065271f9f5b1", "role": "CLIENT", "short_name": "RODU", "snr": 9.9, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 671, "long_name": "Frozen Elk", "next_hop": 0, "num": "0x1356e5a7", "position": {"altitude": 1282, "latitude": 32.367066, "location_source": "LOC_INTERNAL", "longitude": -107.325336, "time_offset_sec": 689}, "public_key_hex": "ba1368b21e97bc91b19adfbf5f0031ce456ff07aa56d6a8b6eec0ccc96799047", "role": "TAK_TRACKER", "short_name": "FUQL", "snr": 11.9, "status": null, "telemetry": {"air_util_tx": 0.443, "battery_level": 49, "channel_utilization": 6.68, "uptime_seconds": 41398, "voltage": 3.741}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 13755, "long_name": "Storm Moose", "next_hop": 0, "num": "0x1379b6f8", "position": {"altitude": 1283, "latitude": 33.488927, "location_source": "LOC_INTERNAL", "longitude": -107.17989, "time_offset_sec": 13977}, "public_key_hex": "94bcb6ebe3bc3ec012f4dbcf228e3439668758ca425184c26c68128fad5552b1", "role": "ROUTER_LATE", "short_name": "SO4X", "snr": 7.42, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.385, "battery_level": 36, "channel_utilization": 20.65, "uptime_seconds": 20292, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 3390, "long_name": "Wild Shark", "next_hop": 0, "num": "0x13aa96e0", "position": null, "public_key_hex": "522f72c0a046e007baedf483b49090d229c6cd95555aa3a8a9c4a72ff6bbffd0", "role": "CLIENT", "short_name": "WXOE", "snr": 8.25, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.552, "battery_level": 101, "channel_utilization": 10.44, "uptime_seconds": 28836, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 572, "long_name": "Slow Tortoise KE8BZ", "next_hop": 0, "num": "0x13c260ca", "position": {"altitude": 988, "latitude": 32.950608, "location_source": "LOC_INTERNAL", "longitude": -107.691689, "time_offset_sec": 751}, "public_key_hex": "de56d298c6d8b7322ebceeeaa5b5c220cd8f518819cb08fb98c054953ac0e43a", "role": "CLIENT", "short_name": "SJEL", "snr": 10.47, "status": null, "telemetry": {"air_util_tx": 2.227, "battery_level": 49, "channel_utilization": 17.7, "uptime_seconds": 95503, "voltage": 3.741}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 3627, "long_name": "Burning Moose", "next_hop": 11, "num": "0x1418f8cd", "position": {"altitude": 1294, "latitude": 33.659566, "location_source": "LOC_INTERNAL", "longitude": -108.238162, "time_offset_sec": 3734}, "public_key_hex": "22c0a92b37e0d813e0606b32cebbe17031ee9ab24370bfa0ec5c62c244fcca3e", "role": "ROUTER", "short_name": "🌊", "snr": 9.05, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 6908, "long_name": "Green Iguana", "next_hop": 189, "num": "0x14344f00", "position": {"altitude": 829, "latitude": 32.897047, "location_source": "LOC_INTERNAL", "longitude": -107.223164, "time_offset_sec": 7051}, "public_key_hex": "d1cbe0db99baa5af5dc3179d2bbdd50c2db5f98b1c338be18ec2c55f73836d38", "role": "CLIENT", "short_name": "GHVH", "snr": 3.87, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.306, "battery_level": 30, "channel_utilization": 12.84, "uptime_seconds": 72917, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 1071, "long_name": "Tall Wolf", "next_hop": 0, "num": "0x14d33250", "position": {"altitude": 1562, "latitude": 32.694901, "location_source": "LOC_INTERNAL", "longitude": -107.508362, "time_offset_sec": 1246}, "public_key_hex": "081e7a86105059118e56233bc00bcbd77dde78a465ea4759bef00ab5ca3e0181", "role": "CLIENT", "short_name": "TH3H", "snr": 2.73, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.842, "battery_level": 27, "channel_utilization": 8.35, "uptime_seconds": 56438, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 4481, "long_name": "Wandering Moose", "next_hop": 0, "num": "0x14eb1f2d", "position": {"altitude": 1654, "latitude": 33.730089, "location_source": "LOC_INTERNAL", "longitude": -107.361317, "time_offset_sec": 4625}, "public_key_hex": "8a4a31c8023223e5c508b31f3829c13008e82a957c1d15c38be451b797e3d8b5", "role": "CLIENT", "short_name": "W94X", "snr": 8.99, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.146, "battery_level": 89, "channel_utilization": 26.52, "uptime_seconds": 61941, "voltage": 4.101}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.5, "iaq": 76, "relative_humidity": 67.21, "temperature": 28.61}, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 9181, "long_name": "Silver Bear", "next_hop": 0, "num": "0x15008bbd", "position": {"altitude": 1303, "latitude": 33.304292, "location_source": "LOC_INTERNAL", "longitude": -106.704279, "time_offset_sec": 9318}, "public_key_hex": "e0e5fc0c2810e96cbdbaa94273448a433a56f85d833446f4a78dd567f24564af", "role": "CLIENT", "short_name": "SV3M", "snr": 5.67, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.252, "battery_level": 44, "channel_utilization": 10.76, "uptime_seconds": 20110, "voltage": 3.696}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1_EINK", "last_heard_offset_sec": 12488, "long_name": "Dawn Bison", "next_hop": 0, "num": "0x15079a96", "position": {"altitude": 1142, "latitude": 33.178914, "location_source": "LOC_INTERNAL", "longitude": -106.882896, "time_offset_sec": 12552}, "public_key_hex": "b19b49ec63540cbb0683e60d45179dcab274743512d5e9c81351057c625f031b", "role": "CLIENT", "short_name": "🗻", "snr": 4.12, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4732, "long_name": "Lost Oak", "next_hop": 85, "num": "0x151e3fb5", "position": {"altitude": 1556, "latitude": 33.030756, "location_source": "LOC_INTERNAL", "longitude": -107.105935, "time_offset_sec": 4801}, "public_key_hex": "b0c3b2db380cf1b42a013974b3936b6d8a03b9e36bee94abd5ee7030ed151f45", "role": "CLIENT", "short_name": "LZTS", "snr": 7.17, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1009.79, "iaq": 51, "relative_humidity": 27.03, "temperature": 12.69}, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 5740, "long_name": "Bright Juniper", "next_hop": 0, "num": "0x15dc23b2", "position": {"altitude": 868, "latitude": 32.860217, "location_source": "LOC_INTERNAL", "longitude": -108.123223, "time_offset_sec": 5988}, "public_key_hex": "cd14d907287a83262d5f58b428faad9d6f79832399ad9f1e38853c799756ae09", "role": "CLIENT", "short_name": "BS7U", "snr": 6.24, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.414, "battery_level": 39, "channel_utilization": 8.47, "uptime_seconds": 112298, "voltage": 3.651}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 6, "environment": {"barometric_pressure": 1014.5, "iaq": 107, "relative_humidity": 91.9, "temperature": 22.23}, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 510, "long_name": "Floating Fox", "next_hop": 102, "num": "0x16108cd9", "position": {"altitude": 1198, "latitude": 33.289005, "location_source": "LOC_INTERNAL", "longitude": -107.249121, "time_offset_sec": 649}, "public_key_hex": "4cdfc9b5d15351036ad5f84ff783a1ce059cdef45e08c87252221687624e4d51", "role": "CLIENT", "short_name": "FO2G", "snr": 7.94, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.415, "battery_level": 46, "channel_utilization": 6.21, "uptime_seconds": 27755, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 555, "long_name": "River Turtle", "next_hop": 0, "num": "0x162f1f2d", "position": {"altitude": 1048, "latitude": 33.456724, "location_source": "LOC_INTERNAL", "longitude": -107.166742, "time_offset_sec": 680}, "public_key_hex": "96b2115da7d505865a41d707f058f860536de871f4dc1a1ddfa730939dd14e4a", "role": "CLIENT_HIDDEN", "short_name": "RIBX", "snr": 10.55, "status": null, "telemetry": {"air_util_tx": 0.271, "battery_level": 95, "channel_utilization": 2.71, "uptime_seconds": 58824, "voltage": 4.155}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "THINKNODE_M5", "last_heard_offset_sec": 3463, "long_name": "Steel Trout", "next_hop": 183, "num": "0x163f2d40", "position": {"altitude": 1354, "latitude": 32.863185, "location_source": "LOC_INTERNAL", "longitude": -108.147876, "time_offset_sec": 3725}, "public_key_hex": "41838ad0fc0e569398ea924f689c3daa2d1057f363d35c8b444e6c536fe4d24f", "role": "CLIENT", "short_name": "SC17", "snr": 12.0, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 232, "long_name": "Whispering Lynx", "next_hop": 0, "num": "0x167494c0", "position": {"altitude": 1556, "latitude": 33.115465, "location_source": "LOC_INTERNAL", "longitude": -107.426901, "time_offset_sec": 281}, "public_key_hex": "c2478ff9f49a90e70290f8027b4c8e3a64849b721419e698728b4c6c1d1f0666", "role": "CLIENT", "short_name": "WFFL", "snr": 4.16, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 3.127, "battery_level": 54, "channel_utilization": 14.67, "uptime_seconds": 49601, "voltage": 3.786}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 1560, "long_name": "Black Cougar", "next_hop": 28, "num": "0x16897d73", "position": {"altitude": 1673, "latitude": 32.91074, "location_source": "LOC_INTERNAL", "longitude": -108.369742, "time_offset_sec": 1624}, "public_key_hex": "c112995c30570dcea089ca8cc09e113877c301f2a02fa50cf3de16b175006618", "role": "CLIENT", "short_name": "BYO0", "snr": 8.38, "status": null, "telemetry": {"air_util_tx": 0.664, "battery_level": 14, "channel_utilization": 6.06, "uptime_seconds": 212294, "voltage": 3.426}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 2627, "long_name": "Storm Elk", "next_hop": 95, "num": "0x16b275f9", "position": null, "public_key_hex": "2a82e18a602e00282dedae0ec94bc011f1f63e6501c1154fdf4088e8f9e66221", "role": "CLIENT", "short_name": "SD28", "snr": 12.0, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.022, "battery_level": 96, "channel_utilization": 14.35, "uptime_seconds": 44369, "voltage": 4.164}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 4213, "long_name": "Blue Lion", "next_hop": 111, "num": "0x16b2a0d6", "position": {"altitude": 1426, "latitude": 32.811334, "location_source": "LOC_INTERNAL", "longitude": -107.621788, "time_offset_sec": 4332}, "public_key_hex": "8539ed4565ae84a1422af41bbf3b9931250e817a1afaced69f213a6deba68cd7", "role": "CLIENT", "short_name": "BOU8", "snr": 6.59, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1223, "long_name": "Wild Badger", "next_hop": 184, "num": "0x16c3bc1e", "position": {"altitude": 1210, "latitude": 31.911923, "location_source": "LOC_INTERNAL", "longitude": -106.914223, "time_offset_sec": 1415}, "public_key_hex": "9b5a6fbbad28e1bb34255eb4e1c06ebae5112d6865efe8f0f7300e8e615fcecd", "role": "CLIENT", "short_name": "WJIU", "snr": 8.91, "status": null, "telemetry": {"air_util_tx": 0.308, "battery_level": 68, "channel_utilization": 14.45, "uptime_seconds": 68262, "voltage": 3.912}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 3751, "long_name": "Lost Seal KQ5CO", "next_hop": 125, "num": "0x174ad192", "position": {"altitude": 1619, "latitude": 33.035231, "location_source": "LOC_INTERNAL", "longitude": -106.344659, "time_offset_sec": 3887}, "public_key_hex": "60c3cf0a8a24067b3dd13f67bf5fb744a064eff33318446e69a7173025035ba6", "role": "CLIENT", "short_name": "L3G4", "snr": 8.3, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.595, "battery_level": 68, "channel_utilization": 5.31, "uptime_seconds": 44253, "voltage": 3.912}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 3105, "long_name": "Dusk Bear", "next_hop": 0, "num": "0x1766b643", "position": null, "public_key_hex": "2a662dddcc43dbaf9307f399f96979586ec89075447f8dcd8d0770d24d8bb8c1", "role": "CLIENT", "short_name": "D06J", "snr": 2.87, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.311, "battery_level": 90, "channel_utilization": 23.58, "uptime_seconds": 63789, "voltage": 4.11}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 1090, "long_name": "Soft Mesa", "next_hop": 40, "num": "0x17e79e67", "position": {"altitude": 1287, "latitude": 32.365261, "location_source": "LOC_INTERNAL", "longitude": -106.634547, "time_offset_sec": 1289}, "public_key_hex": "ece402bde0b1a1d0d81cf6a77bb47ed8cdea95fe5c572fb26bb0e0be659b0b1d", "role": "CLIENT", "short_name": "SUXH", "snr": 6.42, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.641, "battery_level": 17, "channel_utilization": 20.0, "uptime_seconds": 1774, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 6549, "long_name": "Fast Pike", "next_hop": 0, "num": "0x18315641", "position": {"altitude": 1600, "latitude": 33.22812, "location_source": "LOC_INTERNAL", "longitude": -106.528869, "time_offset_sec": 6792}, "public_key_hex": "1a028f6e546ff000ccd3e5b381ea64df4a7c67fe8e48a3a7a5e7a6b5e6f31954", "role": "TRACKER", "short_name": "🌙", "snr": -1.78, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 233, "long_name": "Drowsy Beaver", "next_hop": 0, "num": "0x1879f157", "position": {"altitude": 1403, "latitude": 32.948675, "location_source": "LOC_INTERNAL", "longitude": -107.057998, "time_offset_sec": 236}, "public_key_hex": "69673da7dbee9e58d0582faf761ff65d3f53b504871de416fd3cd4bf756fb02b", "role": "CLIENT", "short_name": "D72I", "snr": 9.62, "status": null, "telemetry": {"air_util_tx": 0.401, "battery_level": 36, "channel_utilization": 35.24, "uptime_seconds": 96943, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 7571, "long_name": "Smooth Otter", "next_hop": 0, "num": "0x18e8f8e8", "position": {"altitude": 1321, "latitude": 32.871304, "location_source": "LOC_INTERNAL", "longitude": -106.837591, "time_offset_sec": 7854}, "public_key_hex": "", "role": "CLIENT", "short_name": "SWO2", "snr": 3.69, "status": {"status": "low-batt"}, "telemetry": {"air_util_tx": 0.199, "battery_level": 96, "channel_utilization": 2.78, "uptime_seconds": 172071, "voltage": 4.164}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1016.31, "iaq": 37, "relative_humidity": 87.49, "temperature": 33.24}, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 18931, "long_name": "Roving Falcon", "next_hop": 0, "num": "0x18ef3676", "position": null, "public_key_hex": "e7c21800cd0080b0283e471d96c9145398f52b79584122317b54c691dbb7f7f2", "role": "CLIENT", "short_name": "🦅", "snr": 4.74, "status": null, "telemetry": {"air_util_tx": 0.98, "battery_level": 25, "channel_utilization": 27.08, "uptime_seconds": 101477, "voltage": 3.525}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 994.67, "iaq": 57, "relative_humidity": 50.76, "temperature": 11.41}, "hops_away": 1, "hw_model": "T_ECHO", "last_heard_offset_sec": 3752, "long_name": "Wandering Adder", "next_hop": 201, "num": "0x1988381c", "position": {"altitude": 1575, "latitude": 33.57496, "location_source": "LOC_INTERNAL", "longitude": -107.855479, "time_offset_sec": 3771}, "public_key_hex": "9309172700d9b8c4dcdbfb6cb9a70f1667e3d1d4a63fa2f79b25c97c1fb27e78", "role": "CLIENT", "short_name": "W19E", "snr": 5.62, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 2950, "long_name": "Short Colt", "next_hop": 216, "num": "0x19f3157f", "position": {"altitude": 1615, "latitude": 32.464438, "location_source": "LOC_INTERNAL", "longitude": -107.616346, "time_offset_sec": 3081}, "public_key_hex": "eb6cfc06557874a6d463e4f4f2e108734d4a480588a123874b01145932dd322a", "role": "CLIENT", "short_name": "SG5Q", "snr": -0.24, "status": null, "telemetry": {"air_util_tx": 0.085, "battery_level": 23, "channel_utilization": 5.55, "uptime_seconds": 85090, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1780, "long_name": "Old Phoenix", "next_hop": 0, "num": "0x1a12e784", "position": {"altitude": 1200, "latitude": 33.519889, "location_source": "LOC_INTERNAL", "longitude": -107.338351, "time_offset_sec": 1808}, "public_key_hex": "d9ceee6f3c4b4da117cb125d2214bbd093339914243306a487dd72a3268df1d8", "role": "CLIENT", "short_name": "🐝", "snr": 6.02, "status": null, "telemetry": {"air_util_tx": 0.713, "battery_level": 62, "channel_utilization": 0.76, "uptime_seconds": 46755, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 181, "long_name": "Found Raven", "next_hop": 0, "num": "0x1b3b65e9", "position": {"altitude": 1293, "latitude": 33.288548, "location_source": "LOC_INTERNAL", "longitude": -106.793415, "time_offset_sec": 332}, "public_key_hex": "16abe3f61fba13eecc05937c951b3dc75f49c7a91b931f65cb78e51b71347a66", "role": "CLIENT", "short_name": "FGB8", "snr": 8.32, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 128, "long_name": "Tall Crow", "next_hop": 166, "num": "0x1b3dc88d", "position": {"altitude": 1529, "latitude": 33.179202, "location_source": "LOC_INTERNAL", "longitude": -107.497106, "time_offset_sec": 169}, "public_key_hex": "03eb9d64485bf32d9e0c759235d16d583bdd1ab21dea084426d8f84683de1d3f", "role": "CLIENT", "short_name": "TVOT", "snr": 7.57, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.232, "battery_level": 43, "channel_utilization": 16.23, "uptime_seconds": 62860, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2400, "long_name": "Storm Moose", "next_hop": 0, "num": "0x1b96157a", "position": {"altitude": 1109, "latitude": 32.378496, "location_source": "LOC_INTERNAL", "longitude": -107.954423, "time_offset_sec": 2652}, "public_key_hex": "6f495139fa0535f498dd4e452971c3b048303ef830853b0775562372d0aed5ef", "role": "CLIENT", "short_name": "SVDY", "snr": 3.46, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 660, "long_name": "River Adder", "next_hop": 23, "num": "0x1bb73d04", "position": {"altitude": 1641, "latitude": 33.68275, "location_source": "LOC_INTERNAL", "longitude": -106.336486, "time_offset_sec": 729}, "public_key_hex": "00d33760c0ae44ec4ed815ed2f8fb856de3dc8cba6d4a3fe87e864bb163c21fc", "role": "CLIENT", "short_name": "🦇", "snr": 8.36, "status": {"status": "weak-signal"}, "telemetry": {"air_util_tx": 0.259, "battery_level": 16, "channel_utilization": 10.86, "uptime_seconds": 148515, "voltage": 3.444}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1024.25, "iaq": 35, "relative_humidity": 29.15, "temperature": 10.43}, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 281, "long_name": "Tall Sage", "next_hop": 0, "num": "0x1bb8ec2e", "position": {"altitude": 1531, "latitude": 32.77112, "location_source": "LOC_INTERNAL", "longitude": -108.092313, "time_offset_sec": 401}, "public_key_hex": "", "role": "CLIENT", "short_name": "TYN9", "snr": 5.06, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.803, "battery_level": 50, "channel_utilization": 15.33, "uptime_seconds": 214193, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 5105, "long_name": "Desert Crane", "next_hop": 0, "num": "0x1c5d1282", "position": {"altitude": 1015, "latitude": 32.714988, "location_source": "LOC_INTERNAL", "longitude": -107.149688, "time_offset_sec": 5361}, "public_key_hex": "31ac1d441f3a1497f3fe0c690feb1be2c7e1ae206e75076adb0266cbb3aa6db4", "role": "CLIENT", "short_name": "DPH4", "snr": 4.23, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.329, "battery_level": 79, "channel_utilization": 24.0, "uptime_seconds": 118737, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 1510, "long_name": "Red Adder", "next_hop": 0, "num": "0x1c65ab38", "position": {"altitude": 1119, "latitude": 32.218937, "location_source": "LOC_INTERNAL", "longitude": -107.683511, "time_offset_sec": 1670}, "public_key_hex": "526c2de137bac9ced28684319ac3c88652bec2857257494a88ce4953cde8f35d", "role": "ROUTER_LATE", "short_name": "RCQ5", "snr": 5.32, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 1734, "long_name": "Silent Owl", "next_hop": 0, "num": "0x1cd35371", "position": null, "public_key_hex": "760e3df9c2c870447ce712166b29f524bfef1f96d810b291ac9fea3a958d7bf5", "role": "CLIENT", "short_name": "SQ2L", "snr": 4.4, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2380, "long_name": "Shady Viper", "next_hop": 35, "num": "0x1d034814", "position": {"altitude": 1558, "latitude": 32.964971, "location_source": "LOC_INTERNAL", "longitude": -106.457279, "time_offset_sec": 2402}, "public_key_hex": "e5942d09ce2a6eb922b60ce70af7f117c247e8e31b9f8f86beab1e90557ccfbc", "role": "CLIENT", "short_name": "SDKU", "snr": 3.29, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.374, "battery_level": 83, "channel_utilization": 4.34, "uptime_seconds": 52904, "voltage": 4.047}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_ECHO", "last_heard_offset_sec": 6228, "long_name": "White Hawk", "next_hop": 186, "num": "0x1d250bf1", "position": {"altitude": 1580, "latitude": 33.745509, "location_source": "LOC_INTERNAL", "longitude": -106.22969, "time_offset_sec": 6390}, "public_key_hex": "34e2a11726966b49cadf79e782bb6411b20db72dc599384e90036ec2aa948b5f", "role": "CLIENT", "short_name": "🌲", "snr": 6.15, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.717, "battery_level": 69, "channel_utilization": 17.24, "uptime_seconds": 4879, "voltage": 3.921}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 1115, "long_name": "Silent Hare", "next_hop": 104, "num": "0x1d7b308f", "position": {"altitude": 1699, "latitude": 32.964606, "location_source": "LOC_INTERNAL", "longitude": -106.834004, "time_offset_sec": 1146}, "public_key_hex": "7d6fc2a73a3613727447a5213e5b28f2d2a6daf1bc9d37fb85af98f924060068", "role": "CLIENT", "short_name": "SEF4", "snr": 9.34, "status": null, "telemetry": {"air_util_tx": 0.141, "battery_level": 19, "channel_utilization": 7.71, "uptime_seconds": 24330, "voltage": 3.471}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 3021, "long_name": "Dusk Ridge", "next_hop": 0, "num": "0x1d8a404d", "position": {"altitude": 1272, "latitude": 32.667972, "location_source": "LOC_INTERNAL", "longitude": -107.58155, "time_offset_sec": 3245}, "public_key_hex": "", "role": "SENSOR", "short_name": "DA2X", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.123, "battery_level": 77, "channel_utilization": 8.91, "uptime_seconds": 100385, "voltage": 3.993}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 7594, "long_name": "Loud Moose KE2CF", "next_hop": 0, "num": "0x1d922594", "position": {"altitude": 1512, "latitude": 33.685806, "location_source": "LOC_INTERNAL", "longitude": -106.311204, "time_offset_sec": 7624}, "public_key_hex": "668759f4208b636bc246eb4c674b149e6580afba036d0521aa4bd644f533016d", "role": "CLIENT", "short_name": "🦋", "snr": 8.05, "status": {"status": "online"}, "telemetry": {"air_util_tx": 1.086, "battery_level": 87, "channel_utilization": 10.32, "uptime_seconds": 53171, "voltage": 4.083}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1005.76, "iaq": 48, "relative_humidity": 84.51, "temperature": 25.52}, "hops_away": 2, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 390, "long_name": "Dusk Falcon", "next_hop": 90, "num": "0x1e48de96", "position": {"altitude": 1754, "latitude": 32.922495, "location_source": "LOC_INTERNAL", "longitude": -107.761571, "time_offset_sec": 566}, "public_key_hex": "9cfad118faa52d6a962cfe920c3223a2435ed86716ec4fff20ee094bc3be9247", "role": "CLIENT", "short_name": "DSY7", "snr": 8.44, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.288, "battery_level": 65, "channel_utilization": 6.55, "uptime_seconds": 72604, "voltage": 3.885}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 4374, "long_name": "Silver Trout", "next_hop": 24, "num": "0x1e55127e", "position": null, "public_key_hex": "fad8bd37ec2fd7cb5f22e6c9bd0d59315ce728a1809408904587d3ee07c0de2c", "role": "CLIENT", "short_name": "SAGX", "snr": 2.95, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.309, "battery_level": 58, "channel_utilization": 12.57, "uptime_seconds": 5476, "voltage": 3.822}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 2906, "long_name": "Floating Salmon", "next_hop": 178, "num": "0x1ec65817", "position": {"altitude": 1642, "latitude": 32.054247, "location_source": "LOC_INTERNAL", "longitude": -107.714698, "time_offset_sec": 2991}, "public_key_hex": "2eece35b6bbf4844a5b4fa626cf6b911072f493897cbdac4dc6b51c9cdbac750", "role": "CLIENT", "short_name": "FQR6", "snr": 0.63, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1003.98, "iaq": 89, "relative_humidity": 93.47, "temperature": 35.52}, "hops_away": 4, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1356, "long_name": "Steel Lion", "next_hop": 70, "num": "0x1edcadc8", "position": {"altitude": 1132, "latitude": 32.809096, "location_source": "LOC_INTERNAL", "longitude": -108.059756, "time_offset_sec": 1643}, "public_key_hex": "", "role": "CLIENT_MUTE", "short_name": "🔥", "snr": 9.65, "status": null, "telemetry": {"air_util_tx": 1.187, "battery_level": 12, "channel_utilization": 13.29, "uptime_seconds": 8597, "voltage": 3.408}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1011.68, "iaq": 0, "relative_humidity": 85.78, "temperature": 20.85}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 19869, "long_name": "Quick Colt", "next_hop": 0, "num": "0x1f3c099d", "position": {"altitude": 1528, "latitude": 33.641254, "location_source": "LOC_INTERNAL", "longitude": -107.003798, "time_offset_sec": 19950}, "public_key_hex": "a93259deaa48ea388df51930b660b4db7ad3205f39fdaa796cada03c5f1d94ca", "role": "CLIENT", "short_name": "Q1T3", "snr": 7.01, "status": null, "telemetry": {"air_util_tx": 1.197, "battery_level": 22, "channel_utilization": 2.57, "uptime_seconds": 17868, "voltage": 3.498}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 4696, "long_name": "Green Owl", "next_hop": 0, "num": "0x1fa1ecc4", "position": {"altitude": 1704, "latitude": 33.608806, "location_source": "LOC_INTERNAL", "longitude": -107.078775, "time_offset_sec": 4921}, "public_key_hex": "d8f7463ef6088318f1a337f9d78745f2414d7a5e1ef74a7b3a027f11a21a5b22", "role": "SENSOR", "short_name": "G70L", "snr": 4.43, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.747, "battery_level": 94, "channel_utilization": 42.31, "uptime_seconds": 40259, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.37, "iaq": 88, "relative_humidity": 39.53, "temperature": 19.13}, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 2032, "long_name": "Hidden Cedar", "next_hop": 153, "num": "0x1fd14395", "position": {"altitude": 1345, "latitude": 34.041731, "location_source": "LOC_INTERNAL", "longitude": -107.545165, "time_offset_sec": 2280}, "public_key_hex": "d49a566319a2b467494d96d04c294b9b0f25f3e517570b3ef67921e55391baf4", "role": "CLIENT", "short_name": "HZUZ", "snr": -3.41, "status": null, "telemetry": {"air_util_tx": 1.013, "battery_level": 59, "channel_utilization": 17.63, "uptime_seconds": 11804, "voltage": 3.831}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 3757, "long_name": "Wandering Beaver", "next_hop": 0, "num": "0x1ff10642", "position": {"altitude": 1336, "latitude": 33.635048, "location_source": "LOC_INTERNAL", "longitude": -108.082046, "time_offset_sec": 3847}, "public_key_hex": "1d69bdcc66ded4d1fd928233ff5e4a69dfb31c3e0def2e355642a4c02a066c10", "role": "CLIENT", "short_name": "WC3M", "snr": 11.11, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 8655, "long_name": "Old Owl", "next_hop": 0, "num": "0x1ff9fc94", "position": {"altitude": 1630, "latitude": 32.689108, "location_source": "LOC_INTERNAL", "longitude": -107.204299, "time_offset_sec": 8694}, "public_key_hex": "", "role": "CLIENT_MUTE", "short_name": "OEFS", "snr": 6.12, "status": null, "telemetry": {"air_util_tx": 0.495, "battery_level": 35, "channel_utilization": 25.26, "uptime_seconds": 67098, "voltage": 3.615}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 5112, "long_name": "Black Cougar", "next_hop": 58, "num": "0x20584ab0", "position": {"altitude": 1650, "latitude": 32.332627, "location_source": "LOC_INTERNAL", "longitude": -106.842898, "time_offset_sec": 5277}, "public_key_hex": "24fb486fdca3f123deb52e67730c80d56e73da33f0567a5a9bce05dd7a9ba977", "role": "ROUTER", "short_name": "BCZC", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.388, "battery_level": 46, "channel_utilization": 11.56, "uptime_seconds": 31821, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1423, "long_name": "Sky Doe", "next_hop": 25, "num": "0x205d8291", "position": {"altitude": 1394, "latitude": 33.553239, "location_source": "LOC_INTERNAL", "longitude": -106.866388, "time_offset_sec": 1523}, "public_key_hex": "a8cabf3339c05e04fe61bf45c061bb0bcd2d724d58d6817a9577e9ee08d203a1", "role": "CLIENT", "short_name": "S7B4", "snr": 10.74, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.014, "battery_level": 93, "channel_utilization": 6.16, "uptime_seconds": 1547, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1231, "long_name": "Steel Juniper", "next_hop": 0, "num": "0x21033a28", "position": {"altitude": 1264, "latitude": 33.356136, "location_source": "LOC_INTERNAL", "longitude": -106.614493, "time_offset_sec": 1239}, "public_key_hex": "f2a9858f9df95595e2297da50cd6ff39f6dc6a98e95a3d1301ccf60268dcc006", "role": "CLIENT", "short_name": "SIMB", "snr": 2.0, "status": null, "telemetry": {"air_util_tx": 0.783, "battery_level": 101, "channel_utilization": 4.42, "uptime_seconds": 38270, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 5800, "long_name": "Gold Pony", "next_hop": 90, "num": "0x217fcefe", "position": {"altitude": 1327, "latitude": 33.145461, "location_source": "LOC_INTERNAL", "longitude": -106.737792, "time_offset_sec": 5964}, "public_key_hex": "e2f5c1574f518f68f6feb70ec37f88df48bcd397b0de92f000afe8f3aefb38d3", "role": "CLIENT", "short_name": "GMEF", "snr": 8.53, "status": null, "telemetry": {"air_util_tx": 0.161, "battery_level": 88, "channel_utilization": 24.95, "uptime_seconds": 202680, "voltage": 4.092}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SENSECAP_INDICATOR", "last_heard_offset_sec": 530, "long_name": "Iron Yucca", "next_hop": 0, "num": "0x218bfe2c", "position": {"altitude": 1722, "latitude": 33.303433, "location_source": "LOC_INTERNAL", "longitude": -106.970972, "time_offset_sec": 647}, "public_key_hex": "ed244b20dc77f39a789646b51e74048b10380d945510652c1681a60b27a05cb9", "role": "CLIENT", "short_name": "IZ30", "snr": 10.09, "status": null, "telemetry": {"air_util_tx": 2.038, "battery_level": 43, "channel_utilization": 5.35, "uptime_seconds": 84598, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 4028, "long_name": "Desert Yucca", "next_hop": 216, "num": "0x22152f01", "position": {"altitude": 1490, "latitude": 32.902735, "location_source": "LOC_INTERNAL", "longitude": -108.083973, "time_offset_sec": 4073}, "public_key_hex": "4b59cc1528251d21d567bf07f1c171c781b9ffe3c08fa95446a7b3d58e8107a6", "role": "CLIENT_MUTE", "short_name": "🦋", "snr": 9.79, "status": null, "telemetry": {"air_util_tx": 0.558, "battery_level": 64, "channel_utilization": 13.37, "uptime_seconds": 84244, "voltage": 3.876}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 3662, "long_name": "New Cobra", "next_hop": 252, "num": "0x225663cf", "position": {"altitude": 1321, "latitude": 33.636697, "location_source": "LOC_INTERNAL", "longitude": -107.268583, "time_offset_sec": 3843}, "public_key_hex": "35b56c0424b193ef053313349bcae772fce851ea41d3dccd93597a98601f2654", "role": "CLIENT", "short_name": "🐢", "snr": 7.75, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.601, "battery_level": 80, "channel_utilization": 29.33, "uptime_seconds": 32338, "voltage": 4.02}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1000.51, "iaq": 84, "relative_humidity": 14.79, "temperature": 40.91}, "hops_away": 2, "hw_model": "T_ECHO", "last_heard_offset_sec": 309, "long_name": "Brave Juniper", "next_hop": 9, "num": "0x22681b09", "position": {"altitude": 1313, "latitude": 33.196654, "location_source": "LOC_INTERNAL", "longitude": -106.997179, "time_offset_sec": 575}, "public_key_hex": "0c5ce9a2ae203f5698b67669463c7650d7898547aba0ed6acc456e3d24b1a401", "role": "CLIENT", "short_name": "BPP2", "snr": 3.84, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.797, "battery_level": 62, "channel_utilization": 9.31, "uptime_seconds": 349552, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 7718, "long_name": "Desert Cobra", "next_hop": 0, "num": "0x22d7d309", "position": {"altitude": 1311, "latitude": 33.255675, "location_source": "LOC_INTERNAL", "longitude": -107.444882, "time_offset_sec": 7959}, "public_key_hex": "90b5dee4acb9274a52c640a2b854603a543a4be718e7ae478212bf60cc53a252", "role": "CLIENT", "short_name": "DFPE", "snr": -0.05, "status": {"status": "no-gps"}, "telemetry": {"air_util_tx": 1.058, "battery_level": 40, "channel_utilization": 35.25, "uptime_seconds": 5417, "voltage": 3.66}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 6737, "long_name": "Silver Cedar", "next_hop": 0, "num": "0x22d9762a", "position": null, "public_key_hex": "ca92433f107ebf95e44c6286a649d0d559a0c10e1cbe12194b02fd05a1a0be7f", "role": "CLIENT", "short_name": "SOC1", "snr": 2.98, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 1.834, "battery_level": 65, "channel_utilization": 10.13, "uptime_seconds": 92911, "voltage": 3.885}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 1038, "long_name": "Sneaky Mustang", "next_hop": 250, "num": "0x22fa3ede", "position": {"altitude": 998, "latitude": 33.530425, "location_source": "LOC_INTERNAL", "longitude": -108.118632, "time_offset_sec": 1071}, "public_key_hex": "cd67de99c01cef3a4bccf8be77fdc9867e9d36140ed85dd4db2580090a8b12a4", "role": "CLIENT", "short_name": "S4ZQ", "snr": 7.23, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 11870, "long_name": "Drifting Squirrel", "next_hop": 0, "num": "0x230de5d6", "position": null, "public_key_hex": "207f473e204ad579961c472b68f36b5c2417f263d527abfad579c2c1fbd2292d", "role": "CLIENT", "short_name": "DJWM", "snr": 9.27, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.127, "battery_level": 10, "channel_utilization": 3.15, "uptime_seconds": 24031, "voltage": 3.39}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1030.51, "iaq": 42, "relative_humidity": 54.16, "temperature": 29.92}, "hops_away": 3, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 5016, "long_name": "Smooth Marmot", "next_hop": 126, "num": "0x2375e66b", "position": {"altitude": 1412, "latitude": 32.61115, "location_source": "LOC_INTERNAL", "longitude": -107.686434, "time_offset_sec": 5113}, "public_key_hex": "f050748fd0d4f37779d5eb745a51fca43f61111f3631fe587e8236676090dac6", "role": "CLIENT", "short_name": "STBK", "snr": -0.04, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.332, "battery_level": 57, "channel_utilization": 18.05, "uptime_seconds": 5906, "voltage": 3.813}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M6", "last_heard_offset_sec": 694, "long_name": "Sky Doe", "next_hop": 0, "num": "0x237668c0", "position": {"altitude": 1742, "latitude": 32.685164, "location_source": "LOC_INTERNAL", "longitude": -107.454203, "time_offset_sec": 855}, "public_key_hex": "eb89e19cbd4889d2ceaee0559bc54eade7dd1f3e572d58d67aa5eb5e4f75c750", "role": "CLIENT", "short_name": "SR0J", "snr": 6.47, "status": {"status": "offline-soon"}, "telemetry": {"air_util_tx": 0.496, "battery_level": 19, "channel_utilization": 7.6, "uptime_seconds": 31164, "voltage": 3.471}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1002.49, "iaq": 24, "relative_humidity": 62.45, "temperature": 35.82}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 1384, "long_name": "Whispering Salmon", "next_hop": 0, "num": "0x23c98a6d", "position": {"altitude": 1614, "latitude": 33.614918, "location_source": "LOC_INTERNAL", "longitude": -107.429103, "time_offset_sec": 1647}, "public_key_hex": "c43fa3accf988f4100b88711423b7661a756eb33315f6c2ddcb88c60cb65e663", "role": "CLIENT_MUTE", "short_name": "W297", "snr": 4.03, "status": null, "telemetry": {"air_util_tx": 1.534, "battery_level": 31, "channel_utilization": 2.71, "uptime_seconds": 126260, "voltage": 3.579}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 6333, "long_name": "Dawn Owl AE5DW", "next_hop": 0, "num": "0x23f41648", "position": {"altitude": 1149, "latitude": 32.670635, "location_source": "LOC_INTERNAL", "longitude": -106.966118, "time_offset_sec": 6611}, "public_key_hex": "d19c786d7447228d443f44206e3df23dcbe9bdca14d6f251b0fc27b3e7c597e1", "role": "CLIENT", "short_name": "DV8L", "snr": 5.4, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 2484, "long_name": "Roving Elk", "next_hop": 214, "num": "0x24595fd0", "position": {"altitude": 704, "latitude": 33.437723, "location_source": "LOC_INTERNAL", "longitude": -106.824987, "time_offset_sec": 2523}, "public_key_hex": "7199ef6b37f76349421ef6bfb82b4bb5f0d5a6e009d6fc769c02310b836c412e", "role": "CLIENT", "short_name": "R1XY", "snr": 10.11, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.412, "battery_level": 47, "channel_utilization": 16.49, "uptime_seconds": 43935, "voltage": 3.723}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 5231, "long_name": "Steel Phoenix", "next_hop": 67, "num": "0x24ef37f2", "position": {"altitude": 881, "latitude": 33.382287, "location_source": "LOC_INTERNAL", "longitude": -106.683959, "time_offset_sec": 5469}, "public_key_hex": "9d7e3a32de5ddba3bd77fb3156f58e94be20aeb4b559655b9338c4618c655d17", "role": "LOST_AND_FOUND", "short_name": "🔥", "snr": 4.36, "status": null, "telemetry": {"air_util_tx": 0.683, "battery_level": 36, "channel_utilization": 2.5, "uptime_seconds": 8316, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1023.29, "iaq": 67, "relative_humidity": 56.81, "temperature": 16.91}, "hops_away": 2, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 2457, "long_name": "Hidden Ridge", "next_hop": 121, "num": "0x255e347c", "position": {"altitude": 1191, "latitude": 32.831029, "location_source": "LOC_INTERNAL", "longitude": -107.8584, "time_offset_sec": 2463}, "public_key_hex": "a55a7dcc277e8487d135f7b6f73a8a5378f36d8a105f6c5bf432119cee055d00", "role": "CLIENT", "short_name": "HRX0", "snr": 2.36, "status": {"status": "offline-soon"}, "telemetry": {"air_util_tx": 0.061, "battery_level": 14, "channel_utilization": 40.63, "uptime_seconds": 19839, "voltage": 3.426}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 4139, "long_name": "Lost Eagle", "next_hop": 0, "num": "0x25aa8181", "position": {"altitude": 1358, "latitude": 32.614367, "location_source": "LOC_INTERNAL", "longitude": -107.462449, "time_offset_sec": 4389}, "public_key_hex": "6bbe98fbf5844c3f15b8ecd858fb92bf91e29a76dc7feb61708038e5c45044a2", "role": "CLIENT", "short_name": "LECX", "snr": 4.8, "status": null, "telemetry": {"air_util_tx": 1.039, "battery_level": 101, "channel_utilization": 14.91, "uptime_seconds": 29832, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 6403, "long_name": "Stone Seal", "next_hop": 187, "num": "0x25da47be", "position": {"altitude": 1445, "latitude": 34.003693, "location_source": "LOC_INTERNAL", "longitude": -106.236603, "time_offset_sec": 6660}, "public_key_hex": "552c56b590e2bdd964dbfc232a14a69afad16be2625e6fec65844d55c535eb99", "role": "CLIENT", "short_name": "SLY8", "snr": -0.39, "status": null, "telemetry": {"air_util_tx": 0.525, "battery_level": 76, "channel_utilization": 30.06, "uptime_seconds": 5620, "voltage": 3.984}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1011.6, "iaq": 0, "relative_humidity": 37.72, "temperature": 13.49}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 904, "long_name": "Floating Wolf", "next_hop": 0, "num": "0x25e5b378", "position": {"altitude": 1299, "latitude": 32.597977, "location_source": "LOC_INTERNAL", "longitude": -107.462789, "time_offset_sec": 972}, "public_key_hex": "1619e3db54a4d1696fd63d79a7e2b0a35858ae97ec30bf98fc49550db1a9e8cc", "role": "CLIENT", "short_name": "FLL7", "snr": 1.1, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.401, "battery_level": 32, "channel_utilization": 11.97, "uptime_seconds": 73909, "voltage": 3.588}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 2381, "long_name": "Shady Hawk", "next_hop": 0, "num": "0x25eea078", "position": {"altitude": 1548, "latitude": 32.966234, "location_source": "LOC_INTERNAL", "longitude": -107.004419, "time_offset_sec": 2406}, "public_key_hex": "497a86eed0ca8ad7804229c089b8fd5fbf48839bfd625d02d6872418fa92e852", "role": "CLIENT", "short_name": "SIC9", "snr": 8.74, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.207, "battery_level": 50, "channel_utilization": 12.97, "uptime_seconds": 19430, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1081, "long_name": "Happy Sage", "next_hop": 203, "num": "0x2667d1f8", "position": {"altitude": 1552, "latitude": 33.095074, "location_source": "LOC_INTERNAL", "longitude": -107.13094, "time_offset_sec": 1281}, "public_key_hex": "0c000b564a9244a33072f13726b86b280a1200a0670fad5dcfa817889d69ad42", "role": "CLIENT", "short_name": "H1X4", "snr": 5.61, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 6, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1085, "long_name": "Frosty Phoenix NM1FH", "next_hop": 196, "num": "0x26ca2f96", "position": {"altitude": 1514, "latitude": 32.151259, "location_source": "LOC_INTERNAL", "longitude": -106.862516, "time_offset_sec": 1238}, "public_key_hex": "ce6fcb85cc3e972ffdf1d82ae23f7c1d5a770cbc578fc1574fa7fd665fa6f62e", "role": "CLIENT", "short_name": "FQCL", "snr": 8.5, "status": null, "telemetry": {"air_util_tx": 0.334, "battery_level": 41, "channel_utilization": 18.85, "uptime_seconds": 421633, "voltage": 3.669}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1005.01, "iaq": 68, "relative_humidity": 88.46, "temperature": 26.35}, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 7290, "long_name": "Burning Mustang", "next_hop": 1, "num": "0x27425ae4", "position": null, "public_key_hex": "000e54002f8c0ab1480cbba098217703d232c413abb1ea40e45354716a1eb986", "role": "CLIENT", "short_name": "BN4S", "snr": 6.09, "status": null, "telemetry": {"air_util_tx": 0.245, "battery_level": 22, "channel_utilization": 8.9, "uptime_seconds": 138472, "voltage": 3.498}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4044, "long_name": "Misty Mesa", "next_hop": 166, "num": "0x28189553", "position": {"altitude": 1530, "latitude": 34.237739, "location_source": "LOC_INTERNAL", "longitude": -107.293962, "time_offset_sec": 4114}, "public_key_hex": "7bd4aad3389db08c0ab3187703ad4b8890f3894fe5336f6bf207aa86a2fb6d0d", "role": "CLIENT_BASE", "short_name": "MWNZ", "snr": 3.45, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.33, "iaq": 17, "relative_humidity": 48.69, "temperature": 12.51}, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 5033, "long_name": "Whispering Mesa", "next_hop": 0, "num": "0x286532a5", "position": {"altitude": 1587, "latitude": 33.100997, "location_source": "LOC_INTERNAL", "longitude": -107.578256, "time_offset_sec": 5317}, "public_key_hex": "408f11c37752fb1225f8f6ac0e07af1bc9525af15356cddad6afddbb9cdfd572", "role": "CLIENT_MUTE", "short_name": "WDPB", "snr": 2.02, "status": null, "telemetry": {"air_util_tx": 0.463, "battery_level": 28, "channel_utilization": 3.29, "uptime_seconds": 6869, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 3696, "long_name": "Slow Eagle", "next_hop": 0, "num": "0x2871d2c3", "position": {"altitude": 1315, "latitude": 32.745414, "location_source": "LOC_INTERNAL", "longitude": -107.895128, "time_offset_sec": 3752}, "public_key_hex": "1fff7ed20f2ff6f158999d61b02e3e18377cd1bf32017465ce2458bb7688205d", "role": "CLIENT", "short_name": "🦅", "snr": 5.72, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.312, "battery_level": 18, "channel_utilization": 4.14, "uptime_seconds": 78516, "voltage": 3.462}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 6358, "long_name": "Canyon Bluff", "next_hop": 0, "num": "0x28b78c55", "position": {"altitude": 1051, "latitude": 33.951996, "location_source": "LOC_INTERNAL", "longitude": -108.109663, "time_offset_sec": 6621}, "public_key_hex": "a4748a9966ad143c72cb65ab661b9fa78bc7197600d4149361c1c9fe7790290d", "role": "CLIENT", "short_name": "CUWK", "snr": 2.14, "status": null, "telemetry": {"air_util_tx": 1.151, "battery_level": 101, "channel_utilization": 1.72, "uptime_seconds": 78558, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 2160, "long_name": "Frozen Yucca", "next_hop": 0, "num": "0x2902b034", "position": {"altitude": 2009, "latitude": 32.901567, "location_source": "LOC_INTERNAL", "longitude": -107.182626, "time_offset_sec": 2266}, "public_key_hex": "0a82dcd2a4fbdfd1209f04d2784e33b87e9391a976b92d6d20846aeb4fb48032", "role": "CLIENT", "short_name": "F9PB", "snr": 7.53, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.388, "battery_level": 100, "channel_utilization": 30.03, "uptime_seconds": 127938, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 593, "long_name": "Copper Bluff", "next_hop": 0, "num": "0x294b4ff2", "position": null, "public_key_hex": "95f367b92ac6236e41ff536b3800fee8d14ff4482c678b7a9d3e44d11935e382", "role": "CLIENT", "short_name": "C9HF", "snr": 5.99, "status": null, "telemetry": {"air_util_tx": 0.024, "battery_level": 97, "channel_utilization": 11.51, "uptime_seconds": 16495, "voltage": 4.173}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2761, "long_name": "Frozen Crane", "next_hop": 237, "num": "0x29735d36", "position": {"altitude": 1161, "latitude": 32.957968, "location_source": "LOC_INTERNAL", "longitude": -107.416665, "time_offset_sec": 2855}, "public_key_hex": "d38c2fc7f95c3e4306a68f3ec9ca5eb4c6a4327154b73e50e32adf4f62e71ef9", "role": "TRACKER", "short_name": "F9K1", "snr": 2.16, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.263, "battery_level": 71, "channel_utilization": 12.68, "uptime_seconds": 65271, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1017.33, "iaq": 60, "relative_humidity": 87.04, "temperature": 11.48}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 2916, "long_name": "Happy Moose", "next_hop": 0, "num": "0x29c9c9f0", "position": {"altitude": 1068, "latitude": 33.048205, "location_source": "LOC_INTERNAL", "longitude": -107.182212, "time_offset_sec": 3211}, "public_key_hex": "754a5b838bc5dba0743c1fe2cb527abaacfdcd0eb9956be4def3c4101e79d1e7", "role": "ROUTER", "short_name": "H9AT", "snr": 6.68, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.627, "battery_level": 30, "channel_utilization": 0.9, "uptime_seconds": 83541, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 11816, "long_name": "Short Juniper", "next_hop": 0, "num": "0x29d4f0d6", "position": {"altitude": 1657, "latitude": 33.175304, "location_source": "LOC_INTERNAL", "longitude": -107.340189, "time_offset_sec": 12064}, "public_key_hex": "82daf0da564c692a844e39c61351aba1af6df06fbefb5b8d1067fab533e88f20", "role": "CLIENT", "short_name": "SBUX", "snr": 7.39, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 11612, "long_name": "Sky Eagle", "next_hop": 0, "num": "0x29d75e55", "position": {"altitude": 1363, "latitude": 32.634353, "location_source": "LOC_INTERNAL", "longitude": -106.629271, "time_offset_sec": 11653}, "public_key_hex": "", "role": "CLIENT", "short_name": "SCET", "snr": 4.27, "status": null, "telemetry": {"air_util_tx": 0.121, "battery_level": 76, "channel_utilization": 16.94, "uptime_seconds": 10144, "voltage": 3.984}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 191, "long_name": "Sneaky Bear", "next_hop": 192, "num": "0x2a7eafe7", "position": {"altitude": 1050, "latitude": 33.006934, "location_source": "LOC_INTERNAL", "longitude": -107.180556, "time_offset_sec": 377}, "public_key_hex": "aa4c4b6ce50afd0f90e0c74aad3074c4a3e9bc1f4b7cd7eedacc37c98728d84e", "role": "CLIENT", "short_name": "S2BM", "snr": 1.17, "status": null, "telemetry": {"air_util_tx": 0.268, "battery_level": 70, "channel_utilization": 0.88, "uptime_seconds": 62363, "voltage": 3.93}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 9242, "long_name": "Frozen Lion", "next_hop": 0, "num": "0x2a8ddd3b", "position": {"altitude": 1289, "latitude": 33.408764, "location_source": "LOC_INTERNAL", "longitude": -106.941602, "time_offset_sec": 9277}, "public_key_hex": "36e68f8e390af3201a9c29dfee18c770ea4e06bd0d29bc6103ee153c9a53cbb7", "role": "CLIENT", "short_name": "FUET", "snr": 8.86, "status": null, "telemetry": {"air_util_tx": 0.142, "battery_level": 30, "channel_utilization": 10.54, "uptime_seconds": 67024, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 1682, "long_name": "Quick Lion", "next_hop": 0, "num": "0x2afcb0c0", "position": {"altitude": 1064, "latitude": 33.062992, "location_source": "LOC_INTERNAL", "longitude": -108.242545, "time_offset_sec": 1920}, "public_key_hex": "", "role": "ROUTER", "short_name": "QCH1", "snr": 9.0, "status": null, "telemetry": {"air_util_tx": 0.025, "battery_level": 36, "channel_utilization": 5.1, "uptime_seconds": 864, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 7, "environment": null, "hops_away": 0, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 1956, "long_name": "Sunny Lynx", "next_hop": 0, "num": "0x2b347222", "position": {"altitude": 1296, "latitude": 33.162348, "location_source": "LOC_INTERNAL", "longitude": -107.196228, "time_offset_sec": 2042}, "public_key_hex": "e926767fbe87024d4b7a0af44cae50c39e8c8c5755616a8e59b20d80b9944b15", "role": "CLIENT", "short_name": "SAHV", "snr": 11.11, "status": null, "telemetry": {"air_util_tx": 0.501, "battery_level": 77, "channel_utilization": 8.54, "uptime_seconds": 228867, "voltage": 3.993}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 2557, "long_name": "Silent Pony", "next_hop": 112, "num": "0x2b34a346", "position": {"altitude": 1489, "latitude": 33.126571, "location_source": "LOC_INTERNAL", "longitude": -106.378904, "time_offset_sec": 2563}, "public_key_hex": "f5a89f662c2f3a5f55d478e7c2f33ec9e7f4359b7891a3c229689ea8c0c7d68c", "role": "SENSOR", "short_name": "SL36", "snr": 0.9, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": null, "hops_away": 5, "hw_model": "THINKNODE_M6", "last_heard_offset_sec": 9092, "long_name": "Giant Stag", "next_hop": 227, "num": "0x2b5e052c", "position": {"altitude": 1221, "latitude": 34.103918, "location_source": "LOC_INTERNAL", "longitude": -108.470304, "time_offset_sec": 9124}, "public_key_hex": "6a5ec94870af7d5b5e665de3bd732d04638d7af8fd295b7ac2d69fdc1846163b", "role": "CLIENT", "short_name": "GDT6", "snr": 5.84, "status": null, "telemetry": {"air_util_tx": 0.161, "battery_level": 23, "channel_utilization": 24.35, "uptime_seconds": 52091, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 997.51, "iaq": 54, "relative_humidity": 66.77, "temperature": 21.53}, "hops_away": 6, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 11094, "long_name": "Canyon Turtle", "next_hop": 103, "num": "0x2ba1d378", "position": {"altitude": 1078, "latitude": 32.838468, "location_source": "LOC_INTERNAL", "longitude": -107.571802, "time_offset_sec": 11359}, "public_key_hex": "f463d51e7aaecb4d1428131e72f3b7ea449e6a8d5c22855800867a43e5b10af4", "role": "CLIENT", "short_name": "CMWK", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.194, "battery_level": 86, "channel_utilization": 14.99, "uptime_seconds": 9072, "voltage": 4.074}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 3, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 6651, "long_name": "Tiny Mole", "next_hop": 0, "num": "0x2c3b2dcc", "position": {"altitude": 1171, "latitude": 33.265768, "location_source": "LOC_INTERNAL", "longitude": -107.158108, "time_offset_sec": 6708}, "public_key_hex": "95fefb0414af73334daa18eb1d43b1ef42aed034cc4f34ad42485ae89a6e836a", "role": "CLIENT_BASE", "short_name": "TFKN", "snr": -0.19, "status": null, "telemetry": {"air_util_tx": 1.682, "battery_level": 43, "channel_utilization": 3.54, "uptime_seconds": 333245, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1313, "long_name": "Silent Bison", "next_hop": 95, "num": "0x2c44806f", "position": {"altitude": 1673, "latitude": 33.332687, "location_source": "LOC_INTERNAL", "longitude": -108.403882, "time_offset_sec": 1392}, "public_key_hex": "a1dbb254d365eb8ce1df7ae1ada160c03eaa9dd8eab64d6b86364e347cb732c4", "role": "CLIENT", "short_name": "SO8Q", "snr": 3.28, "status": null, "telemetry": {"air_util_tx": 0.161, "battery_level": 12, "channel_utilization": 2.33, "uptime_seconds": 1147, "voltage": 3.408}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1023.9, "iaq": 70, "relative_humidity": 57.26, "temperature": 23.7}, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 371, "long_name": "Green Shark", "next_hop": 0, "num": "0x2c4f0a46", "position": {"altitude": 1198, "latitude": 32.459029, "location_source": "LOC_INTERNAL", "longitude": -106.520458, "time_offset_sec": 566}, "public_key_hex": "25e2d778098b7e11fcd2dcca143d2b3fb92888c4310bc5116dafa090525f627b", "role": "TAK", "short_name": "GGZ8", "snr": 8.81, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 3647, "long_name": "Sky Crow", "next_hop": 0, "num": "0x2cc1b44c", "position": {"altitude": 1766, "latitude": 33.038761, "location_source": "LOC_INTERNAL", "longitude": -107.317439, "time_offset_sec": 3896}, "public_key_hex": "74f1a468c5ffc4551aa890f3adfaad3c6b546c3037d647a496242260916f9c25", "role": "CLIENT", "short_name": "🐺", "snr": 11.05, "status": null, "telemetry": {"air_util_tx": 0.47, "battery_level": 23, "channel_utilization": 2.74, "uptime_seconds": 129382, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 10432, "long_name": "Old Juniper", "next_hop": 0, "num": "0x2cdbaab1", "position": {"altitude": 1133, "latitude": 33.066707, "location_source": "LOC_INTERNAL", "longitude": -107.620177, "time_offset_sec": 10514}, "public_key_hex": "24325838a5b348c60c12a6de6da9f9d56f0b91cdb4e35ae05d8d7d7b0b60145e", "role": "TRACKER", "short_name": "OTGD", "snr": 1.91, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 786, "long_name": "Drifting Shark", "next_hop": 0, "num": "0x2cffb46b", "position": {"altitude": 1769, "latitude": 33.111323, "location_source": "LOC_INTERNAL", "longitude": -107.792845, "time_offset_sec": 809}, "public_key_hex": "7b2d36372449f86224e31c825f0b83df3242c51e6590d8ee43fdd3d3b6eb2cf4", "role": "CLIENT_MUTE", "short_name": "DMHA", "snr": 2.03, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1002.26, "iaq": 60, "relative_humidity": 52.62, "temperature": 10.59}, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 2156, "long_name": "Bright Pike", "next_hop": 0, "num": "0x2d097018", "position": {"altitude": 1961, "latitude": 32.728872, "location_source": "LOC_INTERNAL", "longitude": -107.467619, "time_offset_sec": 2242}, "public_key_hex": "4032dc18f7ac255f8b45e6d0de53c9e26a87773fe1fa144d0bead43fcfef6dc0", "role": "CLIENT", "short_name": "BLUO", "snr": 9.96, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.296, "battery_level": 26, "channel_utilization": 5.76, "uptime_seconds": 352047, "voltage": 3.534}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1297, "long_name": "White Seal", "next_hop": 203, "num": "0x2d467a1e", "position": {"altitude": 606, "latitude": 32.590838, "location_source": "LOC_INTERNAL", "longitude": -108.031101, "time_offset_sec": 1423}, "public_key_hex": "cc3909ddca959ec85a5651226abfe0466c75711dabfdd4c95c1eace8fa95eaed", "role": "CLIENT", "short_name": "WS08", "snr": 6.64, "status": null, "telemetry": {"air_util_tx": 1.644, "battery_level": 66, "channel_utilization": 8.71, "uptime_seconds": 55069, "voltage": 3.894}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1019.43, "iaq": 55, "relative_humidity": 55.36, "temperature": 21.12}, "hops_away": 0, "hw_model": "MINI_EPAPER_S3", "last_heard_offset_sec": 8020, "long_name": "Rough Bison", "next_hop": 0, "num": "0x2da1c655", "position": {"altitude": 652, "latitude": 33.586611, "location_source": "LOC_INTERNAL", "longitude": -108.107971, "time_offset_sec": 8318}, "public_key_hex": "91b61115d77af4176a7c0816507b80a701deffeb9c71c1f1129aa08ec3e2b8b2", "role": "CLIENT", "short_name": "REY0", "snr": 7.9, "status": null, "telemetry": {"air_util_tx": 0.83, "battery_level": 35, "channel_utilization": 11.3, "uptime_seconds": 47328, "voltage": 3.615}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 996.72, "iaq": 31, "relative_humidity": 58.79, "temperature": 13.99}, "hops_away": 0, "hw_model": "THINKNODE_M5", "last_heard_offset_sec": 6928, "long_name": "Floating Falcon", "next_hop": 0, "num": "0x2dff7287", "position": {"altitude": 1298, "latitude": 34.609606, "location_source": "LOC_INTERNAL", "longitude": -106.295517, "time_offset_sec": 7087}, "public_key_hex": "ec530a9f8866ba7523aaea2a20934463ce8a143ddc553e3e85a2d2173007b4a6", "role": "CLIENT", "short_name": "F1BM", "snr": 5.16, "status": null, "telemetry": {"air_util_tx": 0.682, "battery_level": 101, "channel_utilization": 15.94, "uptime_seconds": 19307, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2915, "long_name": "Red Coyote", "next_hop": 0, "num": "0x2e0aa0ef", "position": null, "public_key_hex": "ccfcbc27c57006045a1608fbe32bd1835b6e618d32a1ed4ee86794fb98e9de8b", "role": "CLIENT", "short_name": "R4CS", "snr": 10.93, "status": null, "telemetry": {"air_util_tx": 0.68, "battery_level": 99, "channel_utilization": 19.5, "uptime_seconds": 52545, "voltage": 4.191}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1010.3, "iaq": 45, "relative_humidity": 38.32, "temperature": 25.02}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 2771, "long_name": "Shady Owl", "next_hop": 0, "num": "0x2e5a3396", "position": {"altitude": 1560, "latitude": 33.447145, "location_source": "LOC_INTERNAL", "longitude": -107.147302, "time_offset_sec": 2916}, "public_key_hex": "595bd7bc432fac984064d001e07e153d1a37856a9b1c4425f1a595cd99912bea", "role": "CLIENT", "short_name": "SKRA", "snr": 1.49, "status": null, "telemetry": {"air_util_tx": 1.042, "battery_level": 38, "channel_utilization": 2.38, "uptime_seconds": 4539, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3479, "long_name": "Lost Eagle", "next_hop": 0, "num": "0x2ed3f2c9", "position": {"altitude": 1409, "latitude": 34.047196, "location_source": "LOC_INTERNAL", "longitude": -107.411467, "time_offset_sec": 3584}, "public_key_hex": "901e5d5764542878fd2435626e367e76eb6a8db9ad51ff6de3d1019ff78017fd", "role": "CLIENT", "short_name": "LB5Y", "snr": 4.57, "status": null, "telemetry": {"air_util_tx": 0.888, "battery_level": 85, "channel_utilization": 5.94, "uptime_seconds": 12625, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 2410, "long_name": "Lunar Falcon", "next_hop": 0, "num": "0x2f0f3244", "position": {"altitude": 1196, "latitude": 33.385031, "location_source": "LOC_INTERNAL", "longitude": -108.171963, "time_offset_sec": 2489}, "public_key_hex": "f8615cc5faf7f35fbaddfa32d3e468615a58d7e9113d905271d96d4fa5b0c767", "role": "CLIENT", "short_name": "LCNT", "snr": 6.43, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": {"barometric_pressure": 1008.36, "iaq": 66, "relative_humidity": 32.6, "temperature": 24.35}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 13431, "long_name": "Roving Otter", "next_hop": 0, "num": "0x2f2b0cc3", "position": {"altitude": 1502, "latitude": 33.075668, "location_source": "LOC_INTERNAL", "longitude": -106.545429, "time_offset_sec": 13708}, "public_key_hex": "3fe4d1db3059e2ba5734e2442ad2f192e141d6d02a1000d1124ec34bfe4969c0", "role": "CLIENT", "short_name": "RYEF", "snr": 2.93, "status": {"status": "running"}, "telemetry": {"air_util_tx": 1.196, "battery_level": 85, "channel_utilization": 11.67, "uptime_seconds": 43860, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 4490, "long_name": "Red Cobra", "next_hop": 178, "num": "0x2f335cb1", "position": {"altitude": 1284, "latitude": 32.952871, "location_source": "LOC_INTERNAL", "longitude": -106.45338, "time_offset_sec": 4598}, "public_key_hex": "d38ba579c9c86914d7a46952920363d445a63077cec64ed8eedd2f530f199aac", "role": "CLIENT", "short_name": "R8FE", "snr": 10.84, "status": null, "telemetry": {"air_util_tx": 0.271, "battery_level": 30, "channel_utilization": 5.39, "uptime_seconds": 16626, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1006.84, "iaq": 107, "relative_humidity": 86.07, "temperature": 26.78}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1556, "long_name": "Wild Mamba", "next_hop": 0, "num": "0x2f4a24be", "position": {"altitude": 1283, "latitude": 34.196781, "location_source": "LOC_INTERNAL", "longitude": -108.081588, "time_offset_sec": 1742}, "public_key_hex": "d302285d86ef2cfd19f365606d60be646a461dc86436bd75682ff8c97b9d5629", "role": "CLIENT", "short_name": "WIR0", "snr": 6.83, "status": null, "telemetry": {"air_util_tx": 0.218, "battery_level": 99, "channel_utilization": 10.27, "uptime_seconds": 22497, "voltage": 4.191}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 8074, "long_name": "Short Mustang", "next_hop": 0, "num": "0x2f8041b6", "position": {"altitude": 1629, "latitude": 32.430916, "location_source": "LOC_INTERNAL", "longitude": -106.903131, "time_offset_sec": 8241}, "public_key_hex": "ca5b2ba5ef9580e07e2f24bc7255e9051a47e7051993a3f64d6208f2506d9d98", "role": "CLIENT", "short_name": "SPK3", "snr": 3.93, "status": {"status": "low-batt"}, "telemetry": {"air_util_tx": 0.103, "battery_level": 92, "channel_utilization": 24.36, "uptime_seconds": 89728, "voltage": 4.128}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.39, "iaq": 77, "relative_humidity": 67.81, "temperature": 16.65}, "hops_away": 1, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 293, "long_name": "Tiny Bluff", "next_hop": 222, "num": "0x2f9511af", "position": {"altitude": 1078, "latitude": 33.394593, "location_source": "LOC_INTERNAL", "longitude": -107.04634, "time_offset_sec": 572}, "public_key_hex": "5852c0696fce46ca89d723cd0a4f45a629c2536cfbee3e14deb0fda6e827e2fe", "role": "CLIENT", "short_name": "TBIV", "snr": -0.85, "status": null, "telemetry": {"air_util_tx": 1.387, "battery_level": 96, "channel_utilization": 4.88, "uptime_seconds": 30393, "voltage": 4.164}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1010.15, "iaq": 73, "relative_humidity": 69.95, "temperature": 25.35}, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 3521, "long_name": "Silent Hawk NM2XD", "next_hop": 25, "num": "0x2fddcc45", "position": {"altitude": 951, "latitude": 33.560012, "location_source": "LOC_INTERNAL", "longitude": -107.640412, "time_offset_sec": 3551}, "public_key_hex": "4cfdd5c01b12f81cd4f90801d290858e46ea16f21e300805ffe48bd02412bdf8", "role": "ROUTER", "short_name": "SBQM", "snr": 12.0, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.015, "battery_level": 26, "channel_utilization": 12.25, "uptime_seconds": 439034, "voltage": 3.534}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1017.89, "iaq": 36, "relative_humidity": 86.12, "temperature": 32.4}, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 2517, "long_name": "Howling Fox", "next_hop": 102, "num": "0x2ffc54b6", "position": null, "public_key_hex": "94381db82f1ffdc0ce3680dc424a2550f0e3186e33a46b5dbfaf012b8c982c73", "role": "CLIENT", "short_name": "HGU8", "snr": 3.02, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1010.67, "iaq": 34, "relative_humidity": 51.43, "temperature": 31.02}, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 755, "long_name": "Old Lion", "next_hop": 0, "num": "0x3019784d", "position": null, "public_key_hex": "dd70ca76b27534160accff9cfbffa89c475ed6a0df324753942cd9670946b7cd", "role": "CLIENT", "short_name": "🦇", "snr": 4.62, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1010.06, "iaq": 15, "relative_humidity": 61.18, "temperature": 24.46}, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 2640, "long_name": "Steel Aspen", "next_hop": 34, "num": "0x302276b1", "position": {"altitude": 1389, "latitude": 32.178993, "location_source": "LOC_INTERNAL", "longitude": -106.728026, "time_offset_sec": 2827}, "public_key_hex": "10903a4d8c75b7d8d645b213d4bd7bf2e7510008b1058338040e1899ffb88905", "role": "CLIENT", "short_name": "🐝", "snr": -3.89, "status": null, "telemetry": {"air_util_tx": 0.033, "battery_level": 95, "channel_utilization": 16.84, "uptime_seconds": 85688, "voltage": 4.155}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1012.87, "iaq": 26, "relative_humidity": 38.89, "temperature": 22.29}, "hops_away": 4, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 1055, "long_name": "Canyon Heron", "next_hop": 59, "num": "0x302347c6", "position": {"altitude": 1500, "latitude": 33.175513, "location_source": "LOC_INTERNAL", "longitude": -108.193238, "time_offset_sec": 1148}, "public_key_hex": "13f20da3a657fce0204811efc1ae982c95ccaebb7261a0e5366262f686f210de", "role": "ROUTER", "short_name": "CL68", "snr": 3.4, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.501, "battery_level": 19, "channel_utilization": 13.65, "uptime_seconds": 55497, "voltage": 3.471}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1081, "long_name": "Slow Moose", "next_hop": 61, "num": "0x307e37f5", "position": {"altitude": 1723, "latitude": 32.61456, "location_source": "LOC_INTERNAL", "longitude": -107.310215, "time_offset_sec": 1181}, "public_key_hex": "a16dc21e89c07d49ecfc537b7806c9bbc0188f7defbd5cef438c5e43e8ec9ce3", "role": "CLIENT", "short_name": "SJ62", "snr": 4.57, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 2493, "long_name": "Sharp Phoenix", "next_hop": 36, "num": "0x30b51075", "position": {"altitude": 1704, "latitude": 33.168725, "location_source": "LOC_INTERNAL", "longitude": -106.951606, "time_offset_sec": 2683}, "public_key_hex": "35c7f7d6bb4712bb032246ffc038364d6369f4039bbae66478bf682e95c45d45", "role": "CLIENT", "short_name": "SU0J", "snr": 10.27, "status": null, "telemetry": {"air_util_tx": 0.51, "battery_level": 11, "channel_utilization": 26.69, "uptime_seconds": 39780, "voltage": 3.399}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 9096, "long_name": "Drowsy Bronco", "next_hop": 0, "num": "0x30efe3b4", "position": {"altitude": 1245, "latitude": 33.106372, "location_source": "LOC_INTERNAL", "longitude": -106.7179, "time_offset_sec": 9270}, "public_key_hex": "b0e4d9ce00bb3ffc3f329d3ab02eef180478951cc871cf8971b26c0decf26d0c", "role": "CLIENT", "short_name": "DE6W", "snr": 6.29, "status": null, "telemetry": {"air_util_tx": 1.628, "battery_level": 72, "channel_utilization": 10.45, "uptime_seconds": 29813, "voltage": 3.948}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1017.35, "iaq": 91, "relative_humidity": 43.65, "temperature": 18.36}, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 357, "long_name": "Dawn Coyote", "next_hop": 116, "num": "0x30f40c60", "position": {"altitude": 1338, "latitude": 32.549872, "location_source": "LOC_INTERNAL", "longitude": -106.643419, "time_offset_sec": 626}, "public_key_hex": "69ff9ea49887dbb9f206994b2aea3aa7c1428110ad50b54c0dd8ea32b716a4ba", "role": "CLIENT", "short_name": "DFTL", "snr": 0.96, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 1.038, "battery_level": 24, "channel_utilization": 10.63, "uptime_seconds": 54787, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 754, "long_name": "Loud Bass", "next_hop": 0, "num": "0x30fa4c03", "position": {"altitude": 1498, "latitude": 33.853065, "location_source": "LOC_INTERNAL", "longitude": -107.51827, "time_offset_sec": 854}, "public_key_hex": "74834eb0e774da1724557df897960e7f153351e1b4361a69dc4dc2528c302b06", "role": "ROUTER_LATE", "short_name": "LKB1", "snr": 6.84, "status": null, "telemetry": {"air_util_tx": 0.676, "battery_level": 98, "channel_utilization": 8.2, "uptime_seconds": 1124, "voltage": 4.182}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 3800, "long_name": "Bright Trout", "next_hop": 19, "num": "0x31328c71", "position": {"altitude": 1732, "latitude": 32.840214, "location_source": "LOC_INTERNAL", "longitude": -107.137479, "time_offset_sec": 4085}, "public_key_hex": "7fc6cad0e2b814bcb1d3fb7f070e737a17c3197f48d16abb9c1a7775155f7d66", "role": "ROUTER", "short_name": "BGVZ", "snr": 3.4, "status": null, "telemetry": {"air_util_tx": 0.948, "battery_level": 23, "channel_utilization": 6.91, "uptime_seconds": 168843, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 4140, "long_name": "Loud Bear", "next_hop": 0, "num": "0x314173e9", "position": {"altitude": 1218, "latitude": 32.880206, "location_source": "LOC_INTERNAL", "longitude": -107.441087, "time_offset_sec": 4236}, "public_key_hex": "c92c8f7bae844f67fa71181009c39e75cf5f68d22de5de67d2a621cfddf57114", "role": "CLIENT", "short_name": "LBDB", "snr": 3.82, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 70, "long_name": "Old Stag", "next_hop": 0, "num": "0x3148a12f", "position": {"altitude": 1020, "latitude": 33.518529, "location_source": "LOC_INTERNAL", "longitude": -106.755016, "time_offset_sec": 93}, "public_key_hex": "4b902cc9230b4885370f304fe23a6075f3faf48bf9b57467c2db1fb8622dcb30", "role": "CLIENT", "short_name": "OJ86", "snr": 4.7, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 1791, "long_name": "Loud Adder", "next_hop": 0, "num": "0x31a6a1e3", "position": {"altitude": 1118, "latitude": 32.634524, "location_source": "LOC_INTERNAL", "longitude": -107.177717, "time_offset_sec": 2041}, "public_key_hex": "299a024b5ba48817147c466d268a5f1a19df19cc757ba4226c9c6f37f7a3f2e9", "role": "CLIENT", "short_name": "LMAU", "snr": 1.54, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.824, "battery_level": 70, "channel_utilization": 8.51, "uptime_seconds": 23034, "voltage": 3.93}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 5550, "long_name": "Desert Cedar", "next_hop": 0, "num": "0x31fff78e", "position": {"altitude": 1916, "latitude": 32.538876, "location_source": "LOC_INTERNAL", "longitude": -107.03072, "time_offset_sec": 5711}, "public_key_hex": "0781a7eb508fc0c538cdd99780f491250f7e5325a63d37fc8ef3664f671991e3", "role": "CLIENT", "short_name": "DGCN", "snr": 7.54, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.935, "battery_level": 17, "channel_utilization": 9.45, "uptime_seconds": 35953, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1024.25, "iaq": 45, "relative_humidity": 30.09, "temperature": 23.56}, "hops_away": 2, "hw_model": "SEEED_WIO_TRACKER_L1_EINK", "last_heard_offset_sec": 1401, "long_name": "Frozen Heron", "next_hop": 103, "num": "0x3210af50", "position": {"altitude": 1273, "latitude": 33.848447, "location_source": "LOC_INTERNAL", "longitude": -107.514036, "time_offset_sec": 1503}, "public_key_hex": "e1e001184ee54ec7c0646a98c35b4561ecec57f3c2f4c10a6885cb6024dffca8", "role": "ROUTER", "short_name": "F5HQ", "snr": 1.84, "status": null, "telemetry": {"air_util_tx": 0.24, "battery_level": 75, "channel_utilization": 24.19, "uptime_seconds": 117051, "voltage": 3.975}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 2567, "long_name": "Brave Pony", "next_hop": 117, "num": "0x32919c69", "position": {"altitude": 1493, "latitude": 33.621492, "location_source": "LOC_INTERNAL", "longitude": -107.271347, "time_offset_sec": 2582}, "public_key_hex": "6dd3bcfb3a06e79a64f2d91f880a7abb3091eca24f9ab291a1e97ae18c61c383", "role": "CLIENT", "short_name": "BP7J", "snr": 9.61, "status": null, "telemetry": {"air_util_tx": 0.122, "battery_level": 71, "channel_utilization": 6.1, "uptime_seconds": 21430, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 2961, "long_name": "Sunny Bronco", "next_hop": 0, "num": "0x32dc1a76", "position": {"altitude": 1417, "latitude": 32.755904, "location_source": "LOC_INTERNAL", "longitude": -107.013091, "time_offset_sec": 3254}, "public_key_hex": "cc1303af364737c5f324c4b320d8c2072124475f10becb923fbfd08708f05021", "role": "CLIENT_MUTE", "short_name": "STBX", "snr": 4.13, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 2894, "long_name": "Storm Mole", "next_hop": 22, "num": "0x32f499a6", "position": {"altitude": 1596, "latitude": 33.814613, "location_source": "LOC_INTERNAL", "longitude": -107.14183, "time_offset_sec": 2962}, "public_key_hex": "7ff62f65c7a67fc4f7852b3faf04002d94522d7dbc22e36be2298374214b0e0d", "role": "CLIENT", "short_name": "SLZ8", "snr": 6.07, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 6321, "long_name": "Silver Bass", "next_hop": 204, "num": "0x330f06d8", "position": {"altitude": 1549, "latitude": 33.241452, "location_source": "LOC_INTERNAL", "longitude": -108.032326, "time_offset_sec": 6536}, "public_key_hex": "5e71597621bf7267184483913b770267bec132efc5d34f75b37e177dd6503eb6", "role": "CLIENT", "short_name": "🌵", "snr": 0.32, "status": null, "telemetry": {"air_util_tx": 0.219, "battery_level": 24, "channel_utilization": 14.56, "uptime_seconds": 6201, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 301, "long_name": "White Doe", "next_hop": 0, "num": "0x33b5c384", "position": {"altitude": 1916, "latitude": 33.342177, "location_source": "LOC_INTERNAL", "longitude": -107.48488, "time_offset_sec": 380}, "public_key_hex": "8dd111fc91dce2a62afa71e4612e4b0778102f5a46d545bdf04b3228dedd608e", "role": "CLIENT_HIDDEN", "short_name": "WENR", "snr": 4.32, "status": null, "telemetry": {"air_util_tx": 0.292, "battery_level": 62, "channel_utilization": 11.98, "uptime_seconds": 54735, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 4872, "long_name": "White Bass", "next_hop": 0, "num": "0x33b6711f", "position": {"altitude": 1275, "latitude": 33.221311, "location_source": "LOC_INTERNAL", "longitude": -107.068917, "time_offset_sec": 5022}, "public_key_hex": "12f331b46977af65cefbbe75943be108c668439b5079ebce47b4ec175f489364", "role": "CLIENT", "short_name": "W3X2", "snr": 11.91, "status": null, "telemetry": {"air_util_tx": 1.203, "battery_level": 50, "channel_utilization": 14.41, "uptime_seconds": 170602, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1790, "long_name": "Soft Pike", "next_hop": 0, "num": "0x348294ad", "position": {"altitude": 710, "latitude": 33.598746, "location_source": "LOC_INTERNAL", "longitude": -108.138437, "time_offset_sec": 1922}, "public_key_hex": "a0f3c269ce8c86665e461ddb1b37ee7705907807ec0ef1f5f9f279c407a0b20c", "role": "CLIENT", "short_name": "🌙", "snr": 7.01, "status": null, "telemetry": {"air_util_tx": 0.308, "battery_level": 65, "channel_utilization": 19.14, "uptime_seconds": 42664, "voltage": 3.885}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 2941, "long_name": "Tiny Badger", "next_hop": 38, "num": "0x34bf5541", "position": {"altitude": 1620, "latitude": 32.840343, "location_source": "LOC_INTERNAL", "longitude": -107.512689, "time_offset_sec": 2966}, "public_key_hex": "2a86016d6430e85b0dac4d8e4880491e5312197853d46a24c8871c40188a30db", "role": "CLIENT", "short_name": "TZ4C", "snr": 11.35, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.031, "battery_level": 23, "channel_utilization": 28.95, "uptime_seconds": 147350, "voltage": 3.507}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 5891, "long_name": "New Otter", "next_hop": 0, "num": "0x3543fc07", "position": {"altitude": 1414, "latitude": 34.551594, "location_source": "LOC_INTERNAL", "longitude": -106.134115, "time_offset_sec": 6027}, "public_key_hex": "85b64f1767c97c79d4cb15d12be49ab011e3f85011e21c44d81220b4b86283ca", "role": "CLIENT", "short_name": "N97N", "snr": 11.67, "status": null, "telemetry": {"air_util_tx": 0.612, "battery_level": 77, "channel_utilization": 1.99, "uptime_seconds": 242076, "voltage": 3.993}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 125, "long_name": "Sharp Lion", "next_hop": 141, "num": "0x359c376f", "position": {"altitude": 1180, "latitude": 33.557869, "location_source": "LOC_INTERNAL", "longitude": -107.626806, "time_offset_sec": 138}, "public_key_hex": "", "role": "CLIENT_BASE", "short_name": "SN7T", "snr": 6.47, "status": {"status": "low-batt"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 4, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 1929, "long_name": "Silent Cedar", "next_hop": 157, "num": "0x35e89ead", "position": null, "public_key_hex": "1489005e7bb07aa8e8695ad0e92706492e40be9c37ccc50f6837ef4d79d03224", "role": "CLIENT", "short_name": "🐢", "snr": 5.67, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 4919, "long_name": "White Ridge", "next_hop": 132, "num": "0x37294851", "position": {"altitude": 979, "latitude": 32.075937, "location_source": "LOC_INTERNAL", "longitude": -107.008495, "time_offset_sec": 5058}, "public_key_hex": "", "role": "CLIENT", "short_name": "WEDP", "snr": 4.49, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 9052, "long_name": "Steel Hawk", "next_hop": 0, "num": "0x372e6f8c", "position": {"altitude": 1797, "latitude": 32.753516, "location_source": "LOC_INTERNAL", "longitude": -108.284545, "time_offset_sec": 9141}, "public_key_hex": "0db68598c24a5862f20efb3157d1f202e4cd43a6a2f7e0ee459016a8a0e3dd9f", "role": "CLIENT", "short_name": "S6VC", "snr": 4.3, "status": null, "telemetry": {"air_util_tx": 0.959, "battery_level": 85, "channel_utilization": 5.57, "uptime_seconds": 20709, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 5158, "long_name": "Solar Adder", "next_hop": 0, "num": "0x375dc1a6", "position": {"altitude": 1177, "latitude": 32.721335, "location_source": "LOC_INTERNAL", "longitude": -107.359895, "time_offset_sec": 5417}, "public_key_hex": "4ba37ff4b9c69ae5c1a759d095d2a09ffd342c2e0110e36027a95c4c76e507b8", "role": "CLIENT", "short_name": "SF6A", "snr": 3.63, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.469, "battery_level": 62, "channel_utilization": 3.24, "uptime_seconds": 68574, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 12875, "long_name": "Sky Pony", "next_hop": 104, "num": "0x379552d2", "position": {"altitude": 1489, "latitude": 33.789051, "location_source": "LOC_INTERNAL", "longitude": -107.119094, "time_offset_sec": 13111}, "public_key_hex": "39e8349e42d7f60352c7aba9e07d6e1b988ecc43d1cb0cb5e102ca97dcb53838", "role": "CLIENT", "short_name": "SP46", "snr": 4.12, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 80, "long_name": "Misty Oak", "next_hop": 67, "num": "0x37b9fab4", "position": {"altitude": 1393, "latitude": 33.269396, "location_source": "LOC_INTERNAL", "longitude": -107.181673, "time_offset_sec": 245}, "public_key_hex": "94e90eec8fe7d12cac241d6fc450a724f1aef2901f60e60abf775639accddddc", "role": "CLIENT", "short_name": "MBZW", "snr": 8.79, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 2543, "long_name": "Dusk Cobra", "next_hop": 176, "num": "0x37dcc34a", "position": {"altitude": 1496, "latitude": 33.340681, "location_source": "LOC_INTERNAL", "longitude": -107.083151, "time_offset_sec": 2608}, "public_key_hex": "8180ae7681f78718a0e3fa25494d569ed1918cbde94dcbd79303d1c5a2558f4b", "role": "LOST_AND_FOUND", "short_name": "🗻", "snr": 1.02, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 1.035, "battery_level": 68, "channel_utilization": 6.26, "uptime_seconds": 133154, "voltage": 3.912}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 3263, "long_name": "Canyon Oak", "next_hop": 0, "num": "0x380f2b0e", "position": {"altitude": 1501, "latitude": 33.048196, "location_source": "LOC_INTERNAL", "longitude": -106.975414, "time_offset_sec": 3425}, "public_key_hex": "ed94a403602015b926702b5631037268e97e122f8dd719158872f828ed258411", "role": "ROUTER_LATE", "short_name": "CR99", "snr": 10.68, "status": null, "telemetry": {"air_util_tx": 0.66, "battery_level": 53, "channel_utilization": 1.08, "uptime_seconds": 90754, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 5718, "long_name": "Shady Crane", "next_hop": 12, "num": "0x38422b34", "position": {"altitude": 1398, "latitude": 31.939514, "location_source": "LOC_INTERNAL", "longitude": -107.647159, "time_offset_sec": 5875}, "public_key_hex": "39a05519ebcc12e828091b42c58f65fae034f53defcbdd07a204f7f568a7c0cc", "role": "CLIENT", "short_name": "SXAJ", "snr": 12.0, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 2528, "long_name": "Blue Doe", "next_hop": 0, "num": "0x390512a7", "position": {"altitude": 1173, "latitude": 32.38155, "location_source": "LOC_INTERNAL", "longitude": -107.627094, "time_offset_sec": 2567}, "public_key_hex": "f84aa57ff1dbbe3f4b025ddf092f0ba21b802f99cbb58781e31440bb56737ded", "role": "CLIENT", "short_name": "BBXY", "snr": 5.5, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2557, "long_name": "Sky Mustang", "next_hop": 0, "num": "0x39ec6ec9", "position": {"altitude": 1173, "latitude": 33.228267, "location_source": "LOC_INTERNAL", "longitude": -107.236545, "time_offset_sec": 2770}, "public_key_hex": "", "role": "CLIENT", "short_name": "SRG8", "snr": 7.55, "status": null, "telemetry": {"air_util_tx": 0.059, "battery_level": 94, "channel_utilization": 6.87, "uptime_seconds": 34215, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.82, "iaq": 0, "relative_humidity": 37.18, "temperature": 23.8}, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 512, "long_name": "Stone Arroyo", "next_hop": 0, "num": "0x3a813d75", "position": {"altitude": 1630, "latitude": 33.686901, "location_source": "LOC_INTERNAL", "longitude": -107.651696, "time_offset_sec": 694}, "public_key_hex": "8017e8ecf12f6b8730615c2897daaacae5ab46e6a6576c920d924f063965ae4b", "role": "CLIENT", "short_name": "SH40", "snr": 10.31, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.037, "battery_level": 101, "channel_utilization": 14.66, "uptime_seconds": 148162, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.96, "iaq": 52, "relative_humidity": 75.04, "temperature": 32.27}, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_T190", "last_heard_offset_sec": 959, "long_name": "Sneaky Otter", "next_hop": 0, "num": "0x3a84b3a1", "position": {"altitude": 1511, "latitude": 32.411666, "location_source": "LOC_INTERNAL", "longitude": -107.110419, "time_offset_sec": 1253}, "public_key_hex": "37223366dd83347f2e8414b53f15c66b66906ee6a0fc2a3785df2d41398d867f", "role": "CLIENT", "short_name": "SKAE", "snr": 3.55, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 15749, "long_name": "Tall Dolphin", "next_hop": 175, "num": "0x3a8c2376", "position": {"altitude": 1897, "latitude": 32.405617, "location_source": "LOC_INTERNAL", "longitude": -107.218084, "time_offset_sec": 15903}, "public_key_hex": "a97f23293aba138f94d8b449e493576ee5cbff156159ec9d1d3d69f5dab54c69", "role": "CLIENT_HIDDEN", "short_name": "TLMT", "snr": 3.79, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_ECHO", "last_heard_offset_sec": 230, "long_name": "Dusk Tortoise", "next_hop": 177, "num": "0x3ad732db", "position": {"altitude": 1555, "latitude": 33.345739, "location_source": "LOC_INTERNAL", "longitude": -106.721907, "time_offset_sec": 255}, "public_key_hex": "f3b5b31e8f4319acb8e7dc8c4ca2d16c559207fd0bd08c8676e317d8abd219b4", "role": "CLIENT", "short_name": "DJ1E", "snr": 2.32, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 286, "long_name": "Storm Lion", "next_hop": 0, "num": "0x3b2a4f38", "position": {"altitude": 1485, "latitude": 32.976493, "location_source": "LOC_INTERNAL", "longitude": -107.309679, "time_offset_sec": 570}, "public_key_hex": "", "role": "CLIENT", "short_name": "🌲", "snr": 2.6, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.719, "battery_level": 22, "channel_utilization": 2.8, "uptime_seconds": 84144, "voltage": 3.498}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 1135, "long_name": "Loud Pike", "next_hop": 0, "num": "0x3bbdf785", "position": {"altitude": 1010, "latitude": 31.796316, "location_source": "LOC_INTERNAL", "longitude": -106.618855, "time_offset_sec": 1417}, "public_key_hex": "", "role": "CLIENT", "short_name": "L8HA", "snr": 6.95, "status": null, "telemetry": {"air_util_tx": 2.242, "battery_level": 13, "channel_utilization": 13.33, "uptime_seconds": 179196, "voltage": 3.417}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 833, "long_name": "Sunny Turtle", "next_hop": 0, "num": "0x3bec6322", "position": null, "public_key_hex": "a36c93ac8c31e0e366057b42995c278bce4f58303e61ffd82c69d9b6d19c036f", "role": "CLIENT", "short_name": "S8R7", "snr": 10.81, "status": null, "telemetry": {"air_util_tx": 0.106, "battery_level": 24, "channel_utilization": 5.61, "uptime_seconds": 74568, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3132, "long_name": "Storm Hare", "next_hop": 0, "num": "0x3c260256", "position": {"altitude": 1173, "latitude": 33.178951, "location_source": "LOC_INTERNAL", "longitude": -107.43765, "time_offset_sec": 3375}, "public_key_hex": "019a1fcd102952418ce2c96a9ca88b32060dac7f35c9607bbc7b3089a6b7e424", "role": "CLIENT", "short_name": "S7F4", "snr": 5.59, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 1.565, "battery_level": 101, "channel_utilization": 8.06, "uptime_seconds": 123017, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 495, "long_name": "Dusk Coyote", "next_hop": 30, "num": "0x3c7ec803", "position": null, "public_key_hex": "f5b3257469beb79d06461d9ced20fd6b0f6adcc88af8819ac75733c11b234e58", "role": "CLIENT", "short_name": "DI41", "snr": 9.76, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.13, "battery_level": 101, "channel_utilization": 3.31, "uptime_seconds": 18934, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 20329, "long_name": "Gold Lynx", "next_hop": 120, "num": "0x3cabd975", "position": {"altitude": 1276, "latitude": 32.83804, "location_source": "LOC_INTERNAL", "longitude": -106.289307, "time_offset_sec": 20449}, "public_key_hex": "94f93fe3d04a4a8512b2c1ef538ab300915f177f802f195115d6f9c503d8993c", "role": "CLIENT", "short_name": "G2NU", "snr": 3.88, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 6311, "long_name": "Dawn Yucca", "next_hop": 178, "num": "0x3cb174cf", "position": {"altitude": 909, "latitude": 32.290424, "location_source": "LOC_INTERNAL", "longitude": -107.492656, "time_offset_sec": 6417}, "public_key_hex": "05022520e20550639ca28ef8dc8355cab42603a05ee1faa2c11c265f29cc13a7", "role": "CLIENT_MUTE", "short_name": "DU03", "snr": 4.56, "status": {"status": "running"}, "telemetry": {"air_util_tx": 2.419, "battery_level": 37, "channel_utilization": 13.49, "uptime_seconds": 43314, "voltage": 3.633}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 2703, "long_name": "Sharp Phoenix", "next_hop": 167, "num": "0x3d43985f", "position": {"altitude": 1576, "latitude": 32.197037, "location_source": "LOC_INTERNAL", "longitude": -107.449257, "time_offset_sec": 2818}, "public_key_hex": "3860815ade9fc1911beef95e37cebde1e0ebd7a1f7d8aa1ea78d897b81eb8e06", "role": "CLIENT", "short_name": "SZ7I", "snr": 7.09, "status": null, "telemetry": {"air_util_tx": 0.263, "battery_level": 13, "channel_utilization": 24.4, "uptime_seconds": 4251, "voltage": 3.417}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1008.74, "iaq": 53, "relative_humidity": 47.2, "temperature": 8.43}, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1209, "long_name": "Red Arroyo", "next_hop": 0, "num": "0x3de79994", "position": null, "public_key_hex": "df6274b7cd63d960c7bb72d541153cf794f2d5ad2f9083f283318c2c0d68edff", "role": "CLIENT", "short_name": "RWS6", "snr": 3.89, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 546, "long_name": "Stone Cedar", "next_hop": 0, "num": "0x3e1c0ece", "position": {"altitude": 1595, "latitude": 32.885307, "location_source": "LOC_INTERNAL", "longitude": -107.535058, "time_offset_sec": 744}, "public_key_hex": "c051f4a8daa982873bc2fec7e2647eec49fb097e704e5cfc695b83c1874e8fe7", "role": "CLIENT", "short_name": "SIQG", "snr": -1.15, "status": null, "telemetry": {"air_util_tx": 1.175, "battery_level": 42, "channel_utilization": 2.81, "uptime_seconds": 484989, "voltage": 3.678}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 4819, "long_name": "Sky Gecko", "next_hop": 49, "num": "0x3e2e20ef", "position": {"altitude": 1115, "latitude": 33.106531, "location_source": "LOC_INTERNAL", "longitude": -107.458733, "time_offset_sec": 5073}, "public_key_hex": "c9b9950e932fb3c1ccc7abca60fe1dad4f7653cd9df0412f81e913d143765ca1", "role": "ROUTER", "short_name": "SMVM", "snr": 9.61, "status": null, "telemetry": {"air_util_tx": 0.047, "battery_level": 84, "channel_utilization": 13.63, "uptime_seconds": 91994, "voltage": 4.056}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1509, "long_name": "Shady Crow", "next_hop": 158, "num": "0x3e345006", "position": {"altitude": 861, "latitude": 34.091143, "location_source": "LOC_INTERNAL", "longitude": -108.017718, "time_offset_sec": 1701}, "public_key_hex": "12720e4479465a158aa2c3bb3a70d7f6fada35bd731846f6daf1e93d11f2cd3c", "role": "CLIENT", "short_name": "SPIY", "snr": 7.95, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 1604, "long_name": "Happy Bronco", "next_hop": 0, "num": "0x3e37d297", "position": {"altitude": 1028, "latitude": 33.487795, "location_source": "LOC_INTERNAL", "longitude": -108.381078, "time_offset_sec": 1706}, "public_key_hex": "", "role": "SENSOR", "short_name": "HQS2", "snr": 0.69, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 5, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 279, "long_name": "Sneaky Bison", "next_hop": 72, "num": "0x3e82ffd3", "position": {"altitude": 1935, "latitude": 32.577825, "location_source": "LOC_INTERNAL", "longitude": -107.174252, "time_offset_sec": 441}, "public_key_hex": "7347bc043dc918381d40d8b051a320d52f9dfcfc8821248023171d01c1fdf9bd", "role": "CLIENT", "short_name": "STTN", "snr": 1.29, "status": null, "telemetry": {"air_util_tx": 1.068, "battery_level": 101, "channel_utilization": 13.55, "uptime_seconds": 13102, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": {"barometric_pressure": 1007.63, "iaq": 32, "relative_humidity": 51.24, "temperature": 31.2}, "hops_away": 0, "hw_model": "SEEED_SOLAR_NODE", "last_heard_offset_sec": 988, "long_name": "Wild Mamba", "next_hop": 0, "num": "0x3ef69851", "position": {"altitude": 1700, "latitude": 32.488215, "location_source": "LOC_INTERNAL", "longitude": -106.708983, "time_offset_sec": 1278}, "public_key_hex": "2ef11dda5453dbf8030bc69942f50d41949d9ade3b08fdf988a1898b81931b64", "role": "CLIENT", "short_name": "WK4I", "snr": 3.82, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 7395, "long_name": "Giant Sage", "next_hop": 0, "num": "0x3f4e40a6", "position": {"altitude": 1124, "latitude": 33.227145, "location_source": "LOC_INTERNAL", "longitude": -107.497745, "time_offset_sec": 7540}, "public_key_hex": "7e5a41230314362f9bc3bcc353dc039bfda14de95c0630eb9b08e6901ea33242", "role": "CLIENT", "short_name": "GC2V", "snr": 4.58, "status": null, "telemetry": {"air_util_tx": 2.102, "battery_level": 54, "channel_utilization": 15.97, "uptime_seconds": 580, "voltage": 3.786}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "RAK4631", "last_heard_offset_sec": 8505, "long_name": "Sky Iguana", "next_hop": 107, "num": "0x3f5be4f1", "position": {"altitude": 1117, "latitude": 33.851012, "location_source": "LOC_INTERNAL", "longitude": -107.749199, "time_offset_sec": 8548}, "public_key_hex": "3a799fffecacb9692386c0d7af0284d392b541bde45ffc3e3a2c4251b375e3c6", "role": "CLIENT", "short_name": "S7XR", "snr": 3.26, "status": null, "telemetry": {"air_util_tx": 0.187, "battery_level": 11, "channel_utilization": 0.88, "uptime_seconds": 11913, "voltage": 3.399}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "THINKNODE_M5", "last_heard_offset_sec": 5551, "long_name": "Smooth Lynx", "next_hop": 152, "num": "0x3faae676", "position": {"altitude": 1090, "latitude": 33.621759, "location_source": "LOC_INTERNAL", "longitude": -107.207629, "time_offset_sec": 5624}, "public_key_hex": "6b2df0142fbbd3f0ecae48cbfaa5e226e48ea965f68ee21c0a3529fa681f395f", "role": "CLIENT_MUTE", "short_name": "SLVN", "snr": 8.14, "status": {"status": "weak-signal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 5055, "long_name": "Copper Falcon", "next_hop": 0, "num": "0x3fc1c32e", "position": {"altitude": 1715, "latitude": 33.357183, "location_source": "LOC_INTERNAL", "longitude": -107.29983, "time_offset_sec": 5266}, "public_key_hex": "a8f177a6bf45a3cd0482142ed187d183d34690fa7cad78fccd2ff3c0b9d8ca6b", "role": "CLIENT", "short_name": "CA61", "snr": 3.39, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.372, "battery_level": 42, "channel_utilization": 3.79, "uptime_seconds": 29867, "voltage": 3.678}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 2065, "long_name": "Copper Sage", "next_hop": 81, "num": "0x407a7762", "position": {"altitude": 1109, "latitude": 33.584418, "location_source": "LOC_INTERNAL", "longitude": -106.875554, "time_offset_sec": 2266}, "public_key_hex": "ff0e287fb0024ef961b17b6282670664bc449f0d9514473a1759fd62e9ffc1b5", "role": "CLIENT", "short_name": "CI0W", "snr": 10.75, "status": null, "telemetry": {"air_util_tx": 0.134, "battery_level": 73, "channel_utilization": 13.32, "uptime_seconds": 183501, "voltage": 3.957}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 893, "long_name": "Wild Stag", "next_hop": 0, "num": "0x409da0b9", "position": {"altitude": 1599, "latitude": 32.899158, "location_source": "LOC_INTERNAL", "longitude": -107.531942, "time_offset_sec": 1062}, "public_key_hex": "d3ba91f50140e489296741e63741c381ea2e523f01bcb47917e7a70f117c5d3e", "role": "CLIENT", "short_name": "WFNN", "snr": 9.37, "status": null, "telemetry": {"air_util_tx": 0.551, "battery_level": 78, "channel_utilization": 23.83, "uptime_seconds": 223308, "voltage": 4.002}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 3013, "long_name": "White Shark", "next_hop": 166, "num": "0x421ed9cd", "position": null, "public_key_hex": "39b00b0a5880ab4c581c7c992a3c288d353c77eac7d0022b16f17fd53a3fb148", "role": "ROUTER", "short_name": "WWUV", "snr": 10.36, "status": null, "telemetry": {"air_util_tx": 1.01, "battery_level": 60, "channel_utilization": 15.15, "uptime_seconds": 8298, "voltage": 3.84}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 4705, "long_name": "Lone Dolphin", "next_hop": 143, "num": "0x425b3167", "position": {"altitude": 1324, "latitude": 32.239844, "location_source": "LOC_INTERNAL", "longitude": -107.204437, "time_offset_sec": 4903}, "public_key_hex": "67f16b834d9faa0218e6a172b5ce1a425d13a53cbdc7ccdeda6033ff5c16de4c", "role": "CLIENT", "short_name": "🦉", "snr": 1.71, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 798, "long_name": "Red Mamba", "next_hop": 0, "num": "0x42634862", "position": {"altitude": 1468, "latitude": 32.720221, "location_source": "LOC_INTERNAL", "longitude": -106.922564, "time_offset_sec": 833}, "public_key_hex": "5054c78aa27629488c6868c7f84b2fbb0301ea781f67b574855d49887628d8d2", "role": "ROUTER", "short_name": "RL00", "snr": 2.64, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.19, "battery_level": 83, "channel_utilization": 4.48, "uptime_seconds": 4820, "voltage": 4.047}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 1498, "long_name": "Quick Mesa", "next_hop": 0, "num": "0x42b4cb24", "position": {"altitude": 1632, "latitude": 32.996339, "location_source": "LOC_INTERNAL", "longitude": -106.079693, "time_offset_sec": 1708}, "public_key_hex": "94142bb7f81006173eab540143cd692017d4d1919bd1fd17804d604c46170991", "role": "CLIENT", "short_name": "Q633", "snr": 1.13, "status": null, "telemetry": {"air_util_tx": 0.753, "battery_level": 54, "channel_utilization": 11.35, "uptime_seconds": 35851, "voltage": 3.786}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 3, "environment": {"barometric_pressure": 991.66, "iaq": 73, "relative_humidity": 63.16, "temperature": 4.66}, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 606, "long_name": "Happy Colt", "next_hop": 172, "num": "0x42cd002f", "position": {"altitude": 1024, "latitude": 33.287455, "location_source": "LOC_INTERNAL", "longitude": -107.171553, "time_offset_sec": 814}, "public_key_hex": "9eedd9572ef82c539e9c4beb86ae45642d6f8f49f81003d17f329f9f15fd0fad", "role": "CLIENT", "short_name": "HIX1", "snr": 9.97, "status": null, "telemetry": {"air_util_tx": 0.805, "battery_level": 60, "channel_utilization": 6.72, "uptime_seconds": 19641, "voltage": 3.84}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1024.37, "iaq": 71, "relative_humidity": 62.97, "temperature": 16.45}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 10218, "long_name": "Blue Yucca", "next_hop": 0, "num": "0x42cfc132", "position": {"altitude": 788, "latitude": 33.702353, "location_source": "LOC_INTERNAL", "longitude": -106.776716, "time_offset_sec": 10278}, "public_key_hex": "c171e7e65e37259d6b0d1a755d35368bae1ce20bad2834362ed7229a8afefe7f", "role": "CLIENT", "short_name": "🐝", "snr": 5.07, "status": null, "telemetry": {"air_util_tx": 0.941, "battery_level": 34, "channel_utilization": 9.39, "uptime_seconds": 35246, "voltage": 3.606}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 3792, "long_name": "Old Cobra", "next_hop": 0, "num": "0x42dffc4f", "position": {"altitude": 1697, "latitude": 32.803374, "location_source": "LOC_INTERNAL", "longitude": -107.081468, "time_offset_sec": 4018}, "public_key_hex": "c392a2e251f6983101813a5237cbbe02b5119ed360f037d0f33585bcd10f8e60", "role": "CLIENT", "short_name": "OQWC", "snr": -0.14, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "THINKNODE_M6", "last_heard_offset_sec": 5042, "long_name": "Lunar Mustang", "next_hop": 169, "num": "0x433523d0", "position": null, "public_key_hex": "d253a965504c9632d3ce55d66e9c5b67be335079e309154915c60c23ef0973c8", "role": "CLIENT", "short_name": "LEBO", "snr": -3.74, "status": {"status": "online"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK", "last_heard_offset_sec": 4528, "long_name": "White Stag", "next_hop": 3, "num": "0x43fbf777", "position": {"altitude": 1537, "latitude": 33.003847, "location_source": "LOC_INTERNAL", "longitude": -106.629808, "time_offset_sec": 4634}, "public_key_hex": "23c075dac68fa78051ed99c03bc904cb534f9c2acb50882aaf93b271b9fa265e", "role": "SENSOR", "short_name": "🐝", "snr": 7.42, "status": null, "telemetry": {"air_util_tx": 1.153, "battery_level": 82, "channel_utilization": 20.87, "uptime_seconds": 15486, "voltage": 4.038}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2199, "long_name": "Storm Seal", "next_hop": 0, "num": "0x447b9432", "position": {"altitude": 1839, "latitude": 33.347711, "location_source": "LOC_INTERNAL", "longitude": -106.773231, "time_offset_sec": 2322}, "public_key_hex": "44c2ce2da5b8ed09ffb3ec7675c09be2aaba7f89fe9a28d4ff96bddf00eca6e2", "role": "CLIENT", "short_name": "🦇", "snr": 2.56, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 3, "hw_model": "MUZI_R1_NEO", "last_heard_offset_sec": 9703, "long_name": "Gold Whale", "next_hop": 52, "num": "0x4495d3e7", "position": {"altitude": 1687, "latitude": 33.139536, "location_source": "LOC_INTERNAL", "longitude": -107.128211, "time_offset_sec": 9823}, "public_key_hex": "", "role": "CLIENT", "short_name": "G5TG", "snr": 5.28, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 4433, "long_name": "Bright Lynx", "next_hop": 0, "num": "0x4585a4d7", "position": {"altitude": 1508, "latitude": 34.392774, "location_source": "LOC_INTERNAL", "longitude": -107.622506, "time_offset_sec": 4707}, "public_key_hex": "7363006b39bc789935aef32753e5a6b2463f253c6fc81b247dbb4e2c6ee6d8cc", "role": "CLIENT", "short_name": "BEX9", "snr": 5.31, "status": null, "telemetry": {"air_util_tx": 0.123, "battery_level": 93, "channel_utilization": 3.01, "uptime_seconds": 45971, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "RAK4631", "last_heard_offset_sec": 3304, "long_name": "Stone Ridge", "next_hop": 104, "num": "0x464a3092", "position": null, "public_key_hex": "236a842d43af5200d5851b93149ceb271d6401c0d1f9869b4d03ff2b6d9b3504", "role": "CLIENT", "short_name": "S3FD", "snr": 5.87, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.119, "battery_level": 93, "channel_utilization": 6.64, "uptime_seconds": 83, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.56, "iaq": 69, "relative_humidity": 59.24, "temperature": 22.74}, "hops_away": 2, "hw_model": "RAK4631", "last_heard_offset_sec": 1878, "long_name": "Old Coyote", "next_hop": 161, "num": "0x465a3f45", "position": null, "public_key_hex": "589dd2ce3e852dfcebc8383716b51049fedf5958d4c47bfd4fcd8180753c9265", "role": "CLIENT", "short_name": "ODG9", "snr": 12.0, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 996.74, "iaq": 30, "relative_humidity": 22.68, "temperature": 19.77}, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1650, "long_name": "Howling Bear", "next_hop": 26, "num": "0x46829c18", "position": {"altitude": 1186, "latitude": 32.485891, "location_source": "LOC_INTERNAL", "longitude": -106.568956, "time_offset_sec": 1650}, "public_key_hex": "20b91aa8f3a37933c469b27ca1ef6b2ead041017c665e224db5815bcf0ceee06", "role": "CLIENT", "short_name": "HAMZ", "snr": 8.05, "status": null, "telemetry": {"air_util_tx": 0.672, "battery_level": 101, "channel_utilization": 11.65, "uptime_seconds": 108535, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 3288, "long_name": "Smooth Wolf", "next_hop": 0, "num": "0x46d3022f", "position": {"altitude": 1030, "latitude": 33.623966, "location_source": "LOC_INTERNAL", "longitude": -106.987025, "time_offset_sec": 3366}, "public_key_hex": "02d902254db70ef843d914b4a652673b97d5f83869476410da2b0b0d9e3c6bdf", "role": "CLIENT", "short_name": "🐺", "snr": 2.34, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 2607, "long_name": "Iron Otter", "next_hop": 0, "num": "0x4723794e", "position": {"altitude": 1665, "latitude": 33.972929, "location_source": "LOC_INTERNAL", "longitude": -107.536336, "time_offset_sec": 2621}, "public_key_hex": "e50842a4c37590a895eb24393289b2cd43f3389d75f651610d1ce8a7a6363c8d", "role": "CLIENT", "short_name": "I5UV", "snr": 10.29, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.857, "battery_level": 65, "channel_utilization": 34.29, "uptime_seconds": 40045, "voltage": 3.885}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 5635, "long_name": "Loud Mole", "next_hop": 189, "num": "0x4745fcb5", "position": {"altitude": 1856, "latitude": 32.963171, "location_source": "LOC_INTERNAL", "longitude": -106.7369, "time_offset_sec": 5846}, "public_key_hex": "eaa31929e29386358a971950bcc69f76cc6e63d7864bb0f333a017881d62798d", "role": "LOST_AND_FOUND", "short_name": "LIM1", "snr": 1.13, "status": {"status": "online"}, "telemetry": {"air_util_tx": 2.709, "battery_level": 94, "channel_utilization": 28.13, "uptime_seconds": 43337, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 10027, "long_name": "Slow Iguana", "next_hop": 0, "num": "0x4747fb52", "position": null, "public_key_hex": "7f4c72ed406a733349893efe8a0954be75f10614bc89b504591a34a42d8ed1d6", "role": "CLIENT", "short_name": "SL24", "snr": 3.13, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.22, "battery_level": 51, "channel_utilization": 2.01, "uptime_seconds": 78386, "voltage": 3.759}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1015.49, "iaq": 29, "relative_humidity": 47.55, "temperature": 17.24}, "hops_away": 1, "hw_model": "XIAO_NRF52_KIT", "last_heard_offset_sec": 3124, "long_name": "Fast Adder", "next_hop": 44, "num": "0x47bce2ba", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "FKTF", "snr": 10.59, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.198, "battery_level": 62, "channel_utilization": 26.66, "uptime_seconds": 43070, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 2073, "long_name": "River Marmot", "next_hop": 0, "num": "0x47c71459", "position": null, "public_key_hex": "422de85eb248649548c824bd9d138293e7d7acce9420b4306f742fcf27da6c94", "role": "CLIENT", "short_name": "🦂", "snr": 9.33, "status": null, "telemetry": {"air_util_tx": 1.326, "battery_level": 38, "channel_utilization": 11.01, "uptime_seconds": 93587, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 987, "long_name": "Howling Gecko", "next_hop": 0, "num": "0x47fb66b1", "position": {"altitude": 1262, "latitude": 33.495338, "location_source": "LOC_INTERNAL", "longitude": -107.307232, "time_offset_sec": 1179}, "public_key_hex": "432574e8c84556bb7f265bb9dd4ffd3b0f85ffea3869b0accdfc47ba65c74b35", "role": "CLIENT", "short_name": "HBFQ", "snr": 5.38, "status": null, "telemetry": {"air_util_tx": 0.999, "battery_level": 14, "channel_utilization": 3.54, "uptime_seconds": 222947, "voltage": 3.426}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 3776, "long_name": "Smooth Cactus", "next_hop": 0, "num": "0x483a694f", "position": {"altitude": 1465, "latitude": 33.427641, "location_source": "LOC_INTERNAL", "longitude": -107.340998, "time_offset_sec": 3834}, "public_key_hex": "f58d38baf30c2b9e7f5352fb608cc61cb8db6fecf43580b179335c916d09c71e", "role": "CLIENT", "short_name": "SCF7", "snr": 4.95, "status": {"status": "weak-signal"}, "telemetry": {"air_util_tx": 0.783, "battery_level": 92, "channel_utilization": 2.41, "uptime_seconds": 122984, "voltage": 4.128}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.77, "iaq": 25, "relative_humidity": 19.83, "temperature": 26.33}, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4438, "long_name": "Howling Oak", "next_hop": 189, "num": "0x483c475f", "position": {"altitude": 1427, "latitude": 33.889055, "location_source": "LOC_INTERNAL", "longitude": -107.334535, "time_offset_sec": 4520}, "public_key_hex": "ec54f6144acd6f5a389097a1cdc454e25216a542e339aa758bfd6b5bf6999666", "role": "CLIENT", "short_name": "HP27", "snr": 8.16, "status": null, "telemetry": {"air_util_tx": 0.619, "battery_level": 24, "channel_utilization": 14.2, "uptime_seconds": 76704, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 1418, "long_name": "Brave Raven", "next_hop": 54, "num": "0x483eca7c", "position": {"altitude": 1152, "latitude": 32.978165, "location_source": "LOC_INTERNAL", "longitude": -108.217729, "time_offset_sec": 1425}, "public_key_hex": "e78392b59682d33d2ada4cec85466d16393a3d8d71d2a36d145658c25933367d", "role": "CLIENT", "short_name": "🐢", "snr": 2.07, "status": null, "telemetry": {"air_util_tx": 0.22, "battery_level": 53, "channel_utilization": 11.54, "uptime_seconds": 407445, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 1383, "long_name": "Happy Seal", "next_hop": 132, "num": "0x4854156c", "position": {"altitude": 1442, "latitude": 33.606331, "location_source": "LOC_INTERNAL", "longitude": -106.600787, "time_offset_sec": 1589}, "public_key_hex": "81a71b86b569f004e34cf904aa6e8c5412423ce32aa4183ba187c4fe734b1d14", "role": "CLIENT", "short_name": "HENS", "snr": 9.18, "status": null, "telemetry": {"air_util_tx": 0.237, "battery_level": 58, "channel_utilization": 9.9, "uptime_seconds": 47487, "voltage": 3.822}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 1018, "long_name": "Sneaky Cougar", "next_hop": 0, "num": "0x487d2471", "position": null, "public_key_hex": "ebcc5fc22b928136fea4b0ca3c1f5094674e47bbb2eb8e6ffe7874fab8b28f58", "role": "CLIENT", "short_name": "SAKC", "snr": 4.16, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 394, "long_name": "Shady Cobra", "next_hop": 145, "num": "0x48e901f1", "position": {"altitude": 1380, "latitude": 32.872246, "location_source": "LOC_INTERNAL", "longitude": -107.212042, "time_offset_sec": 510}, "public_key_hex": "ad5b6379d1d65f12df4d33cee476e17dff44ce1efb71a74fc55d35a7333c6b52", "role": "SENSOR", "short_name": "SQ69", "snr": 4.21, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.444, "battery_level": 60, "channel_utilization": 15.12, "uptime_seconds": 19835, "voltage": 3.84}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 10719, "long_name": "Brave Otter", "next_hop": 201, "num": "0x490313b5", "position": {"altitude": 1593, "latitude": 33.112042, "location_source": "LOC_INTERNAL", "longitude": -107.730151, "time_offset_sec": 11017}, "public_key_hex": "69e40f351dc853e1aa8fdfc5b913dc73439febe73e3290cbfd2c43b1f6768963", "role": "CLIENT", "short_name": "B8SD", "snr": 5.64, "status": null, "telemetry": {"air_util_tx": 0.148, "battery_level": 44, "channel_utilization": 8.24, "uptime_seconds": 79369, "voltage": 3.696}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 3047, "long_name": "Shady Crow", "next_hop": 0, "num": "0x491344f0", "position": {"altitude": 1296, "latitude": 32.046758, "location_source": "LOC_INTERNAL", "longitude": -107.505796, "time_offset_sec": 3118}, "public_key_hex": "35b6a7167c3329e4dd884e4463bd0f229255e32375d05bc0e72154777e8f5182", "role": "CLIENT", "short_name": "🦉", "snr": 4.89, "status": null, "telemetry": {"air_util_tx": 0.678, "battery_level": 45, "channel_utilization": 28.61, "uptime_seconds": 123590, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2664, "long_name": "Bright Moose", "next_hop": 249, "num": "0x49150ca0", "position": {"altitude": 1185, "latitude": 33.136873, "location_source": "LOC_INTERNAL", "longitude": -107.306155, "time_offset_sec": 2827}, "public_key_hex": "18c470234ec7dd4cd49ccedb8655a11d095fba920d7d695148d569eccfb2e596", "role": "CLIENT", "short_name": "B7Y5", "snr": 7.32, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 3760, "long_name": "Happy Bison", "next_hop": 112, "num": "0x49a0c8c0", "position": {"altitude": 1093, "latitude": 34.141068, "location_source": "LOC_INTERNAL", "longitude": -107.324738, "time_offset_sec": 3785}, "public_key_hex": "776c6f1ea4fe04fabd21ef54f4cd6e04772041a21b83dc4e465e5b9c925207f8", "role": "CLIENT_BASE", "short_name": "H31Z", "snr": 4.87, "status": null, "telemetry": {"air_util_tx": 0.722, "battery_level": 53, "channel_utilization": 15.65, "uptime_seconds": 73213, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 3548, "long_name": "Sunny Phoenix", "next_hop": 0, "num": "0x4a0630d7", "position": null, "public_key_hex": "8e095643dbfb5687150b592ce52b655bed7182e40bb3805bd5603021bd5b7973", "role": "CLIENT", "short_name": "S67Z", "snr": 5.25, "status": null, "telemetry": {"air_util_tx": 0.862, "battery_level": 33, "channel_utilization": 11.21, "uptime_seconds": 16708, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.65, "iaq": 65, "relative_humidity": 15.51, "temperature": 14.0}, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 1691, "long_name": "Quick Crane", "next_hop": 48, "num": "0x4a7fcb93", "position": {"altitude": 1567, "latitude": 32.745722, "location_source": "LOC_INTERNAL", "longitude": -106.880759, "time_offset_sec": 1734}, "public_key_hex": "", "role": "CLIENT", "short_name": "Q2LX", "snr": 7.11, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 189, "long_name": "Lunar Doe", "next_hop": 201, "num": "0x4ab21734", "position": {"altitude": 1001, "latitude": 33.468173, "location_source": "LOC_INTERNAL", "longitude": -105.934058, "time_offset_sec": 308}, "public_key_hex": "43bfb69a2f86b78000b259d576f8f0352e1e420c5930882690f4281487248bf8", "role": "CLIENT", "short_name": "LO5R", "snr": 3.23, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.37, "battery_level": 10, "channel_utilization": 12.63, "uptime_seconds": 511662, "voltage": 3.39}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 770, "long_name": "Brave Hawk", "next_hop": 0, "num": "0x4ae230a9", "position": {"altitude": 1082, "latitude": 32.741686, "location_source": "LOC_INTERNAL", "longitude": -107.136659, "time_offset_sec": 859}, "public_key_hex": "49be2f27b080df1a5ed4aa7c30212ae34b6f568f173eb78f9ffb3c36344663ff", "role": "CLIENT", "short_name": "BHTB", "snr": 10.44, "status": null, "telemetry": {"air_util_tx": 0.278, "battery_level": 34, "channel_utilization": 4.11, "uptime_seconds": 2907, "voltage": 3.606}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1957, "long_name": "Canyon Oak", "next_hop": 227, "num": "0x4aec3038", "position": null, "public_key_hex": "9dda018df6f1e6ff27f619de60411bb27aa73ce0846de74d5dca1f01036f1c40", "role": "ROUTER_LATE", "short_name": "C9DX", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.298, "battery_level": 31, "channel_utilization": 7.99, "uptime_seconds": 69430, "voltage": 3.579}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 532, "long_name": "Steel Otter", "next_hop": 2, "num": "0x4b187b87", "position": {"altitude": 1352, "latitude": 33.03721, "location_source": "LOC_INTERNAL", "longitude": -108.066405, "time_offset_sec": 807}, "public_key_hex": "c121485dc7bab5d818080c7cbc32f96e2c987d362b00b55221713ad65663f8fb", "role": "SENSOR", "short_name": "S3JY", "snr": 2.94, "status": null, "telemetry": {"air_util_tx": 2.114, "battery_level": 52, "channel_utilization": 20.96, "uptime_seconds": 188564, "voltage": 3.768}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1001.93, "iaq": 13, "relative_humidity": 52.34, "temperature": 15.56}, "hops_away": 1, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 134, "long_name": "Canyon Cobra", "next_hop": 134, "num": "0x4b370785", "position": null, "public_key_hex": "7dfb7417dcd46e90037e97d0f81ff2b4f617fff6e1a29914bad7d1b3176f7dcd", "role": "CLIENT", "short_name": "🌲", "snr": 10.14, "status": null, "telemetry": {"air_util_tx": 0.746, "battery_level": 36, "channel_utilization": 17.54, "uptime_seconds": 155984, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3533, "long_name": "Old Fox", "next_hop": 102, "num": "0x4b4a8774", "position": {"altitude": 1648, "latitude": 32.894622, "location_source": "LOC_INTERNAL", "longitude": -107.582707, "time_offset_sec": 3707}, "public_key_hex": "2083f83ca66ec5c091f40bf757c6e331bf8606a420feb3fc92b57235b882bb92", "role": "CLIENT", "short_name": "OE96", "snr": 12.0, "status": {"status": "running"}, "telemetry": {"air_util_tx": 1.557, "battery_level": 93, "channel_utilization": 6.69, "uptime_seconds": 54186, "voltage": 4.137}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 804, "long_name": "Slow Falcon", "next_hop": 0, "num": "0x4b637625", "position": {"altitude": 797, "latitude": 32.688944, "location_source": "LOC_INTERNAL", "longitude": -107.674431, "time_offset_sec": 1069}, "public_key_hex": "366f4d2e6562fbac0a875f3952383cf43fcfa929fa89e39209d2a851be5d7af2", "role": "CLIENT", "short_name": "SJLO", "snr": 6.1, "status": null, "telemetry": {"air_util_tx": 0.317, "battery_level": 46, "channel_utilization": 12.34, "uptime_seconds": 14979, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 651, "long_name": "Drifting Moose", "next_hop": 0, "num": "0x4b77d530", "position": {"altitude": 1052, "latitude": 34.148328, "location_source": "LOC_INTERNAL", "longitude": -106.696747, "time_offset_sec": 951}, "public_key_hex": "88e3e6b2d5c4b4d573209e2f060a2dc9bd860f8c7dfc2d1606cec8fb242d741f", "role": "CLIENT", "short_name": "DLDU", "snr": 1.83, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.374, "battery_level": 69, "channel_utilization": 17.12, "uptime_seconds": 2429, "voltage": 3.921}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 4768, "long_name": "Old Heron", "next_hop": 0, "num": "0x4b9ee1da", "position": {"altitude": 1137, "latitude": 32.759026, "location_source": "LOC_INTERNAL", "longitude": -106.833195, "time_offset_sec": 5043}, "public_key_hex": "321a0086ee8d59658a42927710adab144ce483f912b38f64b04a39c6ac3e5e56", "role": "CLIENT", "short_name": "OU7P", "snr": 2.01, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1012.15, "iaq": 20, "relative_humidity": 82.06, "temperature": 30.37}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2498, "long_name": "Stone Elk", "next_hop": 0, "num": "0x4c1991e8", "position": {"altitude": 1529, "latitude": 33.014879, "location_source": "LOC_INTERNAL", "longitude": -107.731089, "time_offset_sec": 2507}, "public_key_hex": "3a08be45aa8e7346b7a03740e9f3896a1bbbe608bcebac459509fd6d0d9dad12", "role": "CLIENT", "short_name": "SLAD", "snr": 0.7, "status": null, "telemetry": {"air_util_tx": 0.548, "battery_level": 78, "channel_utilization": 9.59, "uptime_seconds": 96023, "voltage": 4.002}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1012.94, "iaq": 20, "relative_humidity": 45.95, "temperature": 6.92}, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 2408, "long_name": "Silver Eagle", "next_hop": 0, "num": "0x4c7f99b5", "position": {"altitude": 1566, "latitude": 33.220154, "location_source": "LOC_INTERNAL", "longitude": -107.446302, "time_offset_sec": 2438}, "public_key_hex": "", "role": "CLIENT", "short_name": "SJ3H", "snr": 2.03, "status": null, "telemetry": {"air_util_tx": 0.399, "battery_level": 28, "channel_utilization": 10.79, "uptime_seconds": 120116, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 445, "long_name": "Misty Shark", "next_hop": 158, "num": "0x4d7dce61", "position": null, "public_key_hex": "63b65466fcaa7cbf18700e7f8ad84289fce0c5fd56946276c2ea83ac02181fe5", "role": "CLIENT", "short_name": "MJTP", "snr": 3.32, "status": null, "telemetry": {"air_util_tx": 0.552, "battery_level": 96, "channel_utilization": 3.19, "uptime_seconds": 175167, "voltage": 4.164}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1017.59, "iaq": 96, "relative_humidity": 49.5, "temperature": 17.54}, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2601, "long_name": "Lost Coyote", "next_hop": 181, "num": "0x4d8f946b", "position": {"altitude": 1546, "latitude": 32.611293, "location_source": "LOC_INTERNAL", "longitude": -107.455073, "time_offset_sec": 2653}, "public_key_hex": "b9c191e8ea6bb9ecb384049a7b09f63a790d954b2cafdd62574c11b184f01a25", "role": "CLIENT", "short_name": "L8A8", "snr": 6.98, "status": null, "telemetry": {"air_util_tx": 1.42, "battery_level": 87, "channel_utilization": 9.8, "uptime_seconds": 31218, "voltage": 4.083}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 3, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 3719, "long_name": "Tiny Ridge", "next_hop": 101, "num": "0x4ddc2937", "position": {"altitude": 1220, "latitude": 33.794181, "location_source": "LOC_INTERNAL", "longitude": -107.157124, "time_offset_sec": 3787}, "public_key_hex": "afc8355d4a457c73c1d8cdb22be6ad3e572dc59b71d37c9315c1218c1a43e86a", "role": "CLIENT_MUTE", "short_name": "TTGP", "snr": 4.87, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 5483, "long_name": "Desert Coyote", "next_hop": 0, "num": "0x4e049a8c", "position": {"altitude": 1375, "latitude": 33.384528, "location_source": "LOC_INTERNAL", "longitude": -106.995136, "time_offset_sec": 5607}, "public_key_hex": "35dbef035ae32ba475e26ee69d99bf1ac15e4e53888d43e836eb1cc0e4ed0d6e", "role": "ROUTER", "short_name": "D1LD", "snr": 10.32, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2179, "long_name": "Storm Cedar", "next_hop": 0, "num": "0x4e2d03c2", "position": {"altitude": 1149, "latitude": 32.9513, "location_source": "LOC_INTERNAL", "longitude": -105.825534, "time_offset_sec": 2430}, "public_key_hex": "c6130f6febbc11c8cf77f3ba078643cb45f047ab748286f7b5a539c05ab8a573", "role": "SENSOR", "short_name": "SQEE", "snr": -4.28, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1019.48, "iaq": 57, "relative_humidity": 35.31, "temperature": 26.64}, "hops_away": 0, "hw_model": "MINI_EPAPER_S3", "last_heard_offset_sec": 1885, "long_name": "Sharp Cougar", "next_hop": 0, "num": "0x4f11eba6", "position": {"altitude": 1055, "latitude": 34.90857, "location_source": "LOC_INTERNAL", "longitude": -107.03887, "time_offset_sec": 2026}, "public_key_hex": "642a6cfd1d98bde0fbd3cf4ba1dc04905aa2afee856cd74d63fa80aaa8dee2db", "role": "CLIENT_MUTE", "short_name": "S9A0", "snr": 7.29, "status": null, "telemetry": {"air_util_tx": 0.912, "battery_level": 101, "channel_utilization": 30.44, "uptime_seconds": 129550, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 263, "long_name": "Black Pony", "next_hop": 0, "num": "0x4f31fb85", "position": {"altitude": 1136, "latitude": 31.978064, "location_source": "LOC_INTERNAL", "longitude": -107.569375, "time_offset_sec": 431}, "public_key_hex": "d92a31657f1e0db1f6a5d74d754a2b580d6600b61b5b6ca7b3d69a0bd0cb3949", "role": "ROUTER", "short_name": "BY4G", "snr": 2.29, "status": null, "telemetry": {"air_util_tx": 0.592, "battery_level": 100, "channel_utilization": 6.02, "uptime_seconds": 118228, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 3440, "long_name": "Sunny Wolf", "next_hop": 0, "num": "0x4f3ebf31", "position": {"altitude": 1551, "latitude": 34.316344, "location_source": "LOC_INTERNAL", "longitude": -107.365624, "time_offset_sec": 3568}, "public_key_hex": "ba99e2e6c1767c7f5c5cea3c46b275d14fbaa71c263ae33cfc398b326b557d36", "role": "CLIENT", "short_name": "SWFP", "snr": 8.75, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 543, "long_name": "Misty Bronco", "next_hop": 0, "num": "0x4f4ef47e", "position": {"altitude": 1373, "latitude": 32.574421, "location_source": "LOC_INTERNAL", "longitude": -107.359873, "time_offset_sec": 645}, "public_key_hex": "9d04d02a9ba7d657dbedeab50802d6490f4769c81d66b0d15fe7969a5bdd267d", "role": "CLIENT", "short_name": "MCXF", "snr": 9.47, "status": null, "telemetry": {"air_util_tx": 0.412, "battery_level": 31, "channel_utilization": 12.38, "uptime_seconds": 20434, "voltage": 3.579}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 998.74, "iaq": 63, "relative_humidity": 13.22, "temperature": 20.18}, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 9351, "long_name": "Smooth Crow", "next_hop": 0, "num": "0x4f9acebc", "position": {"altitude": 1108, "latitude": 33.287967, "location_source": "LOC_INTERNAL", "longitude": -107.163393, "time_offset_sec": 9381}, "public_key_hex": "3b816d65102ecf171e0f0f555ce6d8ca4e1ce7ba32367bb9990380c957139d8f", "role": "CLIENT_MUTE", "short_name": "S71S", "snr": 3.07, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.195, "battery_level": 20, "channel_utilization": 26.92, "uptime_seconds": 13428, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 609, "long_name": "Tall Tortoise", "next_hop": 100, "num": "0x4fc83db2", "position": {"altitude": 1896, "latitude": 33.09145, "location_source": "LOC_INTERNAL", "longitude": -106.624006, "time_offset_sec": 618}, "public_key_hex": "f1e091acacb9615e6e8cd0715fc858ad89a9db10fd73fd685419d23c57c6346e", "role": "SENSOR", "short_name": "T2JM", "snr": 8.7, "status": null, "telemetry": {"air_util_tx": 0.314, "battery_level": 55, "channel_utilization": 14.87, "uptime_seconds": 92459, "voltage": 3.795}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1016.25, "iaq": 31, "relative_humidity": 77.58, "temperature": 22.82}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1425, "long_name": "Mountain Cedar", "next_hop": 0, "num": "0x4ff32b5e", "position": {"altitude": 1836, "latitude": 33.221978, "location_source": "LOC_INTERNAL", "longitude": -107.595271, "time_offset_sec": 1646}, "public_key_hex": "0befe882264538237ac3631c6941146633a8ce0c571e3c0622d7e9e304aa7929", "role": "CLIENT", "short_name": "MFHA", "snr": 10.17, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.355, "battery_level": 81, "channel_utilization": 12.59, "uptime_seconds": 77130, "voltage": 4.029}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M5", "last_heard_offset_sec": 3454, "long_name": "Happy Shark", "next_hop": 0, "num": "0x5023db81", "position": null, "public_key_hex": "31c73ee9d269a171330ac84440f6645be805a47ddcdb2203b8de2434358f8bea", "role": "CLIENT", "short_name": "HM7R", "snr": 6.0, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.27, "battery_level": 90, "channel_utilization": 8.95, "uptime_seconds": 171267, "voltage": 4.11}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 7469, "long_name": "Silent Hawk", "next_hop": 0, "num": "0x508c60c8", "position": {"altitude": 1288, "latitude": 33.001922, "location_source": "LOC_INTERNAL", "longitude": -106.259455, "time_offset_sec": 7716}, "public_key_hex": "ea2bd595e1b796e42fbc44297d60e0531956cd4f3317b6076ce57122fe6f3c86", "role": "CLIENT", "short_name": "SJ20", "snr": 7.66, "status": null, "telemetry": {"air_util_tx": 0.505, "battery_level": 35, "channel_utilization": 7.29, "uptime_seconds": 86288, "voltage": 3.615}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1021.16, "iaq": 40, "relative_humidity": 88.93, "temperature": 37.22}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 3740, "long_name": "Blue Mustang", "next_hop": 0, "num": "0x50b05df0", "position": {"altitude": 1427, "latitude": 33.410179, "location_source": "LOC_INTERNAL", "longitude": -108.284215, "time_offset_sec": 3925}, "public_key_hex": "31d87416d15fe6e101ebd01b7baf580e279a2ce822dd91ab6bee7b596a369e16", "role": "CLIENT", "short_name": "B6GZ", "snr": 2.12, "status": null, "telemetry": {"air_util_tx": 0.898, "battery_level": 86, "channel_utilization": 27.07, "uptime_seconds": 22298, "voltage": 4.074}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1022.43, "iaq": 101, "relative_humidity": 60.39, "temperature": 33.91}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 9252, "long_name": "Found Owl", "next_hop": 0, "num": "0x50dd87e3", "position": {"altitude": 1131, "latitude": 32.556593, "location_source": "LOC_INTERNAL", "longitude": -106.934135, "time_offset_sec": 9491}, "public_key_hex": "336592c4a40d750aa4670787e036588046d62213f3b2f4f95089098bf027a8c0", "role": "ROUTER", "short_name": "F1AY", "snr": 7.97, "status": null, "telemetry": {"air_util_tx": 0.814, "battery_level": 64, "channel_utilization": 9.45, "uptime_seconds": 119563, "voltage": 3.876}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "THINKNODE_M6", "last_heard_offset_sec": 3505, "long_name": "Drifting Pine", "next_hop": 99, "num": "0x51491b42", "position": {"altitude": 1242, "latitude": 33.247823, "location_source": "LOC_INTERNAL", "longitude": -107.706515, "time_offset_sec": 3676}, "public_key_hex": "51ae2f4e7f9b3ff151af4228978d1f2ac23e77da14966f3571c0558c1bfd8b32", "role": "CLIENT", "short_name": "DRWU", "snr": 4.55, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.528, "battery_level": 30, "channel_utilization": 4.94, "uptime_seconds": 40074, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 7461, "long_name": "Howling Tortoise", "next_hop": 0, "num": "0x519de129", "position": {"altitude": 1614, "latitude": 31.546025, "location_source": "LOC_INTERNAL", "longitude": -107.668609, "time_offset_sec": 7581}, "public_key_hex": "50ebe012c33ad935d8424042de6fd34b213b0a944a8f5a39976340707b12d6e9", "role": "CLIENT", "short_name": "H9JH", "snr": 5.57, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.689, "battery_level": 50, "channel_utilization": 21.52, "uptime_seconds": 57636, "voltage": 3.75}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1021.45, "iaq": 44, "relative_humidity": 31.78, "temperature": 24.49}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 1163, "long_name": "Sleepy Marmot", "next_hop": 0, "num": "0x5218f3e7", "position": {"altitude": 1546, "latitude": 33.195416, "location_source": "LOC_INTERNAL", "longitude": -107.135683, "time_offset_sec": 1343}, "public_key_hex": "02c70a7f0ab1ac7229915f55dca20206d905785472e3f0ca8141c099c5f4eabc", "role": "CLIENT", "short_name": "SFPW", "snr": 6.81, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 5932, "long_name": "Green Fox", "next_hop": 0, "num": "0x52bbeaa5", "position": {"altitude": 1757, "latitude": 33.602032, "location_source": "LOC_INTERNAL", "longitude": -107.223963, "time_offset_sec": 6146}, "public_key_hex": "f5d1637c5e0550a7e697bafade0d7ba7212668e331751150942c30406402f419", "role": "CLIENT", "short_name": "GGPI", "snr": 7.64, "status": null, "telemetry": {"air_util_tx": 0.445, "battery_level": 38, "channel_utilization": 3.86, "uptime_seconds": 86972, "voltage": 3.642}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 2971, "long_name": "Copper Arroyo", "next_hop": 251, "num": "0x52f652ad", "position": {"altitude": 1286, "latitude": 32.62743, "location_source": "LOC_INTERNAL", "longitude": -108.063504, "time_offset_sec": 2982}, "public_key_hex": "9f32ddcda90bdf3992ae1d16f9c8c0c78a24b2d55d9555e8e724102164235d36", "role": "CLIENT", "short_name": "CTSY", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.141, "battery_level": 15, "channel_utilization": 25.22, "uptime_seconds": 56615, "voltage": 3.435}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 51, "long_name": "Rough Adder", "next_hop": 0, "num": "0x53436ec5", "position": {"altitude": 1632, "latitude": 33.309706, "location_source": "LOC_INTERNAL", "longitude": -107.307216, "time_offset_sec": 170}, "public_key_hex": "534da73a459a3dfb53510163cff89e5bf20db3ab6c68859462650a786d0497a9", "role": "CLIENT", "short_name": "ROEV", "snr": -0.98, "status": null, "telemetry": {"air_util_tx": 0.826, "battery_level": 68, "channel_utilization": 9.48, "uptime_seconds": 204231, "voltage": 3.912}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 435, "long_name": "White Fox", "next_hop": 160, "num": "0x538bf9f2", "position": null, "public_key_hex": "2a08f094239016f205dc2e4016631515b4f53c37c8fb4c9b3a00c01c1e406fd5", "role": "CLIENT", "short_name": "WXY6", "snr": 0.77, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.373, "battery_level": 95, "channel_utilization": 2.63, "uptime_seconds": 252920, "voltage": 4.155}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1019.75, "iaq": 15, "relative_humidity": 30.92, "temperature": 23.8}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 1261, "long_name": "Silent Badger", "next_hop": 0, "num": "0x543b382e", "position": {"altitude": 1286, "latitude": 32.104133, "location_source": "LOC_INTERNAL", "longitude": -107.468768, "time_offset_sec": 1454}, "public_key_hex": "88f5c63f5d5b2454974415eae24d6cb018dbca877aebea64f6bdec0af4a81df8", "role": "CLIENT_MUTE", "short_name": "SA9A", "snr": 4.66, "status": null, "telemetry": {"air_util_tx": 1.007, "battery_level": 37, "channel_utilization": 5.87, "uptime_seconds": 137381, "voltage": 3.633}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 2245, "long_name": "Dusk Viper", "next_hop": 0, "num": "0x547cee65", "position": null, "public_key_hex": "dd298a5996289aa6a82c9182024d6441e0238cab10420dea868ffc4ab5a1e8a4", "role": "ROUTER", "short_name": "🌊", "snr": 11.2, "status": {"status": "offline-soon"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 999.33, "iaq": 55, "relative_humidity": 89.01, "temperature": 15.19}, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4943, "long_name": "Green Colt", "next_hop": 198, "num": "0x54c245c7", "position": {"altitude": 1305, "latitude": 33.409967, "location_source": "LOC_INTERNAL", "longitude": -107.484346, "time_offset_sec": 5110}, "public_key_hex": "6171d755c496ec8dfa3186bfb9c5928c40cbc5712b5a955cdbd961a45e43d4a9", "role": "CLIENT", "short_name": "GGIS", "snr": 0.62, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 4821, "long_name": "Silent Hawk", "next_hop": 0, "num": "0x552e163e", "position": null, "public_key_hex": "6ea41c3cbf15684f04cca490e24fde2dd9a375478de136630bd2a6c08062fa3c", "role": "CLIENT", "short_name": "SM6L", "snr": 6.71, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.208, "battery_level": 28, "channel_utilization": 7.63, "uptime_seconds": 33588, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1013.66, "iaq": 32, "relative_humidity": 45.54, "temperature": 29.04}, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 5132, "long_name": "Giant Ridge", "next_hop": 0, "num": "0x5542038a", "position": {"altitude": 1711, "latitude": 32.932384, "location_source": "LOC_INTERNAL", "longitude": -107.960917, "time_offset_sec": 5188}, "public_key_hex": "253fdd50e950a675c5f8392966b54b49c6f2990f9f06b7788199c1b2b46a3eb4", "role": "CLIENT", "short_name": "GYDB", "snr": 8.34, "status": null, "telemetry": {"air_util_tx": 0.425, "battery_level": 97, "channel_utilization": 12.63, "uptime_seconds": 160275, "voltage": 4.173}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1025.23, "iaq": 51, "relative_humidity": 100.0, "temperature": 21.58}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 2309, "long_name": "Frosty Wolf", "next_hop": 0, "num": "0x55734537", "position": {"altitude": 937, "latitude": 33.393204, "location_source": "LOC_INTERNAL", "longitude": -107.850923, "time_offset_sec": 2530}, "public_key_hex": "7e4652e64745f9818402f3468dde97348c5ce54112110556f75dee40bb04e1f8", "role": "TAK_TRACKER", "short_name": "FIQP", "snr": 4.64, "status": null, "telemetry": {"air_util_tx": 1.204, "battery_level": 53, "channel_utilization": 8.74, "uptime_seconds": 140213, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2239, "long_name": "Short Yucca", "next_hop": 0, "num": "0x55799f51", "position": {"altitude": 1188, "latitude": 33.614414, "location_source": "LOC_INTERNAL", "longitude": -107.219677, "time_offset_sec": 2515}, "public_key_hex": "899cfaecd22f954af1d43f588273dee5002e72549b71e8881c18129b8d6c0c00", "role": "CLIENT", "short_name": "SGJO", "snr": 6.31, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.113, "battery_level": 57, "channel_utilization": 2.77, "uptime_seconds": 51030, "voltage": 3.813}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 227, "long_name": "Canyon Adder", "next_hop": 43, "num": "0x55fc07e7", "position": {"altitude": 1751, "latitude": 33.220694, "location_source": "LOC_INTERNAL", "longitude": -107.741995, "time_offset_sec": 500}, "public_key_hex": "7a74561a78f535fc95f5890d163818433e9fca44121884787afec20f5aea5ab7", "role": "CLIENT", "short_name": "C5NQ", "snr": 2.48, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.674, "battery_level": 20, "channel_utilization": 8.32, "uptime_seconds": 320816, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 6828, "long_name": "Short Mesa", "next_hop": 0, "num": "0x5607821b", "position": {"altitude": 1447, "latitude": 32.264792, "location_source": "LOC_INTERNAL", "longitude": -107.556886, "time_offset_sec": 6995}, "public_key_hex": "a147c79d0822db6eaf78c8ab0555df6d23b5b4a43dc7921fd5a6bc575c87a39e", "role": "CLIENT", "short_name": "S5IO", "snr": 9.31, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.259, "battery_level": 100, "channel_utilization": 6.39, "uptime_seconds": 59620, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1539, "long_name": "Silent Hare", "next_hop": 0, "num": "0x560ca843", "position": {"altitude": 1427, "latitude": 32.975042, "location_source": "LOC_INTERNAL", "longitude": -106.346847, "time_offset_sec": 1663}, "public_key_hex": "", "role": "CLIENT", "short_name": "🦉", "snr": 5.35, "status": null, "telemetry": {"air_util_tx": 0.756, "battery_level": 98, "channel_utilization": 6.16, "uptime_seconds": 249833, "voltage": 4.182}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 4080, "long_name": "Stone Raven", "next_hop": 0, "num": "0x56801f9c", "position": {"altitude": 1224, "latitude": 33.196324, "location_source": "LOC_INTERNAL", "longitude": -107.29657, "time_offset_sec": 4236}, "public_key_hex": "b542b16c88d335f3c205f46dbaaa5a989fc3eb898e77f4c75e5d5f330ba9b7e6", "role": "ROUTER_LATE", "short_name": "SKCP", "snr": 6.2, "status": null, "telemetry": {"air_util_tx": 0.715, "battery_level": 58, "channel_utilization": 3.8, "uptime_seconds": 356181, "voltage": 3.822}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 4671, "long_name": "White Turtle", "next_hop": 178, "num": "0x56cf95b6", "position": {"altitude": 1680, "latitude": 32.541764, "location_source": "LOC_INTERNAL", "longitude": -106.914057, "time_offset_sec": 4815}, "public_key_hex": "55d8e0e2e4054e8fa5887db5caa1688ee1b6aec13d6119ddf7041c377d2246e4", "role": "CLIENT", "short_name": "W1A4", "snr": 0.79, "status": null, "telemetry": {"air_util_tx": 0.28, "battery_level": 51, "channel_utilization": 14.89, "uptime_seconds": 188313, "voltage": 3.759}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "T_DECK", "last_heard_offset_sec": 2526, "long_name": "Howling Lion", "next_hop": 61, "num": "0x57300ef4", "position": {"altitude": 1344, "latitude": 32.916285, "location_source": "LOC_INTERNAL", "longitude": -107.634001, "time_offset_sec": 2775}, "public_key_hex": "50e4eb0ba899c8f757558ce2bbfd5e09dc232399450fe3ca3348399d708020a9", "role": "CLIENT", "short_name": "HLE2", "snr": 8.41, "status": null, "telemetry": {"air_util_tx": 0.033, "battery_level": 42, "channel_utilization": 16.39, "uptime_seconds": 122991, "voltage": 3.678}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 3214, "long_name": "Sleepy Cougar", "next_hop": 0, "num": "0x57352c4b", "position": {"altitude": 1371, "latitude": 32.55933, "location_source": "LOC_INTERNAL", "longitude": -106.986804, "time_offset_sec": 3408}, "public_key_hex": "29b6a9c3fec1a346e1de89825cac16cf8b6d4d33f98f52683a2ebd010888147c", "role": "CLIENT", "short_name": "SL29", "snr": 12.0, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.216, "battery_level": 94, "channel_utilization": 9.51, "uptime_seconds": 48903, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 7817, "long_name": "Black Bear", "next_hop": 0, "num": "0x575d1b79", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "B1JA", "snr": 5.49, "status": null, "telemetry": {"air_util_tx": 1.738, "battery_level": 27, "channel_utilization": 5.98, "uptime_seconds": 24654, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 5513, "long_name": "Steel Tortoise", "next_hop": 0, "num": "0x57b6c2de", "position": {"altitude": 1210, "latitude": 32.811198, "location_source": "LOC_INTERNAL", "longitude": -106.890358, "time_offset_sec": 5527}, "public_key_hex": "3d54a4ebaa20e77dbec8f7a781cb0af6eca5563258e5e5055faab72aeb6af2af", "role": "CLIENT", "short_name": "SGEA", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.971, "battery_level": 47, "channel_utilization": 15.67, "uptime_seconds": 26310, "voltage": 3.723}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 7086, "long_name": "Iron Bronco", "next_hop": 210, "num": "0x5832817c", "position": {"altitude": 1569, "latitude": 32.821781, "location_source": "LOC_INTERNAL", "longitude": -107.140782, "time_offset_sec": 7225}, "public_key_hex": "6c423146b02c426a5dbb7de0c0fc3477a71514105884410b96f512704755c326", "role": "CLIENT", "short_name": "IFIP", "snr": 3.97, "status": null, "telemetry": {"air_util_tx": 1.422, "battery_level": 16, "channel_utilization": 10.66, "uptime_seconds": 63821, "voltage": 3.444}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 1692, "long_name": "Giant Cobra", "next_hop": 0, "num": "0x583c5a5b", "position": {"altitude": 1032, "latitude": 32.813046, "location_source": "LOC_INTERNAL", "longitude": -107.794138, "time_offset_sec": 1832}, "public_key_hex": "962a97a7b5b4aac4806156eb170f177fd5d9ca9e2b4e8d248b5d63fce6d1cac3", "role": "CLIENT", "short_name": "GMJ4", "snr": 3.52, "status": null, "telemetry": {"air_util_tx": 1.012, "battery_level": 45, "channel_utilization": 7.19, "uptime_seconds": 35130, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 126, "long_name": "Fast Lynx KQ3LW", "next_hop": 6, "num": "0x5849da73", "position": null, "public_key_hex": "1a6b6734b2bf587c354c48c13c1e62fa72dc166cae43dc8c870a5b6716245d94", "role": "CLIENT_MUTE", "short_name": "FI93", "snr": 3.16, "status": null, "telemetry": {"air_util_tx": 0.643, "battery_level": 32, "channel_utilization": 23.9, "uptime_seconds": 43328, "voltage": 3.588}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 2425, "long_name": "Storm Trout", "next_hop": 0, "num": "0x586b6883", "position": {"altitude": 1236, "latitude": 32.815968, "location_source": "LOC_INTERNAL", "longitude": -107.542767, "time_offset_sec": 2443}, "public_key_hex": "7dd18327c0124af056634160508731d3378308b0569a4aff289026f9d66f5d3a", "role": "CLIENT", "short_name": "SO1Y", "snr": 0.63, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1021.67, "iaq": 36, "relative_humidity": 41.59, "temperature": 16.27}, "hops_away": 1, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 1775, "long_name": "Quick Cedar W58AU", "next_hop": 6, "num": "0x588f87cf", "position": {"altitude": 1230, "latitude": 33.116822, "location_source": "LOC_INTERNAL", "longitude": -107.137944, "time_offset_sec": 1982}, "public_key_hex": "", "role": "CLIENT", "short_name": "QZB0", "snr": 8.87, "status": null, "telemetry": {"air_util_tx": 1.663, "battery_level": 53, "channel_utilization": 4.08, "uptime_seconds": 9436, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 6678, "long_name": "Fast Hare", "next_hop": 0, "num": "0x58d23c2d", "position": {"altitude": 1440, "latitude": 32.920805, "location_source": "LOC_INTERNAL", "longitude": -107.680564, "time_offset_sec": 6831}, "public_key_hex": "3ff2802508ac7af3b8942c20093932e9eb77600233079968709f921deae7eff1", "role": "CLIENT", "short_name": "FHT9", "snr": 1.98, "status": null, "telemetry": {"air_util_tx": 0.243, "battery_level": 97, "channel_utilization": 6.41, "uptime_seconds": 22521, "voltage": 4.173}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 3336, "long_name": "Shady Oak", "next_hop": 171, "num": "0x58d3d466", "position": {"altitude": 1483, "latitude": 34.052506, "location_source": "LOC_INTERNAL", "longitude": -106.57317, "time_offset_sec": 3348}, "public_key_hex": "3258a0e7fe246f0fe1761c5048fa6021095d0542f89b268515c4870f243a99df", "role": "CLIENT", "short_name": "SZA8", "snr": 6.74, "status": null, "telemetry": {"air_util_tx": 0.674, "battery_level": 57, "channel_utilization": 13.16, "uptime_seconds": 69659, "voltage": 3.813}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4108, "long_name": "Wild Coyote", "next_hop": 0, "num": "0x590a2b97", "position": null, "public_key_hex": "93580e89ee97f6ac8b0a84305b15d8466cfe969d7843c699bf09320798f99c79", "role": "CLIENT", "short_name": "WBM7", "snr": 4.44, "status": null, "telemetry": {"air_util_tx": 0.406, "battery_level": 19, "channel_utilization": 21.25, "uptime_seconds": 76854, "voltage": 3.471}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 5000, "long_name": "Loud Lion", "next_hop": 0, "num": "0x59493fdf", "position": {"altitude": 1707, "latitude": 34.040154, "location_source": "LOC_INTERNAL", "longitude": -108.243014, "time_offset_sec": 5114}, "public_key_hex": "f2d8ed013f3fa29c7e9c4e9629c17cd1b63a73f25b10e816502eb1dbcc563033", "role": "CLIENT", "short_name": "L15F", "snr": 1.09, "status": null, "telemetry": {"air_util_tx": 1.901, "battery_level": 79, "channel_utilization": 3.25, "uptime_seconds": 214227, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 2673, "long_name": "Roving Lion", "next_hop": 0, "num": "0x5b10e9b7", "position": {"altitude": 1321, "latitude": 32.38925, "location_source": "LOC_INTERNAL", "longitude": -107.069099, "time_offset_sec": 2942}, "public_key_hex": "820b486c6495e1ad09e7dab117a1b7552c829fe3d8caf278e8a5facfaf187699", "role": "CLIENT", "short_name": "🐺", "snr": 12.0, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.929, "battery_level": 11, "channel_utilization": 15.13, "uptime_seconds": 80013, "voltage": 3.399}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1026.63, "iaq": 31, "relative_humidity": 79.54, "temperature": 15.58}, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 290, "long_name": "Tall Yucca", "next_hop": 96, "num": "0x5b55f45c", "position": {"altitude": 1730, "latitude": 33.727681, "location_source": "LOC_INTERNAL", "longitude": -106.987046, "time_offset_sec": 291}, "public_key_hex": "18f90c990661567a0a1c270b184201979599918f0cdc8bed391f5020d26537d1", "role": "CLIENT", "short_name": "TG7E", "snr": 7.53, "status": null, "telemetry": {"air_util_tx": 1.309, "battery_level": 66, "channel_utilization": 4.61, "uptime_seconds": 46397, "voltage": 3.894}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 784, "long_name": "Roving Eagle", "next_hop": 0, "num": "0x5b6a8991", "position": {"altitude": 1247, "latitude": 32.625816, "location_source": "LOC_INTERNAL", "longitude": -107.227175, "time_offset_sec": 788}, "public_key_hex": "8e7bc4885275255e537cdfc9e064b2191291f5b6cb57c39c04058d2142ed1563", "role": "CLIENT", "short_name": "R8M5", "snr": 3.96, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.088, "battery_level": 80, "channel_utilization": 9.12, "uptime_seconds": 27191, "voltage": 4.02}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 1110, "long_name": "Sleepy Stag", "next_hop": 195, "num": "0x5b739989", "position": {"altitude": 1427, "latitude": 33.273372, "location_source": "LOC_INTERNAL", "longitude": -107.3321, "time_offset_sec": 1348}, "public_key_hex": "1ce344c6d332c8b1114014e33ae347fca6cd6cfd7e4fd16b8e4443d8efc5c833", "role": "CLIENT", "short_name": "SDQS", "snr": 0.77, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1009.97, "iaq": 48, "relative_humidity": 63.94, "temperature": 23.68}, "hops_away": 1, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 4754, "long_name": "Forest Viper", "next_hop": 55, "num": "0x5be84694", "position": {"altitude": 1526, "latitude": 32.959566, "location_source": "LOC_INTERNAL", "longitude": -106.82651, "time_offset_sec": 4837}, "public_key_hex": "a9ff29378ab3ec7a94f0db45d3946a7a53f1d6b00589dfbfb468b1e1a645f9c4", "role": "CLIENT", "short_name": "FW2V", "snr": 4.24, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 8689, "long_name": "Desert Bronco KE7JW", "next_hop": 0, "num": "0x5bfa9b5d", "position": null, "public_key_hex": "53c3ffd3c55d07a4d8f7f166c59d89c8c478b360e979ff35165f8393fcfa3dad", "role": "CLIENT", "short_name": "DUXZ", "snr": 6.21, "status": null, "telemetry": {"air_util_tx": 0.351, "battery_level": 20, "channel_utilization": 0.33, "uptime_seconds": 24488, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 4542, "long_name": "Misty Badger", "next_hop": 0, "num": "0x5c3e3c24", "position": {"altitude": 1513, "latitude": 32.539944, "location_source": "LOC_INTERNAL", "longitude": -107.688447, "time_offset_sec": 4628}, "public_key_hex": "d852643bcc812b122022a8f74545d621041f1a97fa673eee510cd1e6df8ecf34", "role": "CLIENT", "short_name": "MK6S", "snr": 4.44, "status": null, "telemetry": {"air_util_tx": 1.826, "battery_level": 58, "channel_utilization": 8.23, "uptime_seconds": 41859, "voltage": 3.822}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 990.78, "iaq": 13, "relative_humidity": 31.97, "temperature": 33.84}, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 687, "long_name": "Storm Marmot", "next_hop": 203, "num": "0x5c6c119b", "position": {"altitude": 1533, "latitude": 33.031282, "location_source": "LOC_INTERNAL", "longitude": -107.060367, "time_offset_sec": 967}, "public_key_hex": "75a45d69da1eeb52542819b3c001d565ed11b2c2ad052cc2de47646093b9432f", "role": "CLIENT_MUTE", "short_name": "S56P", "snr": 1.13, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.034, "battery_level": 10, "channel_utilization": 13.92, "uptime_seconds": 187090, "voltage": 3.39}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": {"barometric_pressure": 1020.15, "iaq": 49, "relative_humidity": 1.43, "temperature": 23.6}, "hops_away": 2, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 115, "long_name": "Black Iguana", "next_hop": 140, "num": "0x5c9456dd", "position": {"altitude": 1617, "latitude": 32.482529, "location_source": "LOC_INTERNAL", "longitude": -107.675732, "time_offset_sec": 332}, "public_key_hex": "1e691bcc62abda1c9683428874c1091c84b63e69634536bf3d8489d13cf6eedc", "role": "CLIENT", "short_name": "BBYR", "snr": -3.93, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1015.86, "iaq": 53, "relative_humidity": 55.86, "temperature": 20.66}, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 7992, "long_name": "Forest Sage AB0MP", "next_hop": 0, "num": "0x5ca89e4b", "position": {"altitude": 1114, "latitude": 34.16658, "location_source": "LOC_INTERNAL", "longitude": -107.3823, "time_offset_sec": 8103}, "public_key_hex": "139f86aa39c096a4a822b810729ab498ac7bed52377414053b5531c9ba304c2a", "role": "CLIENT", "short_name": "F40B", "snr": 2.22, "status": null, "telemetry": {"air_util_tx": 0.59, "battery_level": 85, "channel_utilization": 10.92, "uptime_seconds": 20989, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 3557, "long_name": "Steel Salmon", "next_hop": 0, "num": "0x5cac2114", "position": null, "public_key_hex": "abbf4e7d6641963ea122c46fec3d2a40a5fb0c206d45d4b7ad78f93ce1cd43d9", "role": "CLIENT", "short_name": "SNWR", "snr": 3.81, "status": {"status": "weak-signal"}, "telemetry": {"air_util_tx": 0.608, "battery_level": 62, "channel_utilization": 20.97, "uptime_seconds": 134297, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1010.84, "iaq": 27, "relative_humidity": 38.56, "temperature": 25.6}, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 2748, "long_name": "Floating Cactus", "next_hop": 135, "num": "0x5cb62187", "position": null, "public_key_hex": "a084a8b6835d6b60e7d808d2f2f65d8b9bd0c2d04fc671113fcc7892f237043f", "role": "ROUTER", "short_name": "🔥", "snr": 12.0, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.303, "battery_level": 39, "channel_utilization": 2.65, "uptime_seconds": 55285, "voltage": 3.651}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1701, "long_name": "Sky Colt", "next_hop": 0, "num": "0x5cc29b65", "position": null, "public_key_hex": "2388ec408d9ea1bffa23ddd1e15904454b425c5dade36c7df2dac7d9b3743516", "role": "CLIENT", "short_name": "SRG7", "snr": 6.88, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1029.5, "iaq": 0, "relative_humidity": 14.37, "temperature": 20.27}, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 404, "long_name": "Gold Adder", "next_hop": 0, "num": "0x5cf883f9", "position": {"altitude": 708, "latitude": 32.310391, "location_source": "LOC_INTERNAL", "longitude": -107.199345, "time_offset_sec": 531}, "public_key_hex": "a3cba5d695fe9cadd1b43c91a6584666c33c100d68a8822591dd56f31c623587", "role": "CLIENT", "short_name": "G5FD", "snr": 2.09, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 8072, "long_name": "White Bass", "next_hop": 204, "num": "0x5d1ca7a6", "position": {"altitude": 896, "latitude": 32.738831, "location_source": "LOC_INTERNAL", "longitude": -108.47479, "time_offset_sec": 8103}, "public_key_hex": "56bfeeb88dbe57343040b5bb2f1a4f3cb8e2c10bff76a7ba4d48926e272276a3", "role": "CLIENT", "short_name": "WACF", "snr": 1.84, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4767, "long_name": "Stone Phoenix", "next_hop": 0, "num": "0x5d39a6a5", "position": {"altitude": 1139, "latitude": 33.583354, "location_source": "LOC_INTERNAL", "longitude": -106.054177, "time_offset_sec": 4881}, "public_key_hex": "3c81ba017e67241f3fdc52b7be3210a44fb821859e56dacc070d1ea02fc21bc4", "role": "CLIENT", "short_name": "SE5T", "snr": 8.28, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.244, "battery_level": 76, "channel_utilization": 19.13, "uptime_seconds": 171242, "voltage": 3.984}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 2, "environment": {"barometric_pressure": 1024.29, "iaq": 79, "relative_humidity": 64.85, "temperature": 37.25}, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 60, "long_name": "Iron Shark", "next_hop": 0, "num": "0x5d3edcd2", "position": {"altitude": 1966, "latitude": 33.271395, "location_source": "LOC_INTERNAL", "longitude": -107.208199, "time_offset_sec": 203}, "public_key_hex": "2438dbee39cdbcb7e7cee34b4241d2b4e40094d3605b27641922c41e426eef5e", "role": "CLIENT", "short_name": "IHT6", "snr": -4.25, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 1668, "long_name": "Sharp Wolf", "next_hop": 0, "num": "0x5d5700e6", "position": {"altitude": 1779, "latitude": 33.019747, "location_source": "LOC_INTERNAL", "longitude": -106.850405, "time_offset_sec": 1696}, "public_key_hex": "614c80100854937c661183623c445e5b1edd065a92e042d738f3b6514114dade", "role": "CLIENT", "short_name": "S202", "snr": 8.1, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.566, "battery_level": 66, "channel_utilization": 1.53, "uptime_seconds": 113792, "voltage": 3.894}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "T_DECK", "last_heard_offset_sec": 305, "long_name": "Drifting Cobra", "next_hop": 103, "num": "0x5d6fa8cf", "position": null, "public_key_hex": "a3c7e53a06cabf0e12a289cd6b0707782abc901592e02e9398dce6d0178d2243", "role": "CLIENT", "short_name": "DIA1", "snr": -1.89, "status": null, "telemetry": {"air_util_tx": 0.204, "battery_level": 30, "channel_utilization": 21.66, "uptime_seconds": 17851, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 4, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1210, "long_name": "Sneaky Bison", "next_hop": 94, "num": "0x5e6b5cfa", "position": {"altitude": 1516, "latitude": 32.420087, "location_source": "LOC_INTERNAL", "longitude": -107.710817, "time_offset_sec": 1299}, "public_key_hex": "7c7cbb5c42d3ca7961b038d38015e7bb1263f66fdd8324fabbd03edbb9c7140d", "role": "CLIENT_HIDDEN", "short_name": "SCIN", "snr": 3.97, "status": null, "telemetry": {"air_util_tx": 1.823, "battery_level": 22, "channel_utilization": 1.18, "uptime_seconds": 35076, "voltage": 3.498}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1004.75, "iaq": 89, "relative_humidity": 47.18, "temperature": 22.24}, "hops_away": 0, "hw_model": "SEEED_WIO_TRACKER_L1", "last_heard_offset_sec": 8410, "long_name": "Sunny Colt", "next_hop": 0, "num": "0x5e924b24", "position": {"altitude": 1628, "latitude": 32.631907, "location_source": "LOC_INTERNAL", "longitude": -106.731651, "time_offset_sec": 8620}, "public_key_hex": "b3ad636860caf01eaab96dc15ea0bd89285807900ea8ba40e742fa93a6aaf49c", "role": "CLIENT", "short_name": "S35S", "snr": 3.93, "status": null, "telemetry": {"air_util_tx": 1.236, "battery_level": 46, "channel_utilization": 11.87, "uptime_seconds": 5201, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1016.66, "iaq": 29, "relative_humidity": 42.67, "temperature": 24.87}, "hops_away": 1, "hw_model": "RAK4631", "last_heard_offset_sec": 5740, "long_name": "Quick Seal", "next_hop": 178, "num": "0x5f0f76c2", "position": {"altitude": 1464, "latitude": 32.363427, "location_source": "LOC_INTERNAL", "longitude": -106.984259, "time_offset_sec": 5823}, "public_key_hex": "196f793d29b19686a7dff432ed32f1a5e8798b390d26501419c264242c8d34ae", "role": "CLIENT", "short_name": "Q8CY", "snr": -2.67, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 4986, "long_name": "Dusk Bison", "next_hop": 0, "num": "0x5f147185", "position": {"altitude": 1140, "latitude": 32.142654, "location_source": "LOC_INTERNAL", "longitude": -107.324034, "time_offset_sec": 5047}, "public_key_hex": "fe392798be3ed2ed2c220c44dcaa1ed24ae2a0149caea4930cc9dad75fefeb51", "role": "CLIENT_MUTE", "short_name": "🦅", "snr": 9.35, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": null, "hops_away": 1, "hw_model": "THINKNODE_M1", "last_heard_offset_sec": 741, "long_name": "Desert Phoenix", "next_hop": 119, "num": "0x5f2f9f9b", "position": {"altitude": 1055, "latitude": 33.208668, "location_source": "LOC_INTERNAL", "longitude": -106.618164, "time_offset_sec": 908}, "public_key_hex": "82da9cbc77e469d33e7d805403e01d2dfe35dd84debc5e1cecc3cf8f90bf841e", "role": "CLIENT", "short_name": "DXVI", "snr": -2.18, "status": null, "telemetry": {"air_util_tx": 0.025, "battery_level": 100, "channel_utilization": 2.22, "uptime_seconds": 476020, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1025.44, "iaq": 0, "relative_humidity": 59.94, "temperature": 22.55}, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 4320, "long_name": "Fast Coyote", "next_hop": 241, "num": "0x5f47ac30", "position": {"altitude": 1135, "latitude": 33.264005, "location_source": "LOC_INTERNAL", "longitude": -107.339905, "time_offset_sec": 4565}, "public_key_hex": "26f5501c4afeac4b12f5f99ac41b267d5cc5de96e888c3b05d5bc3c5198ed694", "role": "CLIENT", "short_name": "FT8E", "snr": 6.11, "status": {"status": "no-gps"}, "telemetry": {"air_util_tx": 1.158, "battery_level": 92, "channel_utilization": 1.46, "uptime_seconds": 90355, "voltage": 4.128}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 4821, "long_name": "Wandering Cougar", "next_hop": 6, "num": "0x5fc9d6fa", "position": {"altitude": 984, "latitude": 32.634939, "location_source": "LOC_INTERNAL", "longitude": -107.25922, "time_offset_sec": 4949}, "public_key_hex": "4494a75e3e4d3a7a44ca2944ef45e436d1ce973daeed6b46333a647a7acd28d8", "role": "CLIENT_MUTE", "short_name": "W99T", "snr": 4.11, "status": {"status": "rebooted"}, "telemetry": {"air_util_tx": 0.117, "battery_level": 71, "channel_utilization": 4.77, "uptime_seconds": 42360, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 309, "long_name": "Howling Falcon", "next_hop": 43, "num": "0x60a76bbe", "position": null, "public_key_hex": "0cea29776523ebb2443ec07bf5059a2aa62733d12a7f229decfdec3d11cd17a5", "role": "TRACKER", "short_name": "HRDU", "snr": 6.41, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.714, "battery_level": 95, "channel_utilization": 0.97, "uptime_seconds": 280797, "voltage": 4.155}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1020.15, "iaq": 65, "relative_humidity": 76.09, "temperature": 28.15}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2001, "long_name": "Silent Shark", "next_hop": 0, "num": "0x60acb50d", "position": null, "public_key_hex": "d7d3f2084a457d171e595de3ceaed0362aa8a82840b030aeaa33c37a569b34e6", "role": "CLIENT", "short_name": "SG2A", "snr": 10.32, "status": {"status": "OK"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 2071, "long_name": "Dawn Oak", "next_hop": 205, "num": "0x60d52493", "position": null, "public_key_hex": "", "role": "CLIENT", "short_name": "D57H", "snr": 2.67, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.845, "battery_level": 57, "channel_utilization": 20.85, "uptime_seconds": 23577, "voltage": 3.813}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 408, "long_name": "Found Bronco", "next_hop": 16, "num": "0x6126e11d", "position": {"altitude": 1713, "latitude": 32.328562, "location_source": "LOC_INTERNAL", "longitude": -107.831678, "time_offset_sec": 622}, "public_key_hex": "5f1ede392e100f37d57c2c855a75ce067b5fa69354e7452a7de5c8f1f9ffd16f", "role": "CLIENT", "short_name": "FUAB", "snr": 4.63, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 6386, "long_name": "Soft Dolphin", "next_hop": 89, "num": "0x6134fee3", "position": {"altitude": 1455, "latitude": 33.08712, "location_source": "LOC_INTERNAL", "longitude": -107.295562, "time_offset_sec": 6664}, "public_key_hex": "0fd08b5fd2e1567150219561d969bec29ef910c420efcd5279c7aea5045e5e49", "role": "TAK_TRACKER", "short_name": "S1JZ", "snr": 2.74, "status": {"status": "low-batt"}, "telemetry": {"air_util_tx": 0.143, "battery_level": 43, "channel_utilization": 6.63, "uptime_seconds": 24021, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 3325, "long_name": "River Bluff", "next_hop": 57, "num": "0x6143515c", "position": {"altitude": 1670, "latitude": 33.826539, "location_source": "LOC_INTERNAL", "longitude": -107.469218, "time_offset_sec": 3368}, "public_key_hex": "32c1968b4e8bd4c56e62032c9d4a5864196bc83a8687fd629425a8f087d0d1d3", "role": "CLIENT", "short_name": "RL69", "snr": 4.78, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.25, "battery_level": 90, "channel_utilization": 20.09, "uptime_seconds": 248749, "voltage": 4.11}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 1133, "long_name": "Blue Eagle", "next_hop": 0, "num": "0x614c0e01", "position": null, "public_key_hex": "2c031998d927fa7b524f85fc64952609201c92ab2b966956ffbf4b09be0a610f", "role": "CLIENT", "short_name": "B2AH", "snr": 7.76, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.083, "battery_level": 43, "channel_utilization": 4.71, "uptime_seconds": 3918, "voltage": 3.687}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 3, "environment": {"barometric_pressure": 995.19, "iaq": 48, "relative_humidity": 57.07, "temperature": 18.89}, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 1317, "long_name": "Sharp Arroyo", "next_hop": 90, "num": "0x618a05ed", "position": {"altitude": 1170, "latitude": 32.531093, "location_source": "LOC_INTERNAL", "longitude": -106.511411, "time_offset_sec": 1427}, "public_key_hex": "dccf199986299e0640f02a00b8c256b76490edaba14d24498565d137f68d05f9", "role": "CLIENT", "short_name": "ST9J", "snr": -0.14, "status": null, "telemetry": {"air_util_tx": 0.181, "battery_level": 71, "channel_utilization": 4.5, "uptime_seconds": 5744, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 4758, "long_name": "Brave Otter", "next_hop": 0, "num": "0x619f7ad2", "position": null, "public_key_hex": "03b2fd5dcfc651ab528b2d5a6f09af129027c756cf7ca681d21723adfc1c1958", "role": "CLIENT", "short_name": "BIC2", "snr": 8.86, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 1.417, "battery_level": 41, "channel_utilization": 7.37, "uptime_seconds": 6155, "voltage": 3.669}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1027.12, "iaq": 73, "relative_humidity": 51.07, "temperature": 25.8}, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 3530, "long_name": "Burning Tortoise", "next_hop": 119, "num": "0x61d754f1", "position": {"altitude": 1192, "latitude": 32.554766, "location_source": "LOC_INTERNAL", "longitude": -107.670555, "time_offset_sec": 3766}, "public_key_hex": "112ff04d11fd11f1683100afd66c85cc606fa7280884df18a08e1f03593db308", "role": "CLIENT", "short_name": "B87D", "snr": 5.43, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.132, "battery_level": 45, "channel_utilization": 7.09, "uptime_seconds": 23000, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "THINKNODE_M2", "last_heard_offset_sec": 6314, "long_name": "Roving Hawk", "next_hop": 79, "num": "0x61ecc35f", "position": null, "public_key_hex": "", "role": "ROUTER", "short_name": "🐺", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 1.251, "battery_level": 16, "channel_utilization": 21.55, "uptime_seconds": 11974, "voltage": 3.444}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 1614, "long_name": "Mountain Pony", "next_hop": 0, "num": "0x62a08a3d", "position": {"altitude": 1014, "latitude": 32.731474, "location_source": "LOC_INTERNAL", "longitude": -107.127675, "time_offset_sec": 1734}, "public_key_hex": "", "role": "CLIENT", "short_name": "MLWS", "snr": 4.12, "status": null, "telemetry": {"air_util_tx": 0.103, "battery_level": 31, "channel_utilization": 10.83, "uptime_seconds": 18147, "voltage": 3.579}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 1753, "long_name": "Black Mustang", "next_hop": 0, "num": "0x62aeb717", "position": null, "public_key_hex": "7a34ed04662ba4469e5698e6b22f196b5f1efaf282452f44b28ccd54a47e0c8c", "role": "TAK", "short_name": "B15H", "snr": 2.04, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 3452, "long_name": "Shady Pony", "next_hop": 0, "num": "0x62e16e9d", "position": {"altitude": 1345, "latitude": 33.943778, "location_source": "LOC_INTERNAL", "longitude": -107.49073, "time_offset_sec": 3628}, "public_key_hex": "4e5d5b74d7a2614f86b3ae23ef6f4e59d1cd9aefda74648d4eedcf000ffc7800", "role": "CLIENT", "short_name": "S38R", "snr": 2.68, "status": null, "telemetry": {"air_util_tx": 1.361, "battery_level": 81, "channel_utilization": 6.38, "uptime_seconds": 100368, "voltage": 4.029}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 7272, "long_name": "Lost Bison", "next_hop": 90, "num": "0x63122ae7", "position": {"altitude": 1500, "latitude": 32.953909, "location_source": "LOC_INTERNAL", "longitude": -107.21476, "time_offset_sec": 7292}, "public_key_hex": "a627fe57fe5478e2ff8c532fecad12d3037ee2adfca23980da9d6eb9ece0d5f9", "role": "TRACKER", "short_name": "LIRB", "snr": -0.65, "status": null, "telemetry": {"air_util_tx": 0.872, "battery_level": 49, "channel_utilization": 2.93, "uptime_seconds": 51703, "voltage": 3.741}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 3216, "long_name": "Drowsy Eagle", "next_hop": 49, "num": "0x6410b8ec", "position": {"altitude": 1310, "latitude": 33.010542, "location_source": "LOC_INTERNAL", "longitude": -106.403195, "time_offset_sec": 3354}, "public_key_hex": "bee10be3a33bb9e755411dd0e03149befe46868e7378bb35817edad58d5b462f", "role": "CLIENT", "short_name": "DI1D", "snr": 4.99, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 10233, "long_name": "Frozen Ridge K16WD", "next_hop": 249, "num": "0x643d413d", "position": {"altitude": 1318, "latitude": 32.853899, "location_source": "LOC_INTERNAL", "longitude": -108.16199, "time_offset_sec": 10354}, "public_key_hex": "08e5488221ef6ddb8dbb1586d41011ecc00fb8b74cc10c5639bc95e5c3151403", "role": "CLIENT", "short_name": "FVA6", "snr": 6.26, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.709, "battery_level": 59, "channel_utilization": 17.97, "uptime_seconds": 42772, "voltage": 3.831}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 6694, "long_name": "Dawn Seal", "next_hop": 27, "num": "0x6450c3fb", "position": {"altitude": 1376, "latitude": 32.920828, "location_source": "LOC_INTERNAL", "longitude": -107.07977, "time_offset_sec": 6772}, "public_key_hex": "7c6657dca30be8e3ece68a504aa2d304d472eb3e4e2fef885d848af1e7431f81", "role": "ROUTER", "short_name": "DS11", "snr": -0.65, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.58, "iaq": 69, "relative_humidity": 90.68, "temperature": 14.54}, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 2177, "long_name": "Drowsy Raven", "next_hop": 0, "num": "0x645bc141", "position": {"altitude": 1036, "latitude": 32.917715, "location_source": "LOC_INTERNAL", "longitude": -107.72338, "time_offset_sec": 2382}, "public_key_hex": "5e0ad59c291ae909ad1fc13618f9e5b3fde276352e6e1511bab5b86a615afa18", "role": "CLIENT", "short_name": "DCNF", "snr": 2.28, "status": null, "telemetry": {"air_util_tx": 0.216, "battery_level": 17, "channel_utilization": 5.1, "uptime_seconds": 72205, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1005.46, "iaq": 43, "relative_humidity": 100.0, "temperature": 5.43}, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 4079, "long_name": "Soft Pine", "next_hop": 0, "num": "0x655b61d3", "position": {"altitude": 962, "latitude": 33.818742, "location_source": "LOC_INTERNAL", "longitude": -107.759172, "time_offset_sec": 4092}, "public_key_hex": "d0cbe0fe25b919f38550f3f9561074c0f06aaff8a124b75435b9ac36166366dd", "role": "CLIENT_MUTE", "short_name": "S6K0", "snr": 3.41, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.811, "battery_level": 75, "channel_utilization": 11.02, "uptime_seconds": 104419, "voltage": 3.975}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1005.64, "iaq": 113, "relative_humidity": 27.29, "temperature": 14.93}, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 1527, "long_name": "Slow Mamba", "next_hop": 0, "num": "0x65684a77", "position": {"altitude": 1479, "latitude": 32.519337, "location_source": "LOC_INTERNAL", "longitude": -107.090347, "time_offset_sec": 1738}, "public_key_hex": "768177b124e3416bc53827cbe3eac32d2a122c7652347034363b64d03145f34e", "role": "CLIENT", "short_name": "SK3G", "snr": 2.76, "status": null, "telemetry": {"air_util_tx": 1.46, "battery_level": 100, "channel_utilization": 5.93, "uptime_seconds": 321087, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 87, "long_name": "Sunny Sage", "next_hop": 0, "num": "0x6597cc10", "position": {"altitude": 1022, "latitude": 32.086383, "location_source": "LOC_INTERNAL", "longitude": -107.871811, "time_offset_sec": 167}, "public_key_hex": "f8b0606a45371cf8eecf6ceca7086ab921f4aff7289ab5bafef1dfb1500b5d4b", "role": "ROUTER", "short_name": "🌲", "snr": 7.83, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.025, "battery_level": 20, "channel_utilization": 2.73, "uptime_seconds": 227551, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 5629, "long_name": "River Oak", "next_hop": 0, "num": "0x65a37178", "position": {"altitude": 1177, "latitude": 33.73494, "location_source": "LOC_INTERNAL", "longitude": -108.007027, "time_offset_sec": 5778}, "public_key_hex": "e57787d4990caeada3d54663b25f50e756b11bf275913378f1b5414fa34e00d1", "role": "CLIENT", "short_name": "RBKG", "snr": 8.68, "status": null, "telemetry": {"air_util_tx": 0.108, "battery_level": 45, "channel_utilization": 19.0, "uptime_seconds": 40769, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1018.81, "iaq": 101, "relative_humidity": 25.77, "temperature": 14.31}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1165, "long_name": "Wild Ridge", "next_hop": 0, "num": "0x65a7b407", "position": {"altitude": 1447, "latitude": 33.54226, "location_source": "LOC_INTERNAL", "longitude": -106.895898, "time_offset_sec": 1228}, "public_key_hex": "58b7fca526c5ed88a273674f7fac0ae3b9be0ce980c0775fb1bc0ce3ea5cca37", "role": "CLIENT", "short_name": "WXI2", "snr": 9.41, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.174, "battery_level": 58, "channel_utilization": 23.06, "uptime_seconds": 67457, "voltage": 3.822}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 5989, "long_name": "Lunar Cougar", "next_hop": 0, "num": "0x65af31dc", "position": {"altitude": 1074, "latitude": 32.16723, "location_source": "LOC_INTERNAL", "longitude": -107.285076, "time_offset_sec": 6182}, "public_key_hex": "cda47ed74da113fd8789dfd518c2d5b2f93df64c481784585fb10dcec1c0eeb2", "role": "TRACKER", "short_name": "LC1J", "snr": 4.62, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 2437, "long_name": "Rough Falcon", "next_hop": 0, "num": "0x65b43e72", "position": {"altitude": 1280, "latitude": 33.265534, "location_source": "LOC_INTERNAL", "longitude": -107.716745, "time_offset_sec": 2715}, "public_key_hex": "6d4ec445477406994a457799137b4911d74d6d2e6a79c3826a5cf6569ba64af8", "role": "CLIENT", "short_name": "RUFF", "snr": 3.32, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.123, "battery_level": 82, "channel_utilization": 6.32, "uptime_seconds": 6122, "voltage": 4.038}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "THINKNODE_M3", "last_heard_offset_sec": 337, "long_name": "Shady Ridge", "next_hop": 0, "num": "0x667d0bb4", "position": null, "public_key_hex": "f912306b415f7aa4da19556f1bfb6c9f7fb0c1e29580742078b4493e6c8350c7", "role": "CLIENT", "short_name": "S004", "snr": -0.57, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.624, "battery_level": 33, "channel_utilization": 15.8, "uptime_seconds": 5462, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "T_DECK", "last_heard_offset_sec": 966, "long_name": "River Mole", "next_hop": 78, "num": "0x66a9fcd8", "position": null, "public_key_hex": "92ae245a2ed70681ef79621614b8385429e6547a47a1acd7a7435296cba6606f", "role": "CLIENT", "short_name": "R7QG", "snr": 9.6, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.625, "battery_level": 61, "channel_utilization": 12.36, "uptime_seconds": 17187, "voltage": 3.849}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 603, "long_name": "Misty Pony", "next_hop": 0, "num": "0x66d201f9", "position": {"altitude": 1399, "latitude": 32.243637, "location_source": "LOC_INTERNAL", "longitude": -107.161281, "time_offset_sec": 608}, "public_key_hex": "b32f4a02bb6ba87dd709eaab8aa2def30eea43948da6a88d3e6757ad37fb1bf1", "role": "CLIENT", "short_name": "MHGL", "snr": 2.23, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.079, "battery_level": 46, "channel_utilization": 7.39, "uptime_seconds": 8797, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 1615, "long_name": "Loud Mamba", "next_hop": 0, "num": "0x670a401a", "position": {"altitude": 1125, "latitude": 33.386315, "location_source": "LOC_INTERNAL", "longitude": -107.348963, "time_offset_sec": 1654}, "public_key_hex": "3e988b2487f8f86c5b4fc2ff8603ef75d3d603f382bf747a85aa34e2cb56d887", "role": "CLIENT_HIDDEN", "short_name": "LC74", "snr": 10.26, "status": null, "telemetry": {"air_util_tx": 0.634, "battery_level": 11, "channel_utilization": 3.11, "uptime_seconds": 170109, "voltage": 3.399}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 6984, "long_name": "Gold Cobra", "next_hop": 0, "num": "0x67828a9d", "position": {"altitude": 1484, "latitude": 33.31937, "location_source": "LOC_INTERNAL", "longitude": -107.462128, "time_offset_sec": 7121}, "public_key_hex": "1d9d963537b6a842696639308d55414c42b2838310bdcbae7fb4f98dd2746a94", "role": "CLIENT", "short_name": "GPD1", "snr": 9.74, "status": null, "telemetry": {"air_util_tx": 0.886, "battery_level": 28, "channel_utilization": 8.35, "uptime_seconds": 41548, "voltage": 3.552}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 1311, "long_name": "Sneaky Beaver", "next_hop": 0, "num": "0x67a11808", "position": {"altitude": 1033, "latitude": 32.927237, "location_source": "LOC_INTERNAL", "longitude": -106.917122, "time_offset_sec": 1522}, "public_key_hex": "64497ae071d0dbfd1f006af9604dea39b494ae4699108704d05b53296e8c1f4a", "role": "CLIENT", "short_name": "SMW2", "snr": 7.89, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": {"barometric_pressure": 1015.83, "iaq": 0, "relative_humidity": 48.56, "temperature": 27.84}, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 882, "long_name": "White Bronco", "next_hop": 0, "num": "0x67a2fc22", "position": {"altitude": 1194, "latitude": 32.069484, "location_source": "LOC_INTERNAL", "longitude": -107.0902, "time_offset_sec": 955}, "public_key_hex": "d319e98a163b943a6b1b51e7aab152d35ac96d09299a8db902c58b1d4189a7af", "role": "CLIENT", "short_name": "WUCR", "snr": 0.46, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 3686, "long_name": "Found Falcon", "next_hop": 0, "num": "0x67e769d2", "position": {"altitude": 1633, "latitude": 33.0328, "location_source": "LOC_INTERNAL", "longitude": -107.240522, "time_offset_sec": 3771}, "public_key_hex": "", "role": "CLIENT", "short_name": "FYOX", "snr": 1.48, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 1.625, "battery_level": 99, "channel_utilization": 14.36, "uptime_seconds": 68022, "voltage": 4.191}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1005.59, "iaq": 65, "relative_humidity": 17.76, "temperature": 23.78}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1971, "long_name": "Old Mole", "next_hop": 0, "num": "0x67eda7d6", "position": {"altitude": 1498, "latitude": 32.629438, "location_source": "LOC_INTERNAL", "longitude": -107.269653, "time_offset_sec": 2004}, "public_key_hex": "de38ac98f05428ca2820bbf54be72fbf3e773c07cbf9f6521663752458828e84", "role": "CLIENT_HIDDEN", "short_name": "OU8V", "snr": 12.0, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.562, "battery_level": 101, "channel_utilization": 24.43, "uptime_seconds": 101944, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1003.69, "iaq": 50, "relative_humidity": 44.1, "temperature": 36.37}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 642, "long_name": "Solar Adder", "next_hop": 0, "num": "0x67f48cb5", "position": {"altitude": 1656, "latitude": 32.913674, "location_source": "LOC_INTERNAL", "longitude": -106.957759, "time_offset_sec": 831}, "public_key_hex": "4790c1b4bad3100ca34cee84c30174dbde73988aa7001d48062877f667403831", "role": "ROUTER", "short_name": "S545", "snr": 12.0, "status": {"status": "active"}, "telemetry": {"air_util_tx": 2.037, "battery_level": 96, "channel_utilization": 8.25, "uptime_seconds": 77101, "voltage": 4.164}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 9835, "long_name": "Roving Seal", "next_hop": 233, "num": "0x67f6ee87", "position": {"altitude": 1634, "latitude": 33.779854, "location_source": "LOC_INTERNAL", "longitude": -107.994639, "time_offset_sec": 10090}, "public_key_hex": "", "role": "CLIENT", "short_name": "RVBJ", "snr": 6.89, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1012.06, "iaq": 44, "relative_humidity": 21.17, "temperature": 26.13}, "hops_away": 2, "hw_model": "T_DECK", "last_heard_offset_sec": 873, "long_name": "Silent Sage", "next_hop": 207, "num": "0x68ca0085", "position": {"altitude": 1681, "latitude": 33.090398, "location_source": "LOC_INTERNAL", "longitude": -106.850398, "time_offset_sec": 902}, "public_key_hex": "03d21555e5d10eecc12e3c033d17a459bb3c9026c3dbcc184e964a83fc0dcd01", "role": "CLIENT", "short_name": "SN2Y", "snr": 7.28, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 1.444, "battery_level": 70, "channel_utilization": 5.6, "uptime_seconds": 61549, "voltage": 3.93}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 3693, "long_name": "Forest Badger", "next_hop": 0, "num": "0x68d21cdf", "position": {"altitude": 1447, "latitude": 33.60625, "location_source": "LOC_INTERNAL", "longitude": -106.763408, "time_offset_sec": 3789}, "public_key_hex": "7f22ca57b404fd315a02e7194c02927b8d4a320c3033cd12538b534f38d4a8d5", "role": "CLIENT", "short_name": "F15P", "snr": 1.36, "status": {"status": "offline-soon"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 332, "long_name": "Silver Phoenix", "next_hop": 0, "num": "0x68db9a79", "position": {"altitude": 1436, "latitude": 31.863364, "location_source": "LOC_INTERNAL", "longitude": -106.745974, "time_offset_sec": 537}, "public_key_hex": "7a137a5511c4e21236e69c3fb0d586fa63661d3fe65a8784edd645ffa4e15791", "role": "CLIENT", "short_name": "SRI5", "snr": 6.07, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4_R8", "last_heard_offset_sec": 9910, "long_name": "Dusk Stag", "next_hop": 0, "num": "0x69160996", "position": {"altitude": 1315, "latitude": 33.006478, "location_source": "LOC_INTERNAL", "longitude": -107.60747, "time_offset_sec": 10209}, "public_key_hex": "cd222db4c4df04c04f1c1b67e04e462fb177603fd08e04a1d8f824d614e45211", "role": "LOST_AND_FOUND", "short_name": "D6EE", "snr": 5.47, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.367, "battery_level": 101, "channel_utilization": 11.29, "uptime_seconds": 6571, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 11782, "long_name": "Bright Bison", "next_hop": 31, "num": "0x69443905", "position": {"altitude": 1701, "latitude": 33.557304, "location_source": "LOC_INTERNAL", "longitude": -107.395231, "time_offset_sec": 11794}, "public_key_hex": "1ca60e46542920bb906736a8c09af6753e9167b44b680de0f336b4412bc8fc55", "role": "CLIENT", "short_name": "BQCF", "snr": 4.62, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER", "last_heard_offset_sec": 1846, "long_name": "Tiny Juniper", "next_hop": 0, "num": "0x69512c9f", "position": null, "public_key_hex": "eb11d406cb1e6b5e57ef2f4efc4067ed893d42159e2f0e2e8f2601a6b2a5b833", "role": "CLIENT", "short_name": "TPGU", "snr": 0.42, "status": null, "telemetry": {"air_util_tx": 0.913, "battery_level": 54, "channel_utilization": 10.96, "uptime_seconds": 44889, "voltage": 3.786}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1018.11, "iaq": 100, "relative_humidity": 56.47, "temperature": 15.63}, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 3973, "long_name": "Lunar Dolphin", "next_hop": 0, "num": "0x695ea36c", "position": {"altitude": 1448, "latitude": 33.04932, "location_source": "LOC_INTERNAL", "longitude": -107.173961, "time_offset_sec": 4082}, "public_key_hex": "0c64449dad15645f70042cc3dfbb5945ec54ee542633d3aa52f202c28acae1d9", "role": "CLIENT", "short_name": "LHPX", "snr": 6.42, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.169, "battery_level": 42, "channel_utilization": 27.83, "uptime_seconds": 417701, "voltage": 3.678}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1009.43, "iaq": 60, "relative_humidity": 67.3, "temperature": 20.41}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 5682, "long_name": "Tall Crow", "next_hop": 0, "num": "0x69959909", "position": {"altitude": 1130, "latitude": 33.247049, "location_source": "LOC_INTERNAL", "longitude": -106.725418, "time_offset_sec": 5705}, "public_key_hex": "7f6b52ee6b5b005b1954b6e317df1945cce6286c5b2af22c27d5686014f7ee82", "role": "CLIENT", "short_name": "TKRG", "snr": 6.74, "status": null, "telemetry": {"air_util_tx": 0.838, "battery_level": 101, "channel_utilization": 10.31, "uptime_seconds": 250687, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 93, "long_name": "Wild Eagle", "next_hop": 0, "num": "0x6a88a937", "position": {"altitude": 1337, "latitude": 32.669787, "location_source": "LOC_INTERNAL", "longitude": -106.905899, "time_offset_sec": 212}, "public_key_hex": "7ce8c5001d1a00b459ab45aa033fdaa12ac6ef42d56893003c3dd834794e9e36", "role": "ROUTER_LATE", "short_name": "WM0N", "snr": 9.78, "status": null, "telemetry": {"air_util_tx": 1.126, "battery_level": 52, "channel_utilization": 4.5, "uptime_seconds": 206846, "voltage": 3.768}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 7581, "long_name": "River Coyote", "next_hop": 0, "num": "0x6ac03524", "position": {"altitude": 1459, "latitude": 33.131279, "location_source": "LOC_INTERNAL", "longitude": -108.035675, "time_offset_sec": 7612}, "public_key_hex": "68fd7afb6a2f7dbd732fa013bd181143f906cc65ce33d2810edb0c68897a0c04", "role": "SENSOR", "short_name": "RDYM", "snr": 4.5, "status": null, "telemetry": {"air_util_tx": 0.238, "battery_level": 98, "channel_utilization": 12.09, "uptime_seconds": 9279, "voltage": 4.182}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1010.02, "iaq": 47, "relative_humidity": 55.69, "temperature": 28.1}, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 3598, "long_name": "Frosty Arroyo", "next_hop": 0, "num": "0x6b1505a9", "position": {"altitude": 1280, "latitude": 32.289692, "location_source": "LOC_INTERNAL", "longitude": -106.779069, "time_offset_sec": 3868}, "public_key_hex": "d95c1db8d26a35d1a1a5752866b6414b5f8faba9fc2af8dbdd0dc2ad5fec4de2", "role": "CLIENT", "short_name": "FE2N", "snr": 10.7, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.781, "battery_level": 75, "channel_utilization": 22.77, "uptime_seconds": 72827, "voltage": 3.975}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 998.23, "iaq": 33, "relative_humidity": 62.25, "temperature": 36.78}, "hops_away": 0, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 1330, "long_name": "Floating Squirrel", "next_hop": 0, "num": "0x6b2270e8", "position": {"altitude": 1528, "latitude": 33.389223, "location_source": "LOC_INTERNAL", "longitude": -108.196442, "time_offset_sec": 1470}, "public_key_hex": "31c03b0d9636fe3b833df53b00d92a7e4e5988e7b807c8ba426665808dace31a", "role": "CLIENT_BASE", "short_name": "F0FM", "snr": 0.13, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.645, "battery_level": 94, "channel_utilization": 11.86, "uptime_seconds": 7143, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 3090, "long_name": "Smooth Salmon", "next_hop": 0, "num": "0x6b2dce01", "position": {"altitude": 1409, "latitude": 33.100448, "location_source": "LOC_INTERNAL", "longitude": -107.92389, "time_offset_sec": 3305}, "public_key_hex": "16d1f968b4035b6edf635237f3f01138827927a9848d967d6f31350688cf188a", "role": "CLIENT_HIDDEN", "short_name": "SB4A", "snr": 11.58, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.347, "battery_level": 85, "channel_utilization": 8.17, "uptime_seconds": 36591, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 332, "long_name": "Steel Cedar", "next_hop": 0, "num": "0x6bf30f37", "position": null, "public_key_hex": "88808c58de5b8c4058b666a6db248d8e8ad33045d9df74a5d1a67a98f984706e", "role": "TRACKER", "short_name": "SX1D", "snr": 7.31, "status": {"status": "active"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 2903, "long_name": "Bright Sage", "next_hop": 0, "num": "0x6c8fbc50", "position": {"altitude": 1586, "latitude": 32.350879, "location_source": "LOC_INTERNAL", "longitude": -107.05561, "time_offset_sec": 3201}, "public_key_hex": "461cee2e618fcdeaf759daa978b36ff4eb4d437a83214fea59ea82808297c0ce", "role": "CLIENT_HIDDEN", "short_name": "BPBG", "snr": 4.0, "status": null, "telemetry": {"air_util_tx": 0.289, "battery_level": 85, "channel_utilization": 0.63, "uptime_seconds": 46196, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "MINI_EPAPER_S3", "last_heard_offset_sec": 723, "long_name": "Silver Eagle", "next_hop": 42, "num": "0x6cc140c8", "position": {"altitude": 1298, "latitude": 32.802868, "location_source": "LOC_INTERNAL", "longitude": -108.108877, "time_offset_sec": 731}, "public_key_hex": "5d1514847335f3e3b783bf340990baf1bfeeaeaee6d9f4932894d3d7c82ae65f", "role": "CLIENT", "short_name": "🌵", "snr": 2.76, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 14385, "long_name": "Whispering Falcon", "next_hop": 0, "num": "0x6ce558ad", "position": {"altitude": 1567, "latitude": 32.115722, "location_source": "LOC_INTERNAL", "longitude": -106.926052, "time_offset_sec": 14454}, "public_key_hex": "ba072d449993d9384e2f544d437f138e6032a506820882ad23ad764c7c44582d", "role": "CLIENT", "short_name": "W1DJ", "snr": 6.37, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.819, "battery_level": 55, "channel_utilization": 20.22, "uptime_seconds": 73068, "voltage": 3.795}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 4890, "long_name": "Bright Cedar", "next_hop": 0, "num": "0x6cfdd4fa", "position": {"altitude": 979, "latitude": 32.657349, "location_source": "LOC_INTERNAL", "longitude": -107.084846, "time_offset_sec": 4950}, "public_key_hex": "332d8658cbbab5eaf335b8bbc848934f402374a08c32f6b79ac32eed2601a08c", "role": "ROUTER_LATE", "short_name": "🐝", "snr": 8.44, "status": null, "telemetry": {"air_util_tx": 0.878, "battery_level": 85, "channel_utilization": 1.34, "uptime_seconds": 58815, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 663, "long_name": "Hidden Turtle", "next_hop": 0, "num": "0x6d6fe2cd", "position": {"altitude": 710, "latitude": 33.357273, "location_source": "LOC_INTERNAL", "longitude": -107.306769, "time_offset_sec": 730}, "public_key_hex": "d2984b2719ee23d69b70e70e9b71e8732b5fa3cd148e7376a3a118932268725b", "role": "CLIENT_MUTE", "short_name": "HAD7", "snr": 5.8, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 565, "long_name": "Mountain Dolphin", "next_hop": 0, "num": "0x6d9575e4", "position": {"altitude": 1204, "latitude": 32.968638, "location_source": "LOC_INTERNAL", "longitude": -108.392893, "time_offset_sec": 632}, "public_key_hex": "2b4948dd23b6acce3f6c8789c371cebc0d6d18e9a738600587c303089115e3cf", "role": "SENSOR", "short_name": "MVX9", "snr": 7.42, "status": null, "telemetry": {"air_util_tx": 1.062, "battery_level": 47, "channel_utilization": 7.94, "uptime_seconds": 33895, "voltage": 3.723}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 2618, "long_name": "Tiny Bear", "next_hop": 0, "num": "0x6db0eeb2", "position": {"altitude": 1228, "latitude": 32.430937, "location_source": "LOC_INTERNAL", "longitude": -107.468988, "time_offset_sec": 2827}, "public_key_hex": "", "role": "CLIENT_BASE", "short_name": "TE9P", "snr": 10.5, "status": null, "telemetry": {"air_util_tx": 1.415, "battery_level": 70, "channel_utilization": 10.78, "uptime_seconds": 109124, "voltage": 3.93}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1004.51, "iaq": 30, "relative_humidity": 51.2, "temperature": 5.59}, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 7056, "long_name": "Red Phoenix", "next_hop": 67, "num": "0x6ebad280", "position": {"altitude": 1406, "latitude": 32.587193, "location_source": "LOC_INTERNAL", "longitude": -107.864844, "time_offset_sec": 7077}, "public_key_hex": "4b37206cf6c334f1c025ed1eca12c826ff2e72fcf5b24a4d12ea0349f3754647", "role": "TAK", "short_name": "RSBL", "snr": 12.0, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.068, "battery_level": 101, "channel_utilization": 4.58, "uptime_seconds": 9420, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 748, "long_name": "Happy Mole AE7OR", "next_hop": 0, "num": "0x6f29b8be", "position": {"altitude": 1471, "latitude": 34.024057, "location_source": "LOC_INTERNAL", "longitude": -107.980924, "time_offset_sec": 956}, "public_key_hex": "76d9fbe59a5ec44941574d30735c45f34b0df3b859aa31f4842e316c16493060", "role": "CLIENT", "short_name": "HEAD", "snr": 1.7, "status": null, "telemetry": {"air_util_tx": 2.07, "battery_level": 89, "channel_utilization": 2.5, "uptime_seconds": 4008, "voltage": 4.101}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1002.52, "iaq": 43, "relative_humidity": 27.02, "temperature": 34.46}, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 1148, "long_name": "Short Mesa WD3LM", "next_hop": 0, "num": "0x6fdf60c0", "position": null, "public_key_hex": "7b8a79f2d32792730b51bb3c49fe52b7f32f9c9d0bdad2e236613e5c370f180b", "role": "CLIENT_MUTE", "short_name": "SPEK", "snr": 7.16, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_VISION_MASTER_E290", "last_heard_offset_sec": 3653, "long_name": "Gold Tortoise", "next_hop": 0, "num": "0x70091536", "position": {"altitude": 1231, "latitude": 33.215614, "location_source": "LOC_INTERNAL", "longitude": -107.454934, "time_offset_sec": 3927}, "public_key_hex": "b8bc1238d599bb552daa9bb5854170725e73440aa97a5313a3e809bedf1d2492", "role": "CLIENT", "short_name": "GCR4", "snr": 0.56, "status": null, "telemetry": {"air_util_tx": 0.849, "battery_level": 20, "channel_utilization": 0.54, "uptime_seconds": 72907, "voltage": 3.48}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 7, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 10347, "long_name": "Desert Whale", "next_hop": 122, "num": "0x7049f212", "position": {"altitude": 1563, "latitude": 34.863907, "location_source": "LOC_INTERNAL", "longitude": -107.289982, "time_offset_sec": 10465}, "public_key_hex": "0804773e1c6637bfe1ad68e033090eb8785d465d6488aae6e91153313cbfef52", "role": "CLIENT", "short_name": "DYV8", "snr": 6.21, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 6547, "long_name": "Fast Mesa", "next_hop": 0, "num": "0x706b89dc", "position": {"altitude": 575, "latitude": 33.070382, "location_source": "LOC_INTERNAL", "longitude": -108.658227, "time_offset_sec": 6632}, "public_key_hex": "3c2e7b204295221ff20739d229fa58cc2a0c918643510c1d9c142af4261a6d40", "role": "CLIENT", "short_name": "FELZ", "snr": 7.66, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.176, "battery_level": 62, "channel_utilization": 3.76, "uptime_seconds": 35160, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": {"barometric_pressure": 1011.87, "iaq": 25, "relative_humidity": 37.46, "temperature": 22.71}, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 759, "long_name": "Short Arroyo", "next_hop": 0, "num": "0x7073c568", "position": {"altitude": 1474, "latitude": 32.796892, "location_source": "LOC_INTERNAL", "longitude": -107.986938, "time_offset_sec": 787}, "public_key_hex": "3b06ebd249feb4db8a046d8240f1e6133def1f6681f363341bf1c2d8f35ed253", "role": "CLIENT", "short_name": "SG6Y", "snr": -1.58, "status": null, "telemetry": {"air_util_tx": 0.647, "battery_level": 97, "channel_utilization": 7.86, "uptime_seconds": 205366, "voltage": 4.173}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 481, "long_name": "Green Iguana", "next_hop": 100, "num": "0x70b7aa80", "position": {"altitude": 1720, "latitude": 32.751094, "location_source": "LOC_INTERNAL", "longitude": -106.105514, "time_offset_sec": 528}, "public_key_hex": "c8b9feca4dcd64a53b1f15a8e13c3e717bcc5acb72ff3f8d0087dd65f2386e66", "role": "ROUTER_LATE", "short_name": "GLC3", "snr": -1.8, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.327, "battery_level": 59, "channel_utilization": 2.49, "uptime_seconds": 135440, "voltage": 3.831}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1007.52, "iaq": 47, "relative_humidity": 32.24, "temperature": 26.78}, "hops_away": 2, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 3893, "long_name": "Mountain Squirrel", "next_hop": 14, "num": "0x70d95891", "position": {"altitude": 1127, "latitude": 33.675798, "location_source": "LOC_INTERNAL", "longitude": -106.883999, "time_offset_sec": 4149}, "public_key_hex": "ca4724e421c616c133571de521b110fb8cc4985681e29399d41b8268fea05b4f", "role": "CLIENT", "short_name": "MYSF", "snr": 9.69, "status": null, "telemetry": {"air_util_tx": 0.899, "battery_level": 17, "channel_utilization": 7.19, "uptime_seconds": 137688, "voltage": 3.453}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1509, "long_name": "Gold Adder", "next_hop": 0, "num": "0x71459999", "position": null, "public_key_hex": "01cf4af2928b1fbf274405bf3a17299e7eb73fcdf03ebe8d2efc9e94eb8d179a", "role": "CLIENT", "short_name": "🐺", "snr": 4.63, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1018.3, "iaq": 0, "relative_humidity": 37.74, "temperature": 32.73}, "hops_away": 2, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 1959, "long_name": "Silver Crane", "next_hop": 171, "num": "0x716da39c", "position": null, "public_key_hex": "089363a405cd19f55b88e76e0863663d8d3e6d3b7171d011af89b4f36712a86a", "role": "SENSOR", "short_name": "SIC8", "snr": 0.57, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.419, "battery_level": 45, "channel_utilization": 8.68, "uptime_seconds": 22858, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO_PLUS", "last_heard_offset_sec": 521, "long_name": "Floating Raven", "next_hop": 0, "num": "0x719e4ee9", "position": {"altitude": 913, "latitude": 32.781272, "location_source": "LOC_INTERNAL", "longitude": -107.211215, "time_offset_sec": 682}, "public_key_hex": "7b1afdaebc952249765689c2fe0bf4d41d795822a16e836f1804a636466e1e2e", "role": "CLIENT", "short_name": "F9I9", "snr": -2.23, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.537, "battery_level": 61, "channel_utilization": 6.8, "uptime_seconds": 192545, "voltage": 3.849}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1049, "long_name": "White Turtle", "next_hop": 0, "num": "0x71aaa863", "position": {"altitude": 1203, "latitude": 33.654085, "location_source": "LOC_INTERNAL", "longitude": -107.263033, "time_offset_sec": 1288}, "public_key_hex": "06ce4a8ec0671200fd3e72a02d2eaef7bb9fce10f617f888700875783d85f0c4", "role": "TAK", "short_name": "W0FC", "snr": 2.43, "status": null, "telemetry": {"air_util_tx": 0.083, "battery_level": 85, "channel_utilization": 16.67, "uptime_seconds": 3562, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 2, "environment": null, "hops_away": 1, "hw_model": "HELTEC_VISION_MASTER_E213", "last_heard_offset_sec": 7605, "long_name": "Roving Mamba", "next_hop": 198, "num": "0x7200a1bc", "position": {"altitude": 1097, "latitude": 33.406264, "location_source": "LOC_INTERNAL", "longitude": -107.479595, "time_offset_sec": 7665}, "public_key_hex": "e7e9b3f098033f014a7d0062c6a3794f5b49913c7850b2cdf972aa6a91cba3e7", "role": "CLIENT", "short_name": "RN5I", "snr": 5.81, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.728, "battery_level": 55, "channel_utilization": 12.42, "uptime_seconds": 18866, "voltage": 3.795}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 3093, "long_name": "Tall Fox", "next_hop": 0, "num": "0x722ac5db", "position": {"altitude": 1158, "latitude": 33.754065, "location_source": "LOC_INTERNAL", "longitude": -108.142416, "time_offset_sec": 3181}, "public_key_hex": "5cb8569f357f1f12a62c7b23d01001c4c2cf4c4c307bff7539251865d9c6ef62", "role": "CLIENT_MUTE", "short_name": "TX3E", "snr": 5.35, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1015.37, "iaq": 62, "relative_humidity": 46.84, "temperature": 18.62}, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 705, "long_name": "Iron Bison", "next_hop": 38, "num": "0x72317d7d", "position": {"altitude": 1278, "latitude": 31.93437, "location_source": "LOC_INTERNAL", "longitude": -106.770818, "time_offset_sec": 894}, "public_key_hex": "c536dc8aa9f544bec26fa64ec02f33e0bcf3deea7d40cf8a5929d274da9bc02f", "role": "CLIENT", "short_name": "IHD7", "snr": 9.44, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 1.918, "battery_level": 81, "channel_utilization": 32.59, "uptime_seconds": 147281, "voltage": 4.029}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 16666, "long_name": "Fast Bluff", "next_hop": 0, "num": "0x729d57b3", "position": {"altitude": 1409, "latitude": 33.656311, "location_source": "LOC_INTERNAL", "longitude": -106.945183, "time_offset_sec": 16956}, "public_key_hex": "b16d739c9bba5da22bcefeb30daf4237c1f4c197c1e77068ad2b4931537a3003", "role": "CLIENT", "short_name": "FUAM", "snr": 12.0, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.428, "battery_level": 11, "channel_utilization": 17.7, "uptime_seconds": 19864, "voltage": 3.399}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": {"barometric_pressure": 1011.24, "iaq": 23, "relative_humidity": 81.21, "temperature": 19.5}, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 5391, "long_name": "Silver Beaver", "next_hop": 0, "num": "0x72b29372", "position": {"altitude": 1302, "latitude": 33.3054, "location_source": "LOC_INTERNAL", "longitude": -107.445822, "time_offset_sec": 5586}, "public_key_hex": "f90d811e288681ef2a86d709b512b1cc9e8e624d92909a6d231d1af70a0d974b", "role": "CLIENT", "short_name": "S1Y7", "snr": 10.79, "status": {"status": "rebooted"}, "telemetry": {"air_util_tx": 0.455, "battery_level": 68, "channel_utilization": 35.0, "uptime_seconds": 2721, "voltage": 3.912}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1491, "long_name": "Canyon Bronco K18XM", "next_hop": 0, "num": "0x72d1bb31", "position": {"altitude": 930, "latitude": 33.770664, "location_source": "LOC_INTERNAL", "longitude": -107.936809, "time_offset_sec": 1728}, "public_key_hex": "7db1ca17780b8192e9ce77f648a76bdac0335f6b491e361061312ffe945dd6ec", "role": "CLIENT", "short_name": "CS1D", "snr": 4.57, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WSL_V3", "last_heard_offset_sec": 711, "long_name": "Hidden Adder", "next_hop": 204, "num": "0x72d3c9b3", "position": {"altitude": 1352, "latitude": 33.038897, "location_source": "LOC_INTERNAL", "longitude": -106.605698, "time_offset_sec": 769}, "public_key_hex": "3d9d763bb87710e4ae804eb54774f01048d3f31ca450d0a73e92a4711573f388", "role": "CLIENT", "short_name": "HS9T", "snr": 7.44, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 5321, "long_name": "Forest Salmon", "next_hop": 0, "num": "0x737bd88b", "position": null, "public_key_hex": "e75e5375a6229f57a6512e866a3623e41e94cd991cc0b97d8f2001f99bdbc078", "role": "CLIENT", "short_name": "F33J", "snr": 9.6, "status": null, "telemetry": {"air_util_tx": 0.409, "battery_level": 33, "channel_utilization": 26.34, "uptime_seconds": 45767, "voltage": 3.597}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 3514, "long_name": "Silent Cobra", "next_hop": 235, "num": "0x747b0108", "position": {"altitude": 1113, "latitude": 33.698573, "location_source": "LOC_INTERNAL", "longitude": -107.099209, "time_offset_sec": 3804}, "public_key_hex": "dad3762673a4b521a6bd3333dab99ceed5937dc9e9d8600368bfdb4548aea00d", "role": "CLIENT", "short_name": "SOJ4", "snr": 5.22, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1001.85, "iaq": 0, "relative_humidity": 47.93, "temperature": 37.57}, "hops_away": 2, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 1330, "long_name": "Sharp Tortoise", "next_hop": 58, "num": "0x7482140b", "position": {"altitude": 1593, "latitude": 32.909753, "location_source": "LOC_INTERNAL", "longitude": -106.843692, "time_offset_sec": 1452}, "public_key_hex": "", "role": "CLIENT", "short_name": "🐝", "snr": 7.68, "status": null, "telemetry": {"air_util_tx": 0.68, "battery_level": 71, "channel_utilization": 0.74, "uptime_seconds": 72228, "voltage": 3.939}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 1092, "long_name": "Brave Mustang", "next_hop": 244, "num": "0x74ebe68c", "position": {"altitude": 1066, "latitude": 32.57088, "location_source": "LOC_INTERNAL", "longitude": -107.594198, "time_offset_sec": 1171}, "public_key_hex": "d9c6c924ebe255ffe2f30f4c2b9eb082ee58d1a1a262561b187b55266fcbb44d", "role": "CLIENT", "short_name": "BE1L", "snr": 5.5, "status": null, "telemetry": {"air_util_tx": 0.452, "battery_level": 22, "channel_utilization": 13.31, "uptime_seconds": 31995, "voltage": 3.498}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1441, "long_name": "Desert Pony", "next_hop": 95, "num": "0x75819b22", "position": {"altitude": 1642, "latitude": 32.7144, "location_source": "LOC_INTERNAL", "longitude": -107.293768, "time_offset_sec": 1496}, "public_key_hex": "1274ed4d155eeb387db100a0e9580f1aabcda5da48109168d5e07b54911f21bb", "role": "CLIENT", "short_name": "DL22", "snr": 7.75, "status": null, "telemetry": {"air_util_tx": 0.226, "battery_level": 94, "channel_utilization": 4.3, "uptime_seconds": 315832, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 996.53, "iaq": 40, "relative_humidity": 50.26, "temperature": 22.3}, "hops_away": 5, "hw_model": "RAK4631", "last_heard_offset_sec": 2362, "long_name": "Smooth Tortoise", "next_hop": 26, "num": "0x7592642f", "position": null, "public_key_hex": "38a59621a06369e8a4d9663f50092f8aecc501ca6dd7352ac42412bc24596225", "role": "CLIENT", "short_name": "SUJT", "snr": 11.04, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.582, "battery_level": 30, "channel_utilization": 3.46, "uptime_seconds": 106194, "voltage": 3.57}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1017.05, "iaq": 62, "relative_humidity": 20.66, "temperature": 9.6}, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 1159, "long_name": "Tall Coyote W55FU", "next_hop": 0, "num": "0x75a976fd", "position": {"altitude": 1390, "latitude": 33.082615, "location_source": "LOC_INTERNAL", "longitude": -107.834629, "time_offset_sec": 1184}, "public_key_hex": "c8e6356f5c2ec5c35fa7af9760899bdbd760dd00b9a9f086c4825488224473eb", "role": "CLIENT", "short_name": "TPUY", "snr": 0.29, "status": null, "telemetry": {"air_util_tx": 0.858, "battery_level": 24, "channel_utilization": 18.79, "uptime_seconds": 65427, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 180, "long_name": "Drowsy Shark", "next_hop": 0, "num": "0x763c51ea", "position": {"altitude": 1481, "latitude": 33.016754, "location_source": "LOC_INTERNAL", "longitude": -107.701299, "time_offset_sec": 191}, "public_key_hex": "a2baacc65e28e34b920f93d0abc6f84e2ae418686c165383044e49207f2b4a0b", "role": "CLIENT", "short_name": "D9ZH", "snr": 5.81, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1011.31, "iaq": 47, "relative_humidity": 36.93, "temperature": 17.88}, "hops_away": 2, "hw_model": "T_ECHO", "last_heard_offset_sec": 4592, "long_name": "Sneaky Cobra", "next_hop": 220, "num": "0x76635e54", "position": {"altitude": 1344, "latitude": 32.812135, "location_source": "LOC_INTERNAL", "longitude": -106.951662, "time_offset_sec": 4618}, "public_key_hex": "c3e38660851abef6d4d6c2c8601ab5bb35ff68b6c4b177a60e8d04e407fe33ad", "role": "CLIENT", "short_name": "SPPX", "snr": 6.52, "status": {"status": "nominal"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 1060, "long_name": "Dusk Bluff", "next_hop": 0, "num": "0x766e4007", "position": {"altitude": 1436, "latitude": 33.156057, "location_source": "LOC_INTERNAL", "longitude": -106.498656, "time_offset_sec": 1208}, "public_key_hex": "37169d6a09d2b2db79c9b8b86c17d07c152858ee0b7525ebd9016fd0267202d7", "role": "ROUTER", "short_name": "DC7V", "snr": 0.68, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.551, "battery_level": 53, "channel_utilization": 9.38, "uptime_seconds": 33734, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": {"barometric_pressure": 1003.64, "iaq": 0, "relative_humidity": 50.28, "temperature": 34.94}, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 16708, "long_name": "River Badger AE6LR", "next_hop": 0, "num": "0x7688d7e7", "position": {"altitude": 1237, "latitude": 32.381937, "location_source": "LOC_INTERNAL", "longitude": -107.515037, "time_offset_sec": 16823}, "public_key_hex": "41c0a3c812d4ec19ff44c06827616f99d7abbdd73833cfd91bcce1ad42efe016", "role": "CLIENT", "short_name": "RRCQ", "snr": 12.0, "status": {"status": "online"}, "telemetry": {"air_util_tx": 0.406, "battery_level": 77, "channel_utilization": 25.9, "uptime_seconds": 107176, "voltage": 3.993}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 18686, "long_name": "Lost Hawk", "next_hop": 0, "num": "0x768e79f3", "position": {"altitude": 1538, "latitude": 33.305402, "location_source": "LOC_INTERNAL", "longitude": -107.245097, "time_offset_sec": 18952}, "public_key_hex": "96035f83127debc01a20a7a4b63c31312fea59bd4370277ea568d84df8395412", "role": "ROUTER", "short_name": "LWVP", "snr": 6.53, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1013.87, "iaq": 61, "relative_humidity": 37.63, "temperature": 29.91}, "hops_away": 2, "hw_model": "T_DECK", "last_heard_offset_sec": 6606, "long_name": "Misty Trout", "next_hop": 150, "num": "0x770fc426", "position": {"altitude": 1020, "latitude": 33.669337, "location_source": "LOC_INTERNAL", "longitude": -106.755362, "time_offset_sec": 6878}, "public_key_hex": "930cdc2003db4ef1733bf34ac04a138c23c7bb8a2ed96066c855426fca86a6d9", "role": "CLIENT", "short_name": "MSZG", "snr": -3.72, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.747, "battery_level": 24, "channel_utilization": 16.84, "uptime_seconds": 38808, "voltage": 3.516}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 2359, "long_name": "Sleepy Juniper", "next_hop": 0, "num": "0x771bf8a9", "position": null, "public_key_hex": "23649b698d1a3c04a949bd6be3103325b8968dac4c3bc37384daeee403e2f4c7", "role": "TAK_TRACKER", "short_name": "S4XI", "snr": 9.37, "status": null, "telemetry": {"air_util_tx": 1.043, "battery_level": 39, "channel_utilization": 23.22, "uptime_seconds": 81536, "voltage": 3.651}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 5, "environment": null, "hops_away": 0, "hw_model": "MUZI_BASE", "last_heard_offset_sec": 1611, "long_name": "Short Beaver", "next_hop": 0, "num": "0x776c4708", "position": {"altitude": 1255, "latitude": 33.763903, "location_source": "LOC_INTERNAL", "longitude": -106.466717, "time_offset_sec": 1794}, "public_key_hex": "94b30977c1b425535001b8805ad1ec5a0e84248f5fb9131898e21fe072f9c47f", "role": "CLIENT", "short_name": "SNUD", "snr": 8.49, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 1.003, "battery_level": 84, "channel_utilization": 27.72, "uptime_seconds": 127743, "voltage": 4.056}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TLORA_T3_S3", "last_heard_offset_sec": 2426, "long_name": "Solar Owl", "next_hop": 182, "num": "0x777ac886", "position": {"altitude": 1439, "latitude": 32.592907, "location_source": "LOC_INTERNAL", "longitude": -108.330483, "time_offset_sec": 2636}, "public_key_hex": "eb0873f4bd12f8341cb06ab37dc50cae3f2a8bb9a8cfa28e34dc54d5d2d452ef", "role": "CLIENT", "short_name": "STDJ", "snr": 11.84, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 801, "long_name": "Bright Arroyo", "next_hop": 0, "num": "0x77cfa02a", "position": {"altitude": 1750, "latitude": 33.411219, "location_source": "LOC_INTERNAL", "longitude": -107.565288, "time_offset_sec": 1093}, "public_key_hex": "3e34f1df51c60337e3c4a9c95ee60b7c6569afa18657d7f39074699c28871df3", "role": "SENSOR", "short_name": "BE6T", "snr": 12.0, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.178, "battery_level": 39, "channel_utilization": 5.08, "uptime_seconds": 16174, "voltage": 3.651}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 54, "long_name": "Lunar Lynx", "next_hop": 121, "num": "0x780294e9", "position": {"altitude": 1659, "latitude": 33.962318, "location_source": "LOC_INTERNAL", "longitude": -107.544268, "time_offset_sec": 272}, "public_key_hex": "36a4b7e10bf625cc0d160a943b884634f5706f0346e8c47c8f7472f8e35d06f7", "role": "CLIENT", "short_name": "LXIE", "snr": 2.4, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 8650, "long_name": "Iron Heron", "next_hop": 0, "num": "0x780d26b0", "position": {"altitude": 1282, "latitude": 31.893481, "location_source": "LOC_INTERNAL", "longitude": -107.055716, "time_offset_sec": 8868}, "public_key_hex": "4d12ba69521f0d49c49e3493c9cd972617c2bb8a21c5f6e25880f232ed3b15b7", "role": "CLIENT", "short_name": "I1HT", "snr": 6.74, "status": null, "telemetry": {"air_util_tx": 0.545, "battery_level": 57, "channel_utilization": 6.47, "uptime_seconds": 131248, "voltage": 3.813}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 7, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 3022, "long_name": "Brave Pike", "next_hop": 14, "num": "0x78496d44", "position": {"altitude": 1186, "latitude": 32.456601, "location_source": "LOC_INTERNAL", "longitude": -107.308159, "time_offset_sec": 3076}, "public_key_hex": "29ec8065252760321e5f90962332bf1efb623e658da09d3dfc645d1fae66edff", "role": "ROUTER", "short_name": "BQFF", "snr": -0.68, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 1519, "long_name": "Tiny Colt", "next_hop": 0, "num": "0x785ece6e", "position": null, "public_key_hex": "7dfbd80205fbaf4ddff7df764b803f0005634acb464f15225ad6aa34312ea8d3", "role": "CLIENT", "short_name": "TVAA", "snr": 5.55, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 253, "long_name": "Misty Shark", "next_hop": 123, "num": "0x78b1b84d", "position": {"altitude": 1392, "latitude": 33.329327, "location_source": "LOC_INTERNAL", "longitude": -107.092506, "time_offset_sec": 305}, "public_key_hex": "b6ede5d696727422a7c14921b90c89447fa29f5b891055f8115646aa4c006a86", "role": "CLIENT", "short_name": "MF0Y", "snr": 4.07, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAP", "last_heard_offset_sec": 2345, "long_name": "Happy Arroyo", "next_hop": 0, "num": "0x790a2d18", "position": {"altitude": 998, "latitude": 32.548507, "location_source": "LOC_INTERNAL", "longitude": -107.187949, "time_offset_sec": 2571}, "public_key_hex": "c1ddda5281f7fc5380a8b40685bf0de8b4e7013e437cea71c0e3b8b1a6bf9859", "role": "CLIENT", "short_name": "🌵", "snr": 1.56, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_WIRELESS_TRACKER_V2", "last_heard_offset_sec": 1518, "long_name": "Stone Mesa", "next_hop": 0, "num": "0x796bac87", "position": {"altitude": 1532, "latitude": 33.331451, "location_source": "LOC_INTERNAL", "longitude": -107.20749, "time_offset_sec": 1780}, "public_key_hex": "11a1106709cbbe68eaea431f5e1ac3f48426a89045d7437e2be1b0b8a5a32833", "role": "CLIENT_HIDDEN", "short_name": "S0E7", "snr": -0.62, "status": {"status": "running"}, "telemetry": {"air_util_tx": 0.559, "battery_level": 25, "channel_utilization": 8.11, "uptime_seconds": 53807, "voltage": 3.525}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "WISMESH_TAP_V2", "last_heard_offset_sec": 3964, "long_name": "Rough Squirrel", "next_hop": 0, "num": "0x79c7fc54", "position": {"altitude": 1184, "latitude": 33.847673, "location_source": "LOC_INTERNAL", "longitude": -108.399321, "time_offset_sec": 4180}, "public_key_hex": "e1128e0570df2d4c6c06b509ced92d7866f742c8bb5acd5d2bae222907026f91", "role": "CLIENT", "short_name": "🌙", "snr": 10.86, "status": null, "telemetry": {"air_util_tx": 0.064, "battery_level": 53, "channel_utilization": 9.05, "uptime_seconds": 44833, "voltage": 3.777}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1024.35, "iaq": 0, "relative_humidity": 66.53, "temperature": 19.84}, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 3455, "long_name": "Hidden Shark", "next_hop": 0, "num": "0x79cd3168", "position": {"altitude": 1341, "latitude": 32.735161, "location_source": "LOC_INTERNAL", "longitude": -106.941718, "time_offset_sec": 3596}, "public_key_hex": "fd66c9774c563a92c870ae6bed5b6c15f0cf0ac084cbf32a808f6bca6722dd8b", "role": "CLIENT", "short_name": "H4VJ", "snr": 4.53, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 1671, "long_name": "Shady Mesa", "next_hop": 0, "num": "0x79fc6f8a", "position": null, "public_key_hex": "b320b94d3ccdee790157a8246ea0cc68e5895bd513718f81d6966fb017b47f80", "role": "CLIENT", "short_name": "SFKE", "snr": 4.16, "status": {"status": "running"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": true}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "T_LORA_PAGER", "last_heard_offset_sec": 9430, "long_name": "Quick Cactus", "next_hop": 136, "num": "0x7a37ec20", "position": {"altitude": 1345, "latitude": 33.129057, "location_source": "LOC_INTERNAL", "longitude": -107.822688, "time_offset_sec": 9676}, "public_key_hex": "a193c1c68016952a5df22fa46a732a0ea80e4a48deb6885d347b682254b31a31", "role": "CLIENT", "short_name": "QYEE", "snr": 7.7, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.338, "battery_level": 19, "channel_utilization": 6.92, "uptime_seconds": 94670, "voltage": 3.471}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": true, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_MESH_NODE_T114", "last_heard_offset_sec": 707, "long_name": "Old Salmon", "next_hop": 2, "num": "0x7a4281ac", "position": null, "public_key_hex": "af9afb469b819caf92b67458302e74913fa1c1b6dc88d609d214ad58d57c2ef4", "role": "TAK", "short_name": "OHVD", "snr": 5.82, "status": null, "telemetry": {"air_util_tx": 0.285, "battery_level": 36, "channel_utilization": 9.9, "uptime_seconds": 227163, "voltage": 3.624}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 253, "long_name": "Giant Oak", "next_hop": 0, "num": "0x7a623dbf", "position": null, "public_key_hex": "ba3ad195e706e514fe3959becb2fd6597ceb8568d36346aa8b4508de8117b30f", "role": "ROUTER", "short_name": "GGR6", "snr": 2.92, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.421, "battery_level": 29, "channel_utilization": 0.77, "uptime_seconds": 155995, "voltage": 3.561}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 1, "environment": null, "hops_away": 1, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 1624, "long_name": "Whispering Yucca", "next_hop": 133, "num": "0x7afc3bdf", "position": {"altitude": 941, "latitude": 32.651888, "location_source": "LOC_INTERNAL", "longitude": -107.339859, "time_offset_sec": 1856}, "public_key_hex": "", "role": "CLIENT_HIDDEN", "short_name": "W4IF", "snr": 9.03, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "XIAO_NRF52_KIT", "last_heard_offset_sec": 232, "long_name": "Blue Seal", "next_hop": 0, "num": "0x7b03173d", "position": {"altitude": 1281, "latitude": 32.477974, "location_source": "LOC_INTERNAL", "longitude": -106.900437, "time_offset_sec": 327}, "public_key_hex": "ab4e63b10fbced513a64d35b04cec016deeb42571ae924b08766be75c75e43fd", "role": "CLIENT", "short_name": "BS9G", "snr": 3.11, "status": {"status": "nominal"}, "telemetry": {"air_util_tx": 0.137, "battery_level": 27, "channel_utilization": 8.86, "uptime_seconds": 7446, "voltage": 3.543}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 8541, "long_name": "Lone Stag", "next_hop": 0, "num": "0x7b14a1a4", "position": {"altitude": 1618, "latitude": 32.00989, "location_source": "LOC_INTERNAL", "longitude": -106.960274, "time_offset_sec": 8759}, "public_key_hex": "b708eaa3003a627f770f3195d5f12d3aed2a7c6798ad50a5c6af1d9615a68d56", "role": "CLIENT_HIDDEN", "short_name": "LBRG", "snr": -2.17, "status": null, "telemetry": {"air_util_tx": 0.396, "battery_level": 46, "channel_utilization": 19.14, "uptime_seconds": 80209, "voltage": 3.714}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 15532, "long_name": "Stone Cactus", "next_hop": 0, "num": "0x7b85c491", "position": {"altitude": 948, "latitude": 32.596386, "location_source": "LOC_INTERNAL", "longitude": -107.908213, "time_offset_sec": 15772}, "public_key_hex": "62134c353256dadbae4f680097ea9caabb1680b3659cc1f02c7e4fb0282bf43a", "role": "CLIENT", "short_name": "S7WW", "snr": 5.23, "status": null, "telemetry": {"air_util_tx": 0.344, "battery_level": 100, "channel_utilization": 2.77, "uptime_seconds": 153615, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 748, "long_name": "Dawn Elk", "next_hop": 0, "num": "0x7b95d6c4", "position": {"altitude": 1375, "latitude": 32.814726, "location_source": "LOC_INTERNAL", "longitude": -106.699569, "time_offset_sec": 989}, "public_key_hex": "fef6fe0964937dedb0900268ee852637e0059457bf110d028629e4ccf5f8a717", "role": "CLIENT", "short_name": "🦋", "snr": 5.62, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.362, "battery_level": 62, "channel_utilization": 4.13, "uptime_seconds": 83278, "voltage": 3.858}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": true, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1868, "long_name": "Floating Cactus", "next_hop": 78, "num": "0x7b9832ba", "position": {"altitude": 1422, "latitude": 34.760079, "location_source": "LOC_INTERNAL", "longitude": -107.083786, "time_offset_sec": 2123}, "public_key_hex": "f3b168f6cb1dc13894a84e6bcea3815232cfe5b60279401832cc51b2cbbf5200", "role": "CLIENT", "short_name": "FZ3S", "snr": 7.67, "status": {"status": "ready"}, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 4, "environment": {"barometric_pressure": 996.03, "iaq": 103, "relative_humidity": 43.23, "temperature": 27.85}, "hops_away": 2, "hw_model": "HELTEC_MESH_SOLAR", "last_heard_offset_sec": 2349, "long_name": "Soft Coyote", "next_hop": 141, "num": "0x7c4cf82e", "position": null, "public_key_hex": "39c6faeae76d6831292d9828d401b5247709ae3353bc99be2be6217976f15711", "role": "CLIENT", "short_name": "S34Q", "snr": 0.27, "status": {"status": "active"}, "telemetry": {"air_util_tx": 1.144, "battery_level": 79, "channel_utilization": 11.78, "uptime_seconds": 90955, "voltage": 4.011}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1019.12, "iaq": 55, "relative_humidity": 50.17, "temperature": 20.67}, "hops_away": 0, "hw_model": "HELTEC_MESH_POCKET", "last_heard_offset_sec": 661, "long_name": "Forest Dolphin", "next_hop": 0, "num": "0x7cb88352", "position": {"altitude": 857, "latitude": 33.336533, "location_source": "LOC_INTERNAL", "longitude": -107.606652, "time_offset_sec": 706}, "public_key_hex": "cdcaa7a375d26a24dbcb6d7685fc62a5562c1536f9520e0d85396f5710c90aa8", "role": "CLIENT", "short_name": "FN6X", "snr": 0.74, "status": {"status": "active"}, "telemetry": {"air_util_tx": 0.37, "battery_level": 61, "channel_utilization": 9.89, "uptime_seconds": 372510, "voltage": 3.849}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 8676, "long_name": "Brave Iguana", "next_hop": 0, "num": "0x7cf15b3e", "position": {"altitude": 1886, "latitude": 33.819257, "location_source": "LOC_INTERNAL", "longitude": -107.739619, "time_offset_sec": 8913}, "public_key_hex": "6a9c754541b4c2c875a2aadbe922f57c641582c36a2a9b89c8df1e3d22c37eff", "role": "CLIENT", "short_name": "B4LT", "snr": 5.51, "status": {"status": "no-gps"}, "telemetry": {"air_util_tx": 1.236, "battery_level": 45, "channel_utilization": 10.01, "uptime_seconds": 137576, "voltage": 3.705}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 2052, "long_name": "Whispering Doe", "next_hop": 0, "num": "0x7cf4966c", "position": {"altitude": 874, "latitude": 32.846001, "location_source": "LOC_INTERNAL", "longitude": -105.956593, "time_offset_sec": 2166}, "public_key_hex": "", "role": "CLIENT", "short_name": "W99D", "snr": 3.4, "status": null, "telemetry": {"air_util_tx": 0.56, "battery_level": 52, "channel_utilization": 3.85, "uptime_seconds": 38863, "voltage": 3.768}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": true, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": true, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 2, "hw_model": "HELTEC_V3", "last_heard_offset_sec": 902, "long_name": "White Raven AB5MG", "next_hop": 13, "num": "0x7cfd5051", "position": null, "public_key_hex": "9fa2378b9ce7198261d695d5316c1a3a011cbff32b7b4da3384cff071f968cd0", "role": "CLIENT", "short_name": "WPPH", "snr": 8.19, "status": null, "telemetry": {"air_util_tx": 0.506, "battery_level": 35, "channel_utilization": 18.87, "uptime_seconds": 1244, "voltage": 3.615}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": true, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 4, "hw_model": "LILYGO_TBEAM_S3_CORE", "last_heard_offset_sec": 1198, "long_name": "Silver Heron", "next_hop": 89, "num": "0x7d3454ac", "position": {"altitude": 1641, "latitude": 33.593007, "location_source": "LOC_INTERNAL", "longitude": -106.858867, "time_offset_sec": 1487}, "public_key_hex": "604c7af1d4a56fc9dfbdd54eeb7226cf7fc5656527578340139441eb8f043dbc", "role": "CLIENT", "short_name": "🌊", "snr": 9.21, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.806, "battery_level": 89, "channel_utilization": 14.05, "uptime_seconds": 89908, "voltage": 4.101}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "HELTEC_V4", "last_heard_offset_sec": 828, "long_name": "Red Whale", "next_hop": 0, "num": "0x7d3bc64f", "position": {"altitude": 1496, "latitude": 34.091942, "location_source": "LOC_INTERNAL", "longitude": -107.54737, "time_offset_sec": 950}, "public_key_hex": "ba0b75e6258532e1ad5ceb53688bfb9b4d3cecd04313dddc9ae54137b24d6911", "role": "CLIENT", "short_name": "RNTA", "snr": 7.01, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "RAK4631", "last_heard_offset_sec": 3539, "long_name": "Iron Hawk", "next_hop": 0, "num": "0x7d47b6f8", "position": {"altitude": 1822, "latitude": 33.069863, "location_source": "LOC_INTERNAL", "longitude": -107.612415, "time_offset_sec": 3805}, "public_key_hex": "71715cfe83cd82673ad031905c7b9eec55503ded0490c5ca8f0046d378f539c6", "role": "ROUTER_LATE", "short_name": "IMDI", "snr": 12.0, "status": null, "telemetry": {"air_util_tx": 0.067, "battery_level": 39, "channel_utilization": 0.73, "uptime_seconds": 110889, "voltage": 3.651}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_ECHO", "last_heard_offset_sec": 6745, "long_name": "Copper Pine", "next_hop": 0, "num": "0x7daa6446", "position": {"altitude": 1432, "latitude": 32.883057, "location_source": "LOC_INTERNAL", "longitude": -107.857615, "time_offset_sec": 6792}, "public_key_hex": "228c311d5844991c731e338c97905d4686b4c5378a15a6139e7e304ada2e6387", "role": "CLIENT", "short_name": "C25O", "snr": 7.52, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.331, "battery_level": 65, "channel_utilization": 21.64, "uptime_seconds": 159410, "voltage": 3.885}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "TRACKER_T1000_E", "last_heard_offset_sec": 1289, "long_name": "Wild Moose", "next_hop": 0, "num": "0x7e293a9a", "position": null, "public_key_hex": "ef0471274ab1c232c164127963b28415db71aab7ad8988010856ba77ee9363de", "role": "TRACKER", "short_name": "WJXL", "snr": 2.36, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 0.295, "battery_level": 94, "channel_utilization": 19.23, "uptime_seconds": 148622, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "HELTEC_WIRELESS_PAPER", "last_heard_offset_sec": 5811, "long_name": "Silver Cobra", "next_hop": 80, "num": "0x7e98136c", "position": {"altitude": 1176, "latitude": 33.644568, "location_source": "LOC_INTERNAL", "longitude": -107.51554, "time_offset_sec": 6021}, "public_key_hex": "d7d36933041896a386b15c785f552e08f16d4b3ee6687e6dc1e2d38aaf8b0a7d", "role": "CLIENT", "short_name": "SQ5M", "snr": 8.33, "status": {"status": "ready"}, "telemetry": {"air_util_tx": 0.554, "battery_level": 85, "channel_utilization": 5.06, "uptime_seconds": 30228, "voltage": 4.065}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "T_DECK", "last_heard_offset_sec": 704, "long_name": "Lone Mesa", "next_hop": 0, "num": "0x7ee205cc", "position": {"altitude": 1332, "latitude": 33.586042, "location_source": "LOC_INTERNAL", "longitude": -106.953368, "time_offset_sec": 910}, "public_key_hex": "46f79ed30865e398a21c801f213cfc61e58902b85278f7d515b82b8e2e3adba6", "role": "CLIENT", "short_name": "🦂", "snr": 10.02, "status": {"status": "OK"}, "telemetry": {"air_util_tx": 1.145, "battery_level": 90, "channel_utilization": 4.22, "uptime_seconds": 219179, "voltage": 4.11}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 812, "long_name": "Giant Hawk", "next_hop": 125, "num": "0x7ef09a0c", "position": {"altitude": 1360, "latitude": 33.718694, "location_source": "LOC_INTERNAL", "longitude": -106.810279, "time_offset_sec": 1080}, "public_key_hex": "6a912d9ac3abc3be3bded33ebdc06539f3fd4099e33b3638b20bc9d4278749ab", "role": "CLIENT", "short_name": "GSLL", "snr": 7.27, "status": null, "telemetry": {"air_util_tx": 1.274, "battery_level": 94, "channel_utilization": 13.89, "uptime_seconds": 34740, "voltage": 4.146}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 1011.47, "iaq": 77, "relative_humidity": 57.86, "temperature": 19.64}, "hops_away": 1, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 1465, "long_name": "Quick Viper", "next_hop": 254, "num": "0x7f2c9c94", "position": {"altitude": 1504, "latitude": 32.929298, "location_source": "LOC_INTERNAL", "longitude": -107.529246, "time_offset_sec": 1691}, "public_key_hex": "98da664d4852437c7b699b87e5214d9433223984ac1a39af47f3b0e20ef19703", "role": "CLIENT", "short_name": "🦋", "snr": 1.03, "status": null, "telemetry": null}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 3, "hw_model": "RAK4631", "last_heard_offset_sec": 1370, "long_name": "Old Cobra", "next_hop": 96, "num": "0x7f3ce610", "position": {"altitude": 1386, "latitude": 32.584843, "location_source": "LOC_INTERNAL", "longitude": -106.99496, "time_offset_sec": 1565}, "public_key_hex": "46a346b7947ec2d961097e2481c3cd2a29897afb36065ace08b3affac3b0ec4e", "role": "CLIENT", "short_name": "OMR8", "snr": 1.81, "status": null, "telemetry": {"air_util_tx": 0.343, "battery_level": 101, "channel_utilization": 5.13, "uptime_seconds": 184861, "voltage": 4.2}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": true, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": null, "hops_away": 0, "hw_model": "SEEED_SOLAR_NODE", "last_heard_offset_sec": 3375, "long_name": "Copper Mole", "next_hop": 0, "num": "0x7fa9346f", "position": {"altitude": 1088, "latitude": 34.023624, "location_source": "LOC_INTERNAL", "longitude": -107.080344, "time_offset_sec": 3654}, "public_key_hex": "7f351bcc32b693e11f10c794f30fb986a1f701ac9ff394960f3e65af8b4c1e08", "role": "CLIENT", "short_name": "CSX2", "snr": 5.51, "status": {"status": "running"}, "telemetry": {"air_util_tx": 1.156, "battery_level": 31, "channel_utilization": 4.14, "uptime_seconds": 126619, "voltage": 3.579}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 0, "environment": {"barometric_pressure": 986.27, "iaq": 104, "relative_humidity": 61.42, "temperature": 17.96}, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 2608, "long_name": "Quick Beaver", "next_hop": 0, "num": "0x7fb6b696", "position": {"altitude": 1176, "latitude": 33.375736, "location_source": "LOC_INTERNAL", "longitude": -107.702107, "time_offset_sec": 2853}, "public_key_hex": "bbe249baf336d614c31e98d0c3c773de70725991c1244746ab04fcdea1afe730", "role": "CLIENT", "short_name": "Q8U6", "snr": 1.83, "status": null, "telemetry": {"air_util_tx": 0.264, "battery_level": 99, "channel_utilization": 3.68, "uptime_seconds": 59962, "voltage": 4.191}}
{"bitfield": {"has_is_unmessagable": true, "has_user": true, "is_favorite": false, "is_ignored": false, "is_key_manually_verified": false, "is_licensed": false, "is_muted": false, "is_unmessagable": false, "via_mqtt": false}, "channel": 3, "environment": null, "hops_away": 0, "hw_model": "T_DECK_PRO", "last_heard_offset_sec": 5106, "long_name": "Sunny Adder", "next_hop": 0, "num": "0x7fd909ad", "position": {"altitude": 1437, "latitude": 32.788073, "location_source": "LOC_INTERNAL", "longitude": -107.233327, "time_offset_sec": 5249}, "public_key_hex": "80c21b4a6f7e3955bfeb3626b0e7d8af8e884e4afd5af927ed6d4787d43d0131", "role": "CLIENT", "short_name": "SDJF", "snr": 8.38, "status": {"status": "nominal"}, "telemetry": null}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1
View File
@@ -40,6 +40,7 @@ build_flags =
-Wextra
-Isrc/platform/esp32
-std=gnu++17
-DRADIOLIB_EXCLUDE_STM32WLX=1
-DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG
-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-DMYNEWT_VAL_BLE_HS_LOG_LVL=LOG_LEVEL_CRITICAL
@@ -0,0 +1,26 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define USB_VID 0x303a
#define USB_PID 0x1001
// The default Wire will be mapped to PMU and RTC
static const uint8_t SDA = 17;
static const uint8_t SCL = 18;
// Default SPI will be mapped to Radio
static const uint8_t SS = 39;
static const uint8_t MOSI = 40;
static const uint8_t MISO = 41;
static const uint8_t SCK = 42;
// #define SPI_MOSI (11)
// #define SPI_SCK (10)
// #define SPI_MISO (9)
// #define SPI_CS (12)
// #define SDCARD_CS SPI_CS
#endif /* Pins_Arduino_h */
@@ -0,0 +1,24 @@
[env:thinknode_g3]
extends = esp32s3_base
board = ESP32-S3-WROOM-1-N4
board_build.psram_type = opi
build_flags =
${esp32s3_base.build_flags}
-D HAS_UDP_MULTICAST=1
-D BOARD_HAS_PSRAM
-D PRIVATE_HW
-I variants/esp32s3/ELECROW-ThinkNode-G3
-mfix-esp32-psram-cache-issue
lib_ignore =
Ethernet
build_src_filter =
${esp32s3_base.build_src_filter}
+<../variants/esp32s3/ELECROW-ThinkNode-G3/*>
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=github-tags depName=ESP32-CH390 packageName=meshtastic/ESP32-CH390
https://github.com/meshtastic/ESP32-CH390/archive/refs/tags/v1.0.1.zip
@@ -0,0 +1,6 @@
#include "mesh/NodeDB.h"
void variantDefaultConfig()
{
config.network.eth_enabled = true;
}
@@ -0,0 +1,36 @@
#define HAS_GPS 0
#define HAS_WIRE 0
#define I2C_NO_RESCAN
#define WIFI_LED 5
#define WIFI_STATE_ON 0
#define LED_PIN 6
#define LED_STATE_ON 0
#define BUTTON_PIN 4
#define LORA_SCK 42
#define LORA_MISO 41
#define LORA_MOSI 40
#define LORA_CS 39
#define LORA_RESET 21
#define USE_SX1262
#define SX126X_CS LORA_CS
#define SX126X_DIO1 15
#define SX126X_BUSY 47
#define SX126X_RESET LORA_RESET
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define PIN_POWER_EN 45
#define HAS_ETHERNET 1
#define USE_CH390D 1
#define ETH_MISO_PIN 12
#define ETH_MOSI_PIN 11
#define ETH_SCLK_PIN 13
#define ETH_CS_PIN 14
#define ETH_INT_PIN 10
#define ETH_RST_PIN 9
// #define ETH_ADDR 1
@@ -0,0 +1,19 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define USB_VID 0x303a
#define USB_PID 0x1001
// The default Wire will be mapped to PMU and RTC
static const uint8_t SDA = 17;
static const uint8_t SCL = 18;
// Default SPI is the LR1110 radio bus
static const uint8_t SS = 12;
static const uint8_t MOSI = 10;
static const uint8_t MISO = 9;
static const uint8_t SCK = 11;
#endif /* Pins_Arduino_h */
@@ -0,0 +1,23 @@
[env:thinknode_m7]
extends = esp32s3_base
board = ThinkNode-M7
build_flags =
${esp32s3_base.build_flags}
-D ELECROW_ThinkNode_M7
-D HAS_UDP_MULTICAST=1
-D BOARD_HAS_PSRAM
-I variants/esp32s3/ELECROW-ThinkNode-M7
-mfix-esp32-psram-cache-issue
lib_ignore =
Ethernet
build_src_filter =
${esp32s3_base.build_src_filter}
+<../variants/esp32s3/ELECROW-ThinkNode-M7/*>
lib_deps =
${esp32s3_base.lib_deps}
# renovate: datasource=github-tags depName=ESP32-CH390 packageName=meshtastic/ESP32-CH390
https://github.com/meshtastic/ESP32-CH390/archive/refs/tags/v1.0.1.zip
@@ -0,0 +1,11 @@
#include "RadioLib.h"
static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC};
static const Module::RfSwitchMode_t rfswitch_table[] = {
// mode DIO5 DIO6
{LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}},
{LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}},
{LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}},
{LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE,
};
@@ -0,0 +1,6 @@
#include "mesh/NodeDB.h"
void variantDefaultConfig()
{
config.network.eth_enabled = true;
}
@@ -0,0 +1,43 @@
#define HAS_GPS 0
#define HAS_WIRE 0
#define HAS_SCREEN 0
#define I2C_NO_RESCAN
#define UART_TX 43
#define UART_RX 44
#define WIFI_LED 3
#define WIFI_STATE_ON 0
#define LED_PIN 46
#define LED_STATE_ON 0
#define BUTTON_PIN 4
#define BUTTON_ACTIVE_LOW true
#define BUTTON_ACTIVE_PULLUP true
#define LORA_SCK 11
#define LORA_MISO 9
#define LORA_MOSI 10
#define LORA_CS 12
#define LORA_RESET 39
#define USE_LR1110
#define LR1110_SPI_SCK_PIN LORA_SCK
#define LR1110_SPI_MISO_PIN LORA_MISO
#define LR1110_SPI_MOSI_PIN LORA_MOSI
#define LR1110_SPI_NSS_PIN LORA_CS
#define LR1110_IRQ_PIN 38
#define LR1110_BUSY_PIN 13
#define LR1110_NRESET_PIN LORA_RESET
#define LR11X0_DIO3_TCXO_VOLTAGE 1.8
#define LR11X0_DIO_AS_RF_SWITCH
#define HAS_ETHERNET 1
#define USE_CH390D 1
#define ETH_MISO_PIN 14
#define ETH_MOSI_PIN 48
#define ETH_SCLK_PIN 47
#define ETH_CS_PIN 21
#define ETH_INT_PIN 45
// #define ETH_ADDR 1
+1
View File
@@ -50,6 +50,7 @@ build_flags_common =
-fPIC
-Isrc/platform/portduino
-DRADIOLIB_EEPROM_UNSUPPORTED
-DRADIOLIB_EXCLUDE_STM32WLX=1
-lpthread
-lyaml-cpp
-luv
+1
View File
@@ -24,6 +24,7 @@ build_flags =
-DLFS_NO_ASSERT ; Disable LFS assertions , see https://github.com/meshtastic/firmware/pull/3818
-DMESHTASTIC_EXCLUDE_AUDIO=1
-DMESHTASTIC_EXCLUDE_PAXCOUNTER=1
-DRADIOLIB_EXCLUDE_STM32WLX=1
-Os
-std=gnu++17
build_unflags =
+2 -1
View File
@@ -11,13 +11,14 @@ platform_packages =
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
build_flags =
build_flags =
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
-Isrc/platform/rp2xx0
-Isrc/platform/rp2xx0/hardware_rosc/include
-Isrc/platform/rp2xx0/pico_sleep/include
-D__PLAT_RP2040__
-D__FREERTOS=1
-DRADIOLIB_EXCLUDE_STM32WLX=1
# -D _POSIX_THREADS
build_src_filter =
${arduino_base.build_src_filter} -<platform/esp32/> -<nimble/> -<modules/esp32> -<platform/nrf52/> -<platform/stm32wl> -<mesh/eth/> -<mesh/wifi/> -<mesh/http/> -<mesh/raspihttp>