Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion custom_components/meshcore/logbook.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,26 @@ async def handle_channel_message(event, coordinator) -> None:
channel_idx
)

# path_len semantics for received channel packets mirror the
# direct-contact path (see handle_contact_message for the
# empirical notes against the firmware payload):
# * Direct reception (no repeaters): SDK returns 255 (0xFF)
# — sentinel for "no path bytes processed". -1 also occurs
# in some SDK paths.
# * Multi-hop reception: SDK returns the literal hop count.
# path_hash_mode is a separate field — no bit-mask applied here.
# SNR semantics: V3 CHANNEL_MSG_RECV frames carry SNR directly
# (uppercase "SNR" key from the SDK reader). V2 frames only
# surface SNR via the log_channels lookup when channel decryption
# is enabled, so absence is normal — emit the field only when
# the SDK actually provided it.
path_len_raw = payload.get("path_len", 0)
if not isinstance(path_len_raw, int) or path_len_raw < 0 or path_len_raw == 0xFF:
hop_count = 0
else:
hop_count = path_len_raw
snr = payload.get("SNR") # V3 channel frames; V2 only via log_channels

# Create event data
event_data = {
"message": message_text,
Expand All @@ -115,9 +135,13 @@ async def handle_channel_message(event, coordinator) -> None:
"entity_id": entity_id,
"domain": DOMAIN,
"timestamp": dt_util.utcnow().isoformat(),
"message_type": "channel" # Explicit message type for filtering
"message_type": "channel", # Explicit message type for filtering
"hop_count": hop_count,
}

if snr is not None:
event_data["snr"] = snr

# Add sender pubkey if available
if sender_pubkey:
event_data["pubkey_prefix"] = sender_pubkey
Expand Down
2 changes: 2 additions & 0 deletions docs/docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Fired when any message is received. Ideal for notifications and message logging.
- `timestamp` - When received
- `message_type` - "channel"
- `pubkey_prefix` - Sender's public key prefix
- `hop_count` - Number of repeater hops the packet traversed. `0` indicates direct reception (firmware returns the `0xFF` sentinel, which is normalised to `0`); positive values are the literal hop count from the SDK `path_len` byte.
- `snr` - (Optional) Signal-to-noise ratio in dB for this packet. Present on V3 `CHANNEL_MSG_RECV` frames (carried directly in the SDK payload as `SNR`). On V2 frames the field is only populated when channel decryption is enabled and the SDK matched a `log_channels` entry, so absence is normal.
- `rx_log_data` - (Optional) Array of radio reception details when message was received via multiple mesh paths:
- `channel_idx` - Channel number
- `channel_name` - Channel name
Expand Down