kopia lustrzana https://github.com/mate-dev/meshtastic-matrix-relay
109 wiersze
4.2 KiB
Python
109 wiersze
4.2 KiB
Python
import re
|
|
from haversine import haversine
|
|
from plugins.base_plugin import BasePlugin
|
|
from meshtastic_utils import connect_meshtastic
|
|
from meshtastic import mesh_pb2
|
|
|
|
|
|
class Plugin(BasePlugin):
|
|
plugin_name = "drop"
|
|
special_node = "!NODE_MSGS!"
|
|
|
|
def get_position(self, meshtastic_client, node_id):
|
|
for node, info in meshtastic_client.nodes.items():
|
|
if info["user"]["id"] == node_id:
|
|
return info["position"]
|
|
return None
|
|
|
|
async def handle_meshtastic_message(
|
|
self, packet, formatted_message, longname, meshnet_name
|
|
):
|
|
meshtastic_client = connect_meshtastic()
|
|
nodeInfo = meshtastic_client.getMyNodeInfo()
|
|
|
|
# Attempt message drop to packet originator if not relay
|
|
if "fromId" in packet and packet["fromId"] != nodeInfo["user"]["id"]:
|
|
position = self.get_position(meshtastic_client, packet["fromId"])
|
|
if position and "latitude" in position and "longitude" in position:
|
|
packet_location = (
|
|
position["latitude"],
|
|
position["longitude"],
|
|
)
|
|
|
|
self.logger.debug(f"Packet originates from: {packet_location}")
|
|
messages = self.get_node_data(self.special_node)
|
|
unsent_messages = []
|
|
for message in messages:
|
|
# You cannot pickup what you dropped
|
|
if (
|
|
"originator" in message
|
|
and message["originator"] == packet["fromId"]
|
|
):
|
|
unsent_messages.append(message)
|
|
continue
|
|
|
|
try:
|
|
distance_km = haversine(
|
|
(packet_location[0], packet_location[1]),
|
|
message["location"],
|
|
)
|
|
except:
|
|
distance_km = 1000
|
|
radius_km = (
|
|
self.config["radius_km"] if "radius_km" in self.config else 5
|
|
)
|
|
if distance_km <= radius_km:
|
|
target_node = packet["fromId"]
|
|
self.logger.debug(f"Sending dropped message to {target_node}")
|
|
meshtastic_client.sendText(
|
|
text=message["text"], destinationId=target_node
|
|
)
|
|
else:
|
|
unsent_messages.append(message)
|
|
self.set_node_data(self.special_node, unsent_messages)
|
|
total_unsent_messages = len(unsent_messages)
|
|
if total_unsent_messages > 0:
|
|
self.logger.debug(f"{total_unsent_messages} message(s) remaining")
|
|
|
|
# Attempt to drop a message
|
|
if (
|
|
"decoded" in packet
|
|
and "portnum" in packet["decoded"]
|
|
and packet["decoded"]["portnum"] == "TEXT_MESSAGE_APP"
|
|
):
|
|
text = packet["decoded"]["text"] if "text" in packet["decoded"] else None
|
|
if f"!{self.plugin_name}" not in text:
|
|
return False
|
|
|
|
match = re.search(r"!drop\s+(.+)$", text)
|
|
if not match:
|
|
return False
|
|
|
|
drop_message = match.group(1)
|
|
|
|
position = {}
|
|
for node, info in meshtastic_client.nodes.items():
|
|
if info["user"]["id"] == packet["fromId"]:
|
|
position = info["position"]
|
|
|
|
if "latitude" not in position or "longitude" not in position:
|
|
self.logger.debug(
|
|
"Position of dropping node is not known. Skipping ..."
|
|
)
|
|
return True
|
|
|
|
self.store_node_data(
|
|
self.special_node,
|
|
{
|
|
"location": (position["latitude"], position["longitude"]),
|
|
"text": drop_message,
|
|
"originator": packet["fromId"],
|
|
},
|
|
)
|
|
self.logger.debug(f"Dropped a message: {drop_message}")
|
|
return True
|
|
|
|
async def handle_room_message(self, room, event, full_message):
|
|
if self.matches(full_message):
|
|
return True
|