kopia lustrzana https://github.com/mate-dev/meshtastic-matrix-relay
It's working
rodzic
65f41ee87c
commit
10f509f731
|
@ -2,12 +2,12 @@ import asyncio
|
||||||
import time
|
import time
|
||||||
import meshtastic.tcp_interface
|
import meshtastic.tcp_interface
|
||||||
import meshtastic.serial_interface
|
import meshtastic.serial_interface
|
||||||
|
import meshtastic.ble_interface
|
||||||
from typing import List
|
from typing import List
|
||||||
from config import relay_config
|
from config import relay_config
|
||||||
from log_utils import get_logger
|
from log_utils import get_logger
|
||||||
from db_utils import get_longname, get_shortname
|
from db_utils import get_longname, get_shortname
|
||||||
from plugin_loader import load_plugins
|
from plugin_loader import load_plugins
|
||||||
from ble_interface import BLEInterface
|
|
||||||
|
|
||||||
matrix_rooms: List[dict] = relay_config["matrix_rooms"]
|
matrix_rooms: List[dict] = relay_config["matrix_rooms"]
|
||||||
|
|
||||||
|
@ -32,80 +32,133 @@ def connect_meshtastic(force_connect=False):
|
||||||
attempts = 1
|
attempts = 1
|
||||||
successful = False
|
successful = False
|
||||||
|
|
||||||
if connection_type == "serial":
|
while not successful and attempts <= retry_limit:
|
||||||
serial_port = relay_config["meshtastic"]["serial_port"]
|
try:
|
||||||
logger.info(f"Connecting to serial port {serial_port} ...")
|
if connection_type == "serial":
|
||||||
while not successful and attempts <= retry_limit:
|
serial_port = relay_config["meshtastic"]["serial_port"]
|
||||||
try:
|
logger.info(f"Connecting to serial port {serial_port} ...")
|
||||||
meshtastic_client = meshtastic.serial_interface.SerialInterface(
|
meshtastic_client = meshtastic.serial_interface.SerialInterface(serial_port)
|
||||||
serial_port
|
|
||||||
)
|
elif connection_type == "ble":
|
||||||
successful = True
|
ble_address = relay_config["meshtastic"].get("ble_address")
|
||||||
except Exception as e:
|
ble_name = relay_config["meshtastic"].get("ble_name")
|
||||||
attempts += 1
|
|
||||||
if attempts <= retry_limit:
|
|
||||||
logger.warn(
|
|
||||||
f"Attempt #{attempts-1} failed. Retrying in {attempts} secs {e}"
|
|
||||||
)
|
|
||||||
time.sleep(attempts)
|
|
||||||
else:
|
|
||||||
logger.error(f"Could not connect: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
elif connection_type == "ble":
|
|
||||||
ble_address = relay_config["meshtastic"].get("ble_address")
|
|
||||||
ble_name = relay_config["meshtastic"].get("ble_name")
|
|
||||||
|
|
||||||
if ble_address and ble_name:
|
|
||||||
logger.info(f"Connecting to BLE address {ble_address} ...")
|
|
||||||
elif ble_address:
|
|
||||||
logger.info(f"Connecting to BLE address {ble_address} ...")
|
|
||||||
elif ble_name:
|
|
||||||
logger.info(f"Connecting to BLE name {ble_name} ...")
|
|
||||||
else:
|
|
||||||
logger.error("No BLE address or name provided.")
|
|
||||||
return None
|
|
||||||
|
|
||||||
while not successful and attempts <= retry_limit:
|
|
||||||
try:
|
|
||||||
if ble_address:
|
if ble_address:
|
||||||
meshtastic_client = BLEInterface(address=ble_address)
|
logger.info(f"Connecting to BLE address {ble_address} ...")
|
||||||
|
meshtastic_client = meshtastic.ble_interface.BLEInterface(address=ble_address)
|
||||||
elif ble_name:
|
elif ble_name:
|
||||||
meshtastic_client = BLEInterface(address=ble_name)
|
logger.info(f"Connecting to BLE name {ble_name} ...")
|
||||||
successful = True
|
meshtastic_client = meshtastic.ble_interface.BLEInterface(address=ble_name)
|
||||||
except Exception as e:
|
|
||||||
attempts += 1
|
|
||||||
if attempts <= retry_limit:
|
|
||||||
logger.warn(
|
|
||||||
f"Attempt #{attempts-1} failed. Retrying in {attempts} secs {e}"
|
|
||||||
)
|
|
||||||
time.sleep(attempts)
|
|
||||||
else:
|
else:
|
||||||
logger.error(f"Could not connect: {e}")
|
logger.error("No BLE address or name provided.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
target_host = relay_config["meshtastic"]["host"]
|
||||||
|
logger.info(f"Connecting to host {target_host} ...")
|
||||||
|
meshtastic_client = meshtastic.tcp_interface.TCPInterface(hostname=target_host)
|
||||||
|
|
||||||
else:
|
successful = True
|
||||||
target_host = relay_config["meshtastic"]["host"]
|
nodeInfo = meshtastic_client.getMyNodeInfo()
|
||||||
logger.info(f"Connecting to host {target_host} ...")
|
logger.info(f"Connected to {nodeInfo['user']['shortName']} / {nodeInfo['user']['hwModel']}")
|
||||||
while not successful and attempts <= retry_limit:
|
|
||||||
try:
|
except Exception as e:
|
||||||
meshtastic_client = meshtastic.tcp_interface.TCPInterface(
|
attempts += 1
|
||||||
hostname=target_host
|
if attempts <= retry_limit:
|
||||||
)
|
logger.warn(f"Attempt #{attempts-1} failed. Retrying in {attempts} secs {e}")
|
||||||
successful = True
|
time.sleep(attempts)
|
||||||
except Exception as e:
|
else:
|
||||||
attempts += 1
|
logger.error(f"Could not connect: {e}")
|
||||||
if attempts <= retry_limit:
|
return None
|
||||||
logger.warn(
|
|
||||||
f"Attempt #{attempts-1} failed. Retrying in {attempts} secs... {e}"
|
|
||||||
)
|
|
||||||
time.sleep(attempts)
|
|
||||||
else:
|
|
||||||
logger.error(f"Could not connect: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
nodeInfo = meshtastic_client.getMyNodeInfo()
|
|
||||||
logger.info(
|
|
||||||
f"Connected to {nodeInfo['user']['shortName']} / {nodeInfo['user']['hwModel']}"
|
|
||||||
)
|
|
||||||
return meshtastic_client
|
return meshtastic_client
|
||||||
|
|
||||||
|
def on_lost_meshtastic_connection(interface):
|
||||||
|
logger.error("Lost connection. Reconnecting...")
|
||||||
|
connect_meshtastic(force_connect=True)
|
||||||
|
|
||||||
|
def on_meshtastic_message(packet, loop=None):
|
||||||
|
from matrix_utils import matrix_relay
|
||||||
|
|
||||||
|
sender = packet["fromId"]
|
||||||
|
|
||||||
|
if "text" in packet["decoded"] and packet["decoded"]["text"]:
|
||||||
|
text = packet["decoded"]["text"]
|
||||||
|
|
||||||
|
if "channel" in packet:
|
||||||
|
channel = packet["channel"]
|
||||||
|
else:
|
||||||
|
if packet["decoded"]["portnum"] == "TEXT_MESSAGE_APP":
|
||||||
|
channel = 0
|
||||||
|
else:
|
||||||
|
logger.debug(f"Unknown packet")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Check if the channel is mapped to a Matrix room in the configuration
|
||||||
|
channel_mapped = False
|
||||||
|
for room in matrix_rooms:
|
||||||
|
if room["meshtastic_channel"] == channel:
|
||||||
|
channel_mapped = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if not channel_mapped:
|
||||||
|
logger.debug(f"Skipping message from unmapped channel {channel}")
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"Processing inbound radio message from {sender} on channel {channel}")
|
||||||
|
|
||||||
|
longname = get_longname(sender) or sender
|
||||||
|
shortname = get_shortname(sender) or sender
|
||||||
|
meshnet_name = relay_config["meshtastic"]["meshnet_name"]
|
||||||
|
|
||||||
|
formatted_message = f"[{longname}/{meshnet_name}]: {text}"
|
||||||
|
|
||||||
|
# Plugin functionality
|
||||||
|
plugins = load_plugins()
|
||||||
|
|
||||||
|
found_matching_plugin = False
|
||||||
|
for plugin in plugins:
|
||||||
|
if not found_matching_plugin:
|
||||||
|
result = asyncio.run_coroutine_threadsafe(
|
||||||
|
plugin.handle_meshtastic_message(
|
||||||
|
packet, formatted_message, longname, meshnet_name
|
||||||
|
),
|
||||||
|
loop=loop,
|
||||||
|
)
|
||||||
|
found_matching_plugin = result.result()
|
||||||
|
if found_matching_plugin:
|
||||||
|
logger.debug(f"Processed by plugin {plugin.plugin_name}")
|
||||||
|
|
||||||
|
if found_matching_plugin:
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"Relaying Meshtastic message from {longname} to Matrix: {formatted_message}")
|
||||||
|
|
||||||
|
for room in matrix_rooms:
|
||||||
|
if room["meshtastic_channel"] == channel:
|
||||||
|
asyncio.run_coroutine_threadsafe(
|
||||||
|
matrix_relay(
|
||||||
|
room["id"],
|
||||||
|
formatted_message,
|
||||||
|
longname,
|
||||||
|
shortname,
|
||||||
|
meshnet_name,
|
||||||
|
),
|
||||||
|
loop=loop,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
portnum = packet["decoded"]["portnum"]
|
||||||
|
|
||||||
|
plugins = load_plugins()
|
||||||
|
found_matching_plugin = False
|
||||||
|
for plugin in plugins:
|
||||||
|
if not found_matching_plugin:
|
||||||
|
result = asyncio.run_coroutine_threadsafe(
|
||||||
|
plugin.handle_meshtastic_message(
|
||||||
|
packet, formatted_message=None, longname=None, meshnet_name=None
|
||||||
|
),
|
||||||
|
loop=loop,
|
||||||
|
)
|
||||||
|
found_matching_plugin = result.result()
|
||||||
|
if found_matching_plugin:
|
||||||
|
logger.debug(f"Processed {portnum} with plugin {plugin.plugin_name}")
|
||||||
|
|
Ładowanie…
Reference in New Issue