mmrelay 1.1.4__py3-none-any.whl → 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mmrelay might be problematic. Click here for more details.
- mmrelay/__init__.py +1 -1
- mmrelay/cli.py +1003 -76
- mmrelay/cli_utils.py +696 -0
- mmrelay/config.py +578 -17
- mmrelay/constants/app.py +12 -0
- mmrelay/constants/config.py +6 -1
- mmrelay/constants/messages.py +10 -1
- mmrelay/constants/network.py +7 -0
- mmrelay/e2ee_utils.py +392 -0
- mmrelay/log_utils.py +39 -5
- mmrelay/main.py +96 -26
- mmrelay/matrix_utils.py +1059 -84
- mmrelay/meshtastic_utils.py +192 -40
- mmrelay/plugin_loader.py +76 -44
- mmrelay/plugins/base_plugin.py +16 -4
- mmrelay/plugins/weather_plugin.py +108 -11
- mmrelay/tools/sample-docker-compose-prebuilt.yaml +80 -0
- mmrelay/tools/sample-docker-compose.yaml +34 -8
- mmrelay/tools/sample_config.yaml +29 -4
- {mmrelay-1.1.4.dist-info → mmrelay-1.2.0.dist-info}/METADATA +19 -48
- mmrelay-1.2.0.dist-info/RECORD +45 -0
- mmrelay/config_checker.py +0 -162
- mmrelay-1.1.4.dist-info/RECORD +0 -43
- {mmrelay-1.1.4.dist-info → mmrelay-1.2.0.dist-info}/WHEEL +0 -0
- {mmrelay-1.1.4.dist-info → mmrelay-1.2.0.dist-info}/entry_points.txt +0 -0
- {mmrelay-1.1.4.dist-info → mmrelay-1.2.0.dist-info}/licenses/LICENSE +0 -0
- {mmrelay-1.1.4.dist-info → mmrelay-1.2.0.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from datetime import datetime
|
|
2
3
|
|
|
3
4
|
import requests
|
|
4
5
|
from meshtastic.mesh_interface import BROADCAST_NUM
|
|
@@ -18,41 +19,114 @@ class Plugin(BasePlugin):
|
|
|
18
19
|
return "Show weather forecast for a radio node using GPS location"
|
|
19
20
|
|
|
20
21
|
def generate_forecast(self, latitude, longitude):
|
|
22
|
+
"""
|
|
23
|
+
Generate a concise one-line weather forecast for the given GPS coordinates.
|
|
24
|
+
|
|
25
|
+
Builds and queries the Open-Meteo API for current conditions and hour-aligned forecasts ~+2h and ~+5h, formats temperatures according to the plugin configuration (`self.config["units"]`, default "metric"), and returns a single-line summary including current conditions and the two forecast points.
|
|
26
|
+
|
|
27
|
+
Parameters:
|
|
28
|
+
latitude (float): Latitude in decimal degrees.
|
|
29
|
+
longitude (float): Longitude in decimal degrees.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
str: A single-line forecast such as
|
|
33
|
+
"Now: ☀️ Clear sky - 12.3°C | +2h: 🌧️ Light rain - 13.1°C 20% | +5h: ⛅️ Partly cloudy - 10.8°C 5%".
|
|
34
|
+
On recoverable failures returns a short error message: "Weather data temporarily unavailable.",
|
|
35
|
+
"Error fetching weather data.", or "Error parsing weather data.".
|
|
36
|
+
|
|
37
|
+
Notes:
|
|
38
|
+
- Temperature units are determined by `self.config.get("units", "metric")` ("metric" -> °C, "imperial" -> °F).
|
|
39
|
+
- The function attempts to anchor forecasts to hourly timestamps when available; if timestamps cannot be matched it falls back to hour-of-day indexing (may be less accurate).
|
|
40
|
+
- Network/HTTP errors and request-related exceptions are handled and result in the "Error fetching weather data." message.
|
|
41
|
+
- Malformed or incomplete API responses result in "Error parsing weather data." Unexpected exceptions are re-raised.
|
|
42
|
+
"""
|
|
21
43
|
units = self.config.get("units", "metric") # Default to metric
|
|
22
44
|
temperature_unit = "°C" if units == "metric" else "°F"
|
|
23
45
|
|
|
24
46
|
url = (
|
|
25
47
|
f"https://api.open-meteo.com/v1/forecast?"
|
|
26
48
|
f"latitude={latitude}&longitude={longitude}&"
|
|
27
|
-
f"hourly=temperature_2m,precipitation_probability,weathercode,
|
|
28
|
-
f"forecast_days=
|
|
49
|
+
f"hourly=temperature_2m,precipitation_probability,weathercode,is_day&"
|
|
50
|
+
f"forecast_days=2&timezone=auto¤t_weather=true"
|
|
29
51
|
)
|
|
30
52
|
|
|
31
53
|
try:
|
|
32
54
|
response = requests.get(url, timeout=10)
|
|
55
|
+
response.raise_for_status()
|
|
33
56
|
data = response.json()
|
|
34
57
|
|
|
35
58
|
# Extract relevant weather data
|
|
36
59
|
current_temp = data["current_weather"]["temperature"]
|
|
37
60
|
current_weather_code = data["current_weather"]["weathercode"]
|
|
38
61
|
is_day = data["current_weather"]["is_day"]
|
|
62
|
+
current_time_str = data["current_weather"]["time"]
|
|
63
|
+
|
|
64
|
+
# Parse current time to get the hour with defensive handling
|
|
65
|
+
current_hour = 0
|
|
66
|
+
current_time = None
|
|
67
|
+
try:
|
|
68
|
+
current_time = datetime.fromisoformat(
|
|
69
|
+
current_time_str.replace("Z", "+00:00")
|
|
70
|
+
)
|
|
71
|
+
current_hour = current_time.hour
|
|
72
|
+
except ValueError as ex:
|
|
73
|
+
self.logger.warning(
|
|
74
|
+
f"Unexpected current_weather.time '{current_time_str}': {ex}. Defaulting to hour=0."
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Calculate indices for +2h and +5h forecasts
|
|
78
|
+
# Try to anchor to hourly timestamps for robustness, fall back to hour-of-day
|
|
79
|
+
base_index = current_hour
|
|
80
|
+
hourly_times = data["hourly"].get("time", [])
|
|
81
|
+
if hourly_times and current_time:
|
|
82
|
+
try:
|
|
83
|
+
# Normalize current time to the hour and find it in hourly timestamps
|
|
84
|
+
base_key = current_time.replace(
|
|
85
|
+
minute=0, second=0, microsecond=0
|
|
86
|
+
).strftime("%Y-%m-%dT%H:00")
|
|
87
|
+
base_index = hourly_times.index(base_key)
|
|
88
|
+
except (ValueError, AttributeError):
|
|
89
|
+
# Fall back to hour-of-day if hourly timestamps are unavailable/mismatched
|
|
90
|
+
self.logger.warning(
|
|
91
|
+
"Could not find current time in hourly timestamps. "
|
|
92
|
+
"Falling back to hour-of-day indexing, which may be inaccurate."
|
|
93
|
+
)
|
|
39
94
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
95
|
+
forecast_2h_index = base_index + 2
|
|
96
|
+
forecast_5h_index = base_index + 5
|
|
97
|
+
|
|
98
|
+
# Guard against empty hourly series before clamping
|
|
99
|
+
temps = data["hourly"].get("temperature_2m") or []
|
|
100
|
+
if not temps:
|
|
101
|
+
self.logger.warning("No hourly temperature data returned.")
|
|
102
|
+
return "Weather data temporarily unavailable."
|
|
103
|
+
max_index = len(temps) - 1
|
|
104
|
+
forecast_2h_index = min(forecast_2h_index, max_index)
|
|
105
|
+
forecast_5h_index = min(forecast_5h_index, max_index)
|
|
44
106
|
|
|
45
107
|
forecast_2h_temp = data["hourly"]["temperature_2m"][forecast_2h_index]
|
|
46
108
|
forecast_2h_precipitation = data["hourly"]["precipitation_probability"][
|
|
47
109
|
forecast_2h_index
|
|
48
110
|
]
|
|
49
111
|
forecast_2h_weather_code = data["hourly"]["weathercode"][forecast_2h_index]
|
|
112
|
+
# Get hour-specific day/night flag for +2h forecast
|
|
113
|
+
forecast_2h_is_day = (
|
|
114
|
+
data["hourly"]["is_day"][forecast_2h_index]
|
|
115
|
+
if data["hourly"].get("is_day")
|
|
116
|
+
else is_day
|
|
117
|
+
)
|
|
50
118
|
|
|
51
119
|
forecast_5h_temp = data["hourly"]["temperature_2m"][forecast_5h_index]
|
|
52
120
|
forecast_5h_precipitation = data["hourly"]["precipitation_probability"][
|
|
53
121
|
forecast_5h_index
|
|
54
122
|
]
|
|
55
123
|
forecast_5h_weather_code = data["hourly"]["weathercode"][forecast_5h_index]
|
|
124
|
+
# Get hour-specific day/night flag for +5h forecast
|
|
125
|
+
forecast_5h_is_day = (
|
|
126
|
+
data["hourly"]["is_day"][forecast_5h_index]
|
|
127
|
+
if data["hourly"].get("is_day")
|
|
128
|
+
else is_day
|
|
129
|
+
)
|
|
56
130
|
|
|
57
131
|
if units == "imperial":
|
|
58
132
|
# Convert temperatures from Celsius to Fahrenheit
|
|
@@ -106,19 +180,42 @@ class Plugin(BasePlugin):
|
|
|
106
180
|
f"{current_temp}{temperature_unit} | "
|
|
107
181
|
)
|
|
108
182
|
forecast += (
|
|
109
|
-
f"+2h: {weather_code_to_text(forecast_2h_weather_code,
|
|
183
|
+
f"+2h: {weather_code_to_text(forecast_2h_weather_code, forecast_2h_is_day)} - "
|
|
110
184
|
f"{forecast_2h_temp}{temperature_unit} {forecast_2h_precipitation}% | "
|
|
111
185
|
)
|
|
112
186
|
forecast += (
|
|
113
|
-
f"+5h: {weather_code_to_text(forecast_5h_weather_code,
|
|
187
|
+
f"+5h: {weather_code_to_text(forecast_5h_weather_code, forecast_5h_is_day)} - "
|
|
114
188
|
f"{forecast_5h_temp}{temperature_unit} {forecast_5h_precipitation}%"
|
|
115
189
|
)
|
|
116
190
|
|
|
117
191
|
return forecast
|
|
118
192
|
|
|
119
|
-
except
|
|
120
|
-
|
|
121
|
-
|
|
193
|
+
except Exception as e:
|
|
194
|
+
# Handle HTTP/network errors from requests
|
|
195
|
+
# Handle requests-related exceptions using safe attribute checking
|
|
196
|
+
try:
|
|
197
|
+
# Check if this is a requests exception by checking the module
|
|
198
|
+
if hasattr(requests, "RequestException") and isinstance(
|
|
199
|
+
e, requests.RequestException
|
|
200
|
+
):
|
|
201
|
+
self.logger.error(f"Error fetching weather data: {e}")
|
|
202
|
+
return "Error fetching weather data."
|
|
203
|
+
except (AttributeError, TypeError):
|
|
204
|
+
# Fallback to string-based detection if isinstance fails
|
|
205
|
+
exception_module = getattr(type(e), "__module__", "")
|
|
206
|
+
if "requests" in exception_module:
|
|
207
|
+
self.logger.error(f"Error fetching weather data: {e}")
|
|
208
|
+
return "Error fetching weather data."
|
|
209
|
+
|
|
210
|
+
# Handle data parsing errors
|
|
211
|
+
if isinstance(
|
|
212
|
+
e, (KeyError, IndexError, TypeError, ValueError, AttributeError)
|
|
213
|
+
):
|
|
214
|
+
self.logger.error(f"Malformed weather data: {e}")
|
|
215
|
+
return "Error parsing weather data."
|
|
216
|
+
else:
|
|
217
|
+
# Re-raise unexpected exceptions
|
|
218
|
+
raise
|
|
122
219
|
|
|
123
220
|
async def handle_meshtastic_message(
|
|
124
221
|
self, packet, formatted_message, longname, meshnet_name
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
services:
|
|
2
|
+
mmrelay:
|
|
3
|
+
image: ghcr.io/jeremiah-k/mmrelay:latest
|
|
4
|
+
container_name: meshtastic-matrix-relay
|
|
5
|
+
restart: unless-stopped
|
|
6
|
+
user: "${UID:-1000}:${GID:-1000}"
|
|
7
|
+
|
|
8
|
+
environment:
|
|
9
|
+
- TZ=UTC
|
|
10
|
+
- PYTHONUNBUFFERED=1
|
|
11
|
+
- MPLCONFIGDIR=/tmp/matplotlib
|
|
12
|
+
|
|
13
|
+
# Matrix Authentication: Use 'mmrelay auth login' on host system to create credentials.json
|
|
14
|
+
# The credentials file will be automatically loaded from the volume mount below
|
|
15
|
+
|
|
16
|
+
# Meshtastic Connection Settings - Uncomment and configure as needed
|
|
17
|
+
# TCP Connection (most common)
|
|
18
|
+
# - MMRELAY_MESHTASTIC_CONNECTION_TYPE=tcp
|
|
19
|
+
# - MMRELAY_MESHTASTIC_HOST=192.168.1.100
|
|
20
|
+
# - MMRELAY_MESHTASTIC_PORT=4403 # Default port
|
|
21
|
+
|
|
22
|
+
# Serial Connection (uncomment for serial)
|
|
23
|
+
# - MMRELAY_MESHTASTIC_CONNECTION_TYPE=serial
|
|
24
|
+
# - MMRELAY_MESHTASTIC_SERIAL_PORT=/dev/ttyUSB0
|
|
25
|
+
|
|
26
|
+
# BLE Connection (uncomment for Bluetooth)
|
|
27
|
+
# - MMRELAY_MESHTASTIC_CONNECTION_TYPE=ble
|
|
28
|
+
# - MMRELAY_MESHTASTIC_BLE_ADDRESS=AA:BB:CC:DD:EE:FF
|
|
29
|
+
|
|
30
|
+
# Meshtastic Operational Settings
|
|
31
|
+
# - MMRELAY_MESHTASTIC_BROADCAST_ENABLED=true
|
|
32
|
+
# - MMRELAY_MESHTASTIC_MESHNET_NAME=My Mesh Network
|
|
33
|
+
# - MMRELAY_MESHTASTIC_MESSAGE_DELAY=2.2 # Minimum 2.0 seconds
|
|
34
|
+
|
|
35
|
+
# System Configuration
|
|
36
|
+
# - MMRELAY_LOGGING_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
|
|
37
|
+
# - MMRELAY_LOG_FILE=/app/data/logs/mmrelay.log # Enables file logging
|
|
38
|
+
# - MMRELAY_DATABASE_PATH=/app/data/meshtastic.sqlite
|
|
39
|
+
|
|
40
|
+
# Note: Environment variables for Meshtastic, logging, and database settings take precedence over config.yaml
|
|
41
|
+
|
|
42
|
+
volumes:
|
|
43
|
+
# Map entire ~/.mmrelay directory to /app/data to maintain proper structure
|
|
44
|
+
# This includes config.yaml, plugins/, data/, logs/, credentials.json, and any other subdirectories
|
|
45
|
+
# The --data-dir parameter in CMD points to /app/data
|
|
46
|
+
# Create config.yaml first - see docs/DOCKER.md for setup instructions
|
|
47
|
+
- ${MMRELAY_HOME}/.mmrelay:/app/data
|
|
48
|
+
|
|
49
|
+
# For TCP connections (most common) - Meshtastic typically uses port 4403
|
|
50
|
+
ports:
|
|
51
|
+
- 4403:4403
|
|
52
|
+
|
|
53
|
+
# For serial connections, uncomment the device you need:
|
|
54
|
+
# devices:
|
|
55
|
+
# - /dev/ttyUSB0:/dev/ttyUSB0
|
|
56
|
+
# - /dev/ttyACM0:/dev/ttyACM0
|
|
57
|
+
|
|
58
|
+
# For BLE connections, uncomment these:
|
|
59
|
+
# privileged: true
|
|
60
|
+
# network_mode: host
|
|
61
|
+
# Additional volumes for BLE (add to existing volumes section above):
|
|
62
|
+
# - /var/run/dbus:/var/run/dbus:ro
|
|
63
|
+
# - /sys/bus/usb:/sys/bus/usb:ro
|
|
64
|
+
# - /sys/class/bluetooth:/sys/class/bluetooth:ro
|
|
65
|
+
# - /sys/devices:/sys/devices:ro
|
|
66
|
+
|
|
67
|
+
# Optional: Watchtower for automatic updates
|
|
68
|
+
# Uncomment this service to enable daily checks for new images
|
|
69
|
+
# watchtower:
|
|
70
|
+
# image: containrrr/watchtower:latest
|
|
71
|
+
# container_name: watchtower-mmrelay
|
|
72
|
+
# restart: unless-stopped
|
|
73
|
+
# volumes:
|
|
74
|
+
# - /var/run/docker.sock:/var/run/docker.sock
|
|
75
|
+
# environment:
|
|
76
|
+
# - WATCHTOWER_CLEANUP=true
|
|
77
|
+
# - WATCHTOWER_INCLUDE_STOPPED=true
|
|
78
|
+
# - WATCHTOWER_SCHEDULE=0 0 2 * * * # Daily at 2 AM
|
|
79
|
+
# - WATCHTOWER_TIMEOUT=30s
|
|
80
|
+
# command: meshtastic-matrix-relay
|
|
@@ -10,15 +10,41 @@ services:
|
|
|
10
10
|
- PYTHONUNBUFFERED=1
|
|
11
11
|
- MPLCONFIGDIR=/tmp/matplotlib
|
|
12
12
|
|
|
13
|
+
# Matrix Authentication: Use 'mmrelay auth login' on host system to create credentials.json
|
|
14
|
+
# The credentials file will be automatically loaded from the volume mount below
|
|
15
|
+
|
|
16
|
+
# Meshtastic Connection Settings - Uncomment and configure as needed
|
|
17
|
+
# TCP Connection (most common)
|
|
18
|
+
# - MMRELAY_MESHTASTIC_CONNECTION_TYPE=tcp
|
|
19
|
+
# - MMRELAY_MESHTASTIC_HOST=192.168.1.100
|
|
20
|
+
# - MMRELAY_MESHTASTIC_PORT=4403 # Default port
|
|
21
|
+
|
|
22
|
+
# Serial Connection (uncomment for serial)
|
|
23
|
+
# - MMRELAY_MESHTASTIC_CONNECTION_TYPE=serial
|
|
24
|
+
# - MMRELAY_MESHTASTIC_SERIAL_PORT=/dev/ttyUSB0
|
|
25
|
+
|
|
26
|
+
# BLE Connection (uncomment for Bluetooth)
|
|
27
|
+
# - MMRELAY_MESHTASTIC_CONNECTION_TYPE=ble
|
|
28
|
+
# - MMRELAY_MESHTASTIC_BLE_ADDRESS=AA:BB:CC:DD:EE:FF
|
|
29
|
+
|
|
30
|
+
# Meshtastic Operational Settings
|
|
31
|
+
# - MMRELAY_MESHTASTIC_BROADCAST_ENABLED=true
|
|
32
|
+
# - MMRELAY_MESHTASTIC_MESHNET_NAME=My Mesh Network
|
|
33
|
+
# - MMRELAY_MESHTASTIC_MESSAGE_DELAY=2.2 # Minimum 2.0 seconds
|
|
34
|
+
|
|
35
|
+
# System Configuration
|
|
36
|
+
# - MMRELAY_LOGGING_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
|
|
37
|
+
# - MMRELAY_LOG_FILE=/app/data/logs/mmrelay.log # Enables file logging
|
|
38
|
+
# - MMRELAY_DATABASE_PATH=/app/data/meshtastic.sqlite
|
|
39
|
+
|
|
40
|
+
# Note: Environment variables for Meshtastic, logging, and database settings take precedence over config.yaml
|
|
41
|
+
|
|
13
42
|
volumes:
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# These directories will be created automatically
|
|
20
|
-
- ${MMRELAY_HOME}/.mmrelay/data:/app/data
|
|
21
|
-
- ${MMRELAY_HOME}/.mmrelay/logs:/app/logs
|
|
43
|
+
# Map entire ~/.mmrelay directory to /app/data to maintain proper structure
|
|
44
|
+
# This includes config.yaml, plugins/, data/, logs/, credentials.json, and any other subdirectories
|
|
45
|
+
# The --data-dir parameter in CMD points to /app/data
|
|
46
|
+
# Create config.yaml first with: make config
|
|
47
|
+
- ${MMRELAY_HOME}/.mmrelay:/app/data
|
|
22
48
|
|
|
23
49
|
# For TCP connections (most common) - Meshtastic typically uses port 4403
|
|
24
50
|
ports:
|
mmrelay/tools/sample_config.yaml
CHANGED
|
@@ -3,6 +3,27 @@ matrix:
|
|
|
3
3
|
access_token: reaalllllyloooooongsecretttttcodeeeeeeforrrrbot # See: https://t2bot.io/docs/access_tokens/
|
|
4
4
|
bot_user_id: "@botuser:example.matrix.org"
|
|
5
5
|
|
|
6
|
+
# Alternative: Automatic credentials creation (Docker-friendly)
|
|
7
|
+
# If you provide password instead of access_token, MMRelay will automatically
|
|
8
|
+
# create credentials.json on startup. Useful for Docker deployments.
|
|
9
|
+
#password: your_matrix_password_here # Uncomment and set your Matrix password
|
|
10
|
+
|
|
11
|
+
# End-to-End Encryption (E2EE) configuration
|
|
12
|
+
# NOTE: E2EE requires credentials.json instead of access_token for new sessions
|
|
13
|
+
#
|
|
14
|
+
# SETUP INSTRUCTIONS:
|
|
15
|
+
# 1. Install E2EE dependencies: pipx install 'mmrelay[e2e]'
|
|
16
|
+
# 2. Enable E2EE in config: uncomment and set enabled: true below
|
|
17
|
+
# 3. Create credentials: mmrelay auth login
|
|
18
|
+
# 4. The auth login command will create credentials.json with your Matrix login
|
|
19
|
+
# 5. Restart mmrelay - it will use credentials.json and enable E2EE automatically
|
|
20
|
+
#
|
|
21
|
+
#e2ee:
|
|
22
|
+
# # Optional: When credentials.json is present, MMRelay auto-enables E2EE.
|
|
23
|
+
# # Configure this section only if you want to override defaults (e.g., store_path).
|
|
24
|
+
# enabled: false # Explicit toggle if you need to force-enable/disable (usually not needed)
|
|
25
|
+
# store_path: ~/.mmrelay/store # Optional path for encryption keys storage
|
|
26
|
+
|
|
6
27
|
# Message prefix customization (Meshtastic → Matrix direction)
|
|
7
28
|
#prefix_enabled: true # Enable prefixes on messages from mesh (e.g., "[Alice/MyMesh]: message")
|
|
8
29
|
#prefix_format: "[{long}/{mesh}]: " # Default format. Variables: {long1-20}, {long}, {short}, {mesh1-20}, {mesh}
|
|
@@ -31,7 +52,7 @@ meshtastic:
|
|
|
31
52
|
# # Legacy: heartbeat_interval at meshtastic level still supported but deprecated
|
|
32
53
|
|
|
33
54
|
# Additional configuration options (commented out with defaults)
|
|
34
|
-
|
|
55
|
+
broadcast_enabled: true # Must be set to true to enable Matrix to Meshtastic messages
|
|
35
56
|
#detection_sensor: true # Must be set to true to forward messages of Meshtastic's detection sensor module
|
|
36
57
|
#message_delay: 2.2 # Delay in seconds between messages sent to mesh (minimum: 2.0 due to firmware)
|
|
37
58
|
|
|
@@ -48,10 +69,14 @@ logging:
|
|
|
48
69
|
#color_enabled: true # Set to false to disable colored console output
|
|
49
70
|
|
|
50
71
|
# Component-specific debug logging (useful for troubleshooting)
|
|
72
|
+
# When disabled (false or omitted), external library logs are completely suppressed
|
|
73
|
+
# When enabled, you can use: true (DEBUG level) or specify level: "debug", "info", "warning", "error"
|
|
51
74
|
#debug:
|
|
52
|
-
# matrix_nio: false #
|
|
53
|
-
#
|
|
54
|
-
#
|
|
75
|
+
# matrix_nio: false # Disable matrix-nio logging (default: completely suppressed)
|
|
76
|
+
# #matrix_nio: true # Enable matrix-nio debug logging
|
|
77
|
+
# #matrix_nio: "warning" # Enable matrix-nio warning+ logging
|
|
78
|
+
# bleak: false # Disable BLE (bleak) logging (default: completely suppressed)
|
|
79
|
+
# meshtastic: false # Disable meshtastic library logging (default: completely suppressed)
|
|
55
80
|
|
|
56
81
|
#database:
|
|
57
82
|
# path: ~/.mmrelay/data/meshtastic.sqlite # Default location
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mmrelay
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Bridge between Meshtastic mesh networks and Matrix chat rooms
|
|
5
5
|
Home-page: https://github.com/jeremiah-k/meshtastic-matrix-relay
|
|
6
6
|
Author: Geoff Whittington, Jeremiah K., and contributors
|
|
7
7
|
Author-email: jeremiahk@gmx.com
|
|
8
8
|
Project-URL: Bug Tracker, https://github.com/jeremiah-k/meshtastic-matrix-relay/issues
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
14
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
11
15
|
Classifier: Operating System :: OS Independent
|
|
12
16
|
Classifier: Development Status :: 4 - Beta
|
|
13
17
|
Classifier: Topic :: Communications
|
|
14
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.9
|
|
15
19
|
Description-Content-Type: text/markdown
|
|
16
20
|
License-File: LICENSE
|
|
17
21
|
Requires-Dist: meshtastic>=2.6.4
|
|
@@ -20,12 +24,17 @@ Requires-Dist: matrix-nio==0.25.2
|
|
|
20
24
|
Requires-Dist: matplotlib==3.10.1
|
|
21
25
|
Requires-Dist: requests==2.32.4
|
|
22
26
|
Requires-Dist: markdown==3.8.2
|
|
27
|
+
Requires-Dist: bleach==6.2.0
|
|
23
28
|
Requires-Dist: haversine==2.9.0
|
|
24
29
|
Requires-Dist: schedule==1.2.2
|
|
25
30
|
Requires-Dist: platformdirs==4.3.8
|
|
26
31
|
Requires-Dist: py-staticmaps>=0.4.0
|
|
32
|
+
Requires-Dist: psutil>=5.8.0
|
|
27
33
|
Requires-Dist: rich==14.1.0
|
|
28
34
|
Requires-Dist: setuptools==80.9.0
|
|
35
|
+
Provides-Extra: e2e
|
|
36
|
+
Requires-Dist: matrix-nio[e2e]==0.25.2; extra == "e2e"
|
|
37
|
+
Requires-Dist: python-olm; extra == "e2e"
|
|
29
38
|
Dynamic: author
|
|
30
39
|
Dynamic: author-email
|
|
31
40
|
Dynamic: classifier
|
|
@@ -34,6 +43,7 @@ Dynamic: description-content-type
|
|
|
34
43
|
Dynamic: home-page
|
|
35
44
|
Dynamic: license-file
|
|
36
45
|
Dynamic: project-url
|
|
46
|
+
Dynamic: provides-extra
|
|
37
47
|
Dynamic: requires-dist
|
|
38
48
|
Dynamic: requires-python
|
|
39
49
|
Dynamic: summary
|
|
@@ -55,59 +65,20 @@ A powerful and easy-to-use relay between Meshtastic devices and Matrix chat room
|
|
|
55
65
|
- Configurable through a simple YAML file
|
|
56
66
|
- Supports mapping multiple rooms and channels 1:1
|
|
57
67
|
- Relays messages to/from an MQTT broker, if configured in the Meshtastic firmware
|
|
58
|
-
- ✨️ _Bidirectional replies and reactions support_ ✨️
|
|
59
|
-
- ✨️ _Native Docker support_ ✨️
|
|
68
|
+
- ✨️ _Bidirectional replies and reactions support_ ✨️
|
|
69
|
+
- ✨️ _Native Docker support_ ✨️
|
|
70
|
+
- 🔐 **Matrix End-to-End Encryption (E2EE) support** 🔐 **NEW in v1.2!**
|
|
60
71
|
|
|
61
|
-
|
|
72
|
+
**MMRelay v1.2** introduces full **Matrix End-to-End Encryption** support for secure communication in encrypted rooms. Messages are automatically encrypted/decrypted when communicating with encrypted Matrix rooms, with simple setup using `mmrelay auth login` or automatic credentials creation from config.yaml.
|
|
62
73
|
|
|
63
74
|
## Documentation
|
|
64
75
|
|
|
65
76
|
Visit our [Wiki](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki) for comprehensive guides and information.
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## Quick Start
|
|
72
|
-
|
|
73
|
-
MMRelay runs on Linux, macOS, and Windows.
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
# Install using pipx for isolated installation (recommended)
|
|
77
|
-
pipx install mmrelay
|
|
78
|
-
|
|
79
|
-
# Generate a sample configuration file & then edit it
|
|
80
|
-
mmrelay --generate-config
|
|
81
|
-
|
|
82
|
-
# Start the relay (without --install-service to run manually)
|
|
83
|
-
mmrelay --install-service
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
For detailed installation and configuration instructions, see the [Installation Guide](docs/INSTRUCTIONS.md).
|
|
87
|
-
|
|
88
|
-
## Docker
|
|
78
|
+
MMRelay supports multiple deployment methods including Docker, pip installation, and standalone executables. For complete setup instructions and all deployment options, see:
|
|
89
79
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
# Quick setup with Docker
|
|
94
|
-
make setup # Copy config and open editor (first time)
|
|
95
|
-
make build # Build the Docker image
|
|
96
|
-
make run # Start the container
|
|
97
|
-
make logs # View logs
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Docker provides isolated environment, easy deployment, automatic restarts, and volume persistence.
|
|
101
|
-
|
|
102
|
-
For detailed Docker setup instructions, see the [Docker Guide](docs/DOCKER.md).
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
## Windows Installer
|
|
107
|
-
|
|
108
|
-

|
|
109
|
-
|
|
110
|
-
The latest installer is available in the [releases section](https://github.com/jeremiah-k/meshtastic-matrix-relay/releases).
|
|
80
|
+
- [Installation Instructions](docs/INSTRUCTIONS.md) - Setup and configuration guide
|
|
81
|
+
- [Docker Guide](docs/DOCKER.md) - Docker deployment methods
|
|
111
82
|
|
|
112
83
|
---
|
|
113
84
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
mmrelay/__init__.py,sha256=CcCX3oC0CS1MiZg2aWA5KXA2UXqYLXBT4GP3M07R-cs,120
|
|
2
|
+
mmrelay/cli.py,sha256=LT_DVvhXFPCpGxU5RD4SxNNqtIJyVVD8bwMm9YSz2q8,55711
|
|
3
|
+
mmrelay/cli_utils.py,sha256=z1TfgHM82NdTtO0toGyQrNdeB7F8khtzuLJYjvDG1j8,26380
|
|
4
|
+
mmrelay/config.py,sha256=qajoYz_KCRWCw6ULAND0ysmHqw4Nbv_PjewNrW22O8o,32640
|
|
5
|
+
mmrelay/db_utils.py,sha256=b_cuw4zOwGlvk4CljFh3SguqOi-TRCHW_s9RCt9gUsU,19920
|
|
6
|
+
mmrelay/e2ee_utils.py,sha256=4VL6sP3ln0bZ7ZubE_dSejo0WYMOWqaduWLKnURoeIY,16574
|
|
7
|
+
mmrelay/log_utils.py,sha256=6O-dvt9K5uT89XkA74gcYYQJ5lADAk5U9IVL4mj1XwM,8764
|
|
8
|
+
mmrelay/main.py,sha256=QwOLY6uLvFQZhHRlJrbp_D_-xDuEHQIgEsQ6ME_g1EI,16360
|
|
9
|
+
mmrelay/matrix_utils.py,sha256=at0mME8nWwN-yxGGIlH4GblwGmrJd6DrjlNhM794scU,99146
|
|
10
|
+
mmrelay/meshtastic_utils.py,sha256=86U8vQuWW7xR4E-_n-d7vlQhQ40gO-tJGZcVjzoeFhc,43027
|
|
11
|
+
mmrelay/message_queue.py,sha256=tHKziIPwQ9Xm7qpITyR1r2e-ftdn4ZivdZhek9SmMcQ,18703
|
|
12
|
+
mmrelay/plugin_loader.py,sha256=6SD7eoO0VHnsEPI_YrrnrbeHAjC7okmyUpaA4Eu5AHo,41718
|
|
13
|
+
mmrelay/setup_utils.py,sha256=EAVPmKHQmlXnxMcrkhlU27fBPjJCiwTVSLZdbEFsWLQ,22095
|
|
14
|
+
mmrelay/constants/__init__.py,sha256=M8AXeIcS1JuS8OwmfTmhcCOkAz5XmWlNQ53GBxYOx94,1494
|
|
15
|
+
mmrelay/constants/app.py,sha256=1NoX00c65CcHzQxHjnKCPaFbkJQo3MnNytAe_XmvJUo,714
|
|
16
|
+
mmrelay/constants/config.py,sha256=B1A_OZLLNXHM9rHOwc01ZaJBvFugR2eXlhYYl4nUxlY,2479
|
|
17
|
+
mmrelay/constants/database.py,sha256=4cHfYfBePDUUtVSflrWyStcxKSQv7VE-jSrb1IzAjls,646
|
|
18
|
+
mmrelay/constants/formats.py,sha256=cjbrfNNFCKoGSFsFHR1QQDEQudiGquA9MUapfm0_ZNI,494
|
|
19
|
+
mmrelay/constants/messages.py,sha256=Reu_-6gZGGZQVP6BuqBm01QBhVTFjHVRQSPTUcQJG2Q,1531
|
|
20
|
+
mmrelay/constants/network.py,sha256=QjROOAMxcP1pA1F_gUtuXzm2tORCqo5koqZbwrZRSns,1186
|
|
21
|
+
mmrelay/constants/queue.py,sha256=yyWSrtq06b5GWzZwdl6IFtrMvxEuF9PdKSNPh8DdL2M,565
|
|
22
|
+
mmrelay/plugins/__init__.py,sha256=KVMQIXRhe0wlGj4O3IZ0vOIQRKFkfPYejHXhJL17qrc,51
|
|
23
|
+
mmrelay/plugins/base_plugin.py,sha256=Nh_zz-Z49qYatS4i38C2bLOl1sNDUgWsqpD8NLJdnl0,20807
|
|
24
|
+
mmrelay/plugins/debug_plugin.py,sha256=adX0cRJHUEDLldajybPfiRDDlvytkZe5aN_dSgNKP2Y,870
|
|
25
|
+
mmrelay/plugins/drop_plugin.py,sha256=x4S-e0Muun2Dy1H2qwRMTBB1ptLmy7ZZJhgPu-KefGs,5394
|
|
26
|
+
mmrelay/plugins/health_plugin.py,sha256=svV_GfpAVL0QhiVzi3PVZ1mNpsOL1NHSmkRF-Mn_ExE,2250
|
|
27
|
+
mmrelay/plugins/help_plugin.py,sha256=S7nBhsANK46Zv9wPHOVegPGcuYGMErBsxAnrRlSSCwg,2149
|
|
28
|
+
mmrelay/plugins/map_plugin.py,sha256=eHV_t3TFcypBD4xT_OQx0hD6_iGkLJOADjwYVny0PvE,11292
|
|
29
|
+
mmrelay/plugins/mesh_relay_plugin.py,sha256=gpQkO8S-LqDNwqJpqq5ewGXVEST-JZgOsJmrE-qRzuw,7631
|
|
30
|
+
mmrelay/plugins/nodes_plugin.py,sha256=RDabzyG5hKG5aYWecsRUcLSjMCCv6Pngmq2Qpld1A1U,2903
|
|
31
|
+
mmrelay/plugins/ping_plugin.py,sha256=8uFnT3qfO3RBaTUOx348voIfKpzXB3zTfcT6Gtfc8kM,4070
|
|
32
|
+
mmrelay/plugins/telemetry_plugin.py,sha256=8SxWv4BLXMUTbiVaD3MjlMMdQyS7S_1OfLlVNAUMSO0,6306
|
|
33
|
+
mmrelay/plugins/weather_plugin.py,sha256=7si8q43Fw6Gghj0x7Ah2gyFcdwxodNqINmIj9Olprjg,14412
|
|
34
|
+
mmrelay/tools/__init__.py,sha256=WFjDQjdevgg19_zT6iEoL29rvb1JPqYSd8708Jn5D7A,838
|
|
35
|
+
mmrelay/tools/mmrelay.service,sha256=3vqK1VbfXvVftkTrTEOan77aTHeOT36hIAL7HqJsmTg,567
|
|
36
|
+
mmrelay/tools/sample-docker-compose-prebuilt.yaml,sha256=NWV-g3RwiFlYfjgGL5t9DtInoJJDUSaTBy4w1ICk81A,3136
|
|
37
|
+
mmrelay/tools/sample-docker-compose.yaml,sha256=PHt0MGrzUAzxBovtf1TZyrvJ9YK-ZpdSyyp5Tmp8zIY,2543
|
|
38
|
+
mmrelay/tools/sample.env,sha256=RP-o3rX3jnEIrVG2rqCZq31O1yRXou4HcGrXWLVbKKw,311
|
|
39
|
+
mmrelay/tools/sample_config.yaml,sha256=wQnEhL5St7Xqeb--ClJQVcbVXu_n69fPHuF2zSB0Zu4,6250
|
|
40
|
+
mmrelay-1.2.0.dist-info/licenses/LICENSE,sha256=aB_07MhnK-bL5WLI1ucXLUSdW_yBVoepPRYB0kaAOl8,35204
|
|
41
|
+
mmrelay-1.2.0.dist-info/METADATA,sha256=RvrjFahRkYXAokF54_gLy24oD2pgjjvQEYjcm0oi9BM,6143
|
|
42
|
+
mmrelay-1.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
43
|
+
mmrelay-1.2.0.dist-info/entry_points.txt,sha256=SJZwGUOEpQ-qx4H8UL4xKFnKeInGUaZNW1I0ddjK7Ws,45
|
|
44
|
+
mmrelay-1.2.0.dist-info/top_level.txt,sha256=B_ZLCRm7NYAmI3PipRUyHGymP-C-q16LSeMGzmqJfo4,8
|
|
45
|
+
mmrelay-1.2.0.dist-info/RECORD,,
|