mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-08-26 17:31:34 +00:00
fix(routing): deliver meshcore_broadcast via meshcore_channel through CompositeTransport
The hinted _broadcast path passed the channel NAME on the `channel` kwarg, which MeshCoreTransport ignores (it reads meshcore_channel), so meshcore_broadcast silently no-op'd on transport=both configs. Route the meshcore child via meshcore_channel and the meshtastic child via channel. Fix the test that asserted the broken kwarg layout. Add the new delivery types to the remaining enumeration/validation sites (channel-test endpoint, scheduler digest chunking, danger-zone valid set). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3b2813cf06
commit
8e6acb9c52
5 changed files with 24 additions and 8 deletions
|
|
@ -550,7 +550,7 @@ class NotificationRuleConfig:
|
|||
custom_message: str = ""
|
||||
|
||||
# Delivery type
|
||||
delivery_type: str = "" # mesh_broadcast, mesh_dm, email, webhook
|
||||
delivery_type: str = "" # mesh_broadcast, mesh_dm, meshcore_broadcast, meshcore_dm, email, webhook
|
||||
|
||||
# Mesh broadcast fields
|
||||
broadcast_channel: int = 0
|
||||
|
|
@ -697,7 +697,8 @@ _DZ_VALID_ROLES = frozenset({
|
|||
})
|
||||
|
||||
_DZ_VALID_DELIVERY = frozenset({
|
||||
"mesh_broadcast", "mesh_dm", "email", "webhook", "none",
|
||||
"mesh_broadcast", "mesh_dm", "meshcore_broadcast", "meshcore_dm",
|
||||
"email", "webhook", "none",
|
||||
})
|
||||
# Hazard families that map onto categories.VALID_TOGGLES. snow is a sub-gate of
|
||||
# weather and flood a sub-gate of seismic (resolved in the correlator), so they
|
||||
|
|
|
|||
|
|
@ -15,11 +15,15 @@ class TestRequest(BaseModel):
|
|||
|
||||
class ChannelTestRequest(BaseModel):
|
||||
"""Request body for channel connectivity test."""
|
||||
type: str # mesh_broadcast, mesh_dm, email, webhook
|
||||
type: str # mesh_broadcast, mesh_dm, meshcore_broadcast, meshcore_dm, email, webhook
|
||||
# Mesh broadcast
|
||||
channel_index: Optional[int] = 0
|
||||
# Mesh DM
|
||||
node_ids: Optional[List[str]] = []
|
||||
# MeshCore broadcast
|
||||
meshcore_channel: Optional[str] = None
|
||||
# MeshCore DM
|
||||
meshcore_dm_contacts: Optional[List[str]] = []
|
||||
# Email
|
||||
smtp_host: Optional[str] = ""
|
||||
smtp_port: Optional[int] = 587
|
||||
|
|
@ -117,6 +121,10 @@ async def test_channel(request: Request, body: ChannelTestRequest):
|
|||
channel_config["channel_index"] = body.channel_index or 0
|
||||
elif body.type == "mesh_dm":
|
||||
channel_config["node_ids"] = body.node_ids or []
|
||||
elif body.type == "meshcore_broadcast":
|
||||
channel_config["meshcore_channel"] = body.meshcore_channel or ""
|
||||
elif body.type == "meshcore_dm":
|
||||
channel_config["meshcore_dm_contacts"] = body.meshcore_dm_contacts or []
|
||||
elif body.type == "email":
|
||||
channel_config.update({
|
||||
"smtp_host": body.smtp_host or "",
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class DigestScheduler:
|
|||
channel = self._channel_factory(rule, self._connector)
|
||||
delivery_type = rule.delivery_type
|
||||
|
||||
if delivery_type in ("mesh_broadcast", "mesh_dm"):
|
||||
if delivery_type in ("mesh_broadcast", "mesh_dm", "meshcore_broadcast", "meshcore_dm"):
|
||||
# One deliver call per chunk
|
||||
chunks = digest.mesh_chunks
|
||||
total = len(chunks)
|
||||
|
|
|
|||
|
|
@ -266,9 +266,13 @@ class CompositeTransport(MeshTransport):
|
|||
"CompositeTransport: hinted broadcast child %r not connected", name
|
||||
)
|
||||
return False
|
||||
child_channel = meshcore_channel if name == "meshcore" else channel
|
||||
try:
|
||||
return child.send_message(text, destination=None, channel=child_channel)
|
||||
if name == "meshcore":
|
||||
return child.send_message(
|
||||
text, destination=None, meshcore_channel=meshcore_channel
|
||||
)
|
||||
else:
|
||||
return child.send_message(text, destination=None, channel=channel)
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
"CompositeTransport: hinted broadcast via %r raised: %s", name, exc
|
||||
|
|
|
|||
|
|
@ -229,11 +229,14 @@ def test_meshcore_broadcast_routes_to_meshcore_child_only():
|
|||
assert rules[0]["delivery_type"] == "meshcore_broadcast"
|
||||
assert rules[0]["meshcore_channel"] == "AIDA"
|
||||
|
||||
# MeshCore child received the call with correct transport+channel.
|
||||
# MeshCore child received the call with the channel NAME on the correct kwarg.
|
||||
assert meshcore_child.send_message.called
|
||||
mc_kwargs = meshcore_child.send_message.call_args.kwargs
|
||||
assert mc_kwargs.get("destination") is None
|
||||
assert mc_kwargs.get("channel") == "AIDA" # child receives channel=meshcore_channel
|
||||
# Regression guard for DEFECT 1: channel NAME must be routed via meshcore_channel=.
|
||||
assert mc_kwargs.get("meshcore_channel") == "AIDA"
|
||||
# The old broken code passed AIDA via channel=; that must NOT be the routing mechanism.
|
||||
assert mc_kwargs.get("channel") != "AIDA"
|
||||
|
||||
# Meshtastic child must NOT have been called.
|
||||
meshtastic_child.send_message.assert_not_called()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue