fix(plugin): implement BasePlatformAdapter abstract methods and proper build_source event
release / test-and-release (push) Failing after 12s

This commit is contained in:
2026-09-07 19:45:37 -07:00
parent 7136f8c0fd
commit 2d9106b864
2 changed files with 47 additions and 20 deletions
+46 -19
View File
@@ -14,13 +14,24 @@ import time
from typing import Any, Dict, List, Optional
try:
from gateway.platforms.base import BasePlatformAdapter, SendResult
from gateway.platforms.event import MessageEvent, MessageType
from gateway.platforms.base import (
BasePlatformAdapter,
MessageEvent,
MessageType,
SendResult,
)
except ImportError:
# Allow importing and testing utility functions without gateway in environment
class BasePlatformAdapter: # type: ignore[no-redef]
def __init__(self, config: Any):
def __init__(self, config: Any, platform: Any = "meshtastic"):
self.config = config
self.platform = platform
def build_source(self, **kwargs):
return kwargs
async def handle_message(self, event: Any) -> None:
pass
class SendResult: # type: ignore[no-redef]
def __init__(self, success: bool, message_id: Optional[str] = None, error: Optional[str] = None):
@@ -107,7 +118,7 @@ class MeshtasticAdapter(BasePlatformAdapter):
"""Hermes gateway adapter for Meshtastic LoRa radios over TCP."""
def __init__(self, config: Any):
super().__init__(config)
super().__init__(config, platform="meshtastic")
self.extra = getattr(config, "extra", {}) or {}
self.host = self.extra.get("host", "meshtastic.local")
self.port = int(self.extra.get("port", 4403))
@@ -191,24 +202,32 @@ class MeshtasticAdapter(BasePlatformAdapter):
to_id = packet.get("toId")
is_dm = to_id != "^all" and packet.get("to") == my_node_num
chat_id = from_id if is_dm else f"channel_{ch}"
chat_type = "dm" if is_dm else "channel"
rx_snr = packet.get("rxSnr", 0.0)
hop_limit = packet.get("hopLimit", 0)
logger.info(
"[Meshtastic] Inbound message from %s on ch=%s (is_dm=%s, SNR=%.1fdB): %s",
from_id, ch, is_dm, rx_snr, text
)
# Build Hermes MessageEvent
event = MessageEvent(
platform="meshtastic",
message_type=MessageType.TEXT,
text=text,
sender_id=from_id,
sender_name=from_id,
# Build Hermes SessionSource and MessageEvent
source = self.build_source(
chat_id=chat_id,
chat_name=f"Meshtastic {chat_id}",
chat_type=chat_type,
user_id=from_id,
user_name=from_id,
message_id=str(packet.get("id", int(time.time()))),
)
event = MessageEvent(
text=text,
message_type=MessageType.TEXT,
user_id=from_id,
user_name=from_id,
source=source,
raw_message=packet,
message_id=str(packet.get("id", int(time.time()))),
raw_event=packet,
)
if self._loop and self._loop.is_running():
@@ -217,18 +236,18 @@ class MeshtasticAdapter(BasePlatformAdapter):
except Exception as exc:
logger.exception("[Meshtastic] Error processing received packet: %s", exc)
async def send_message(
async def send(
self,
chat_id: str,
message: str,
reply_to_id: Optional[str] = None,
**kwargs: Any,
content: str,
reply_to: Optional[str] = None,
metadata: Optional[Dict[str, Any]] = None,
) -> SendResult:
"""Send a message out over LoRa."""
"""Send a message out over LoRa (implements BasePlatformAdapter.send)."""
if not self._connected or not self._iface:
return SendResult(success=False, error="Meshtastic radio not connected")
clean_text = strip_markdown(message)
clean_text = strip_markdown(content)
chunks = chunk_text(clean_text, MAX_LORA_MESSAGE_LENGTH)
# Destination: if chat_id starts with '!', it is a direct node ID
@@ -265,6 +284,14 @@ class MeshtasticAdapter(BasePlatformAdapter):
logger.exception("[Meshtastic] Failed to send message: %s", exc)
return SendResult(success=False, error=str(exc))
async def get_chat_info(self, chat_id: str) -> Dict[str, Any]:
"""Get chat/channel info (implements BasePlatformAdapter.get_chat_info)."""
is_dm = chat_id.startswith("!")
return {
"name": f"Node {chat_id}" if is_dm else f"Channel {chat_id}",
"type": "dm" if is_dm else "channel",
}
async def disconnect(self) -> None:
"""Disconnect and clean up resources."""
self._running = False