mmrelay 1.1.2__py3-none-any.whl → 1.1.3__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.

@@ -14,10 +14,14 @@ from mmrelay.db_utils import (
14
14
  store_plugin_data,
15
15
  )
16
16
  from mmrelay.log_utils import get_logger
17
+ from mmrelay.message_queue import DEFAULT_MESSAGE_DELAY, queue_message
17
18
 
18
19
  # Global config variable that will be set from main.py
19
20
  config = None
20
21
 
22
+ # Track if we've already shown the deprecated warning
23
+ _deprecated_warning_shown = False
24
+
21
25
 
22
26
  class BasePlugin(ABC):
23
27
  """Abstract base class for all mmrelay plugins.
@@ -59,20 +63,16 @@ class BasePlugin(ABC):
59
63
  return ""
60
64
 
61
65
  def __init__(self, plugin_name=None) -> None:
62
- """Initialize the plugin with configuration and logging.
66
+ """
67
+ Initialize the plugin instance, setting its name, logger, configuration, mapped channels, and response delay.
63
68
 
64
- Args:
65
- plugin_name (str, optional): Plugin name override. If not provided,
66
- uses class-level plugin_name attribute.
69
+ Parameters:
70
+ plugin_name (str, optional): Overrides the plugin's name. If not provided, uses the class-level `plugin_name` attribute.
67
71
 
68
72
  Raises:
69
- ValueError: If plugin_name is not set via parameter or class attribute
73
+ ValueError: If the plugin name is not set via parameter or class attribute.
70
74
 
71
- Sets up:
72
- - Plugin-specific logger
73
- - Configuration from global config
74
- - Channel mapping and validation
75
- - Response delay settings
75
+ Loads plugin-specific configuration from the global config, validates assigned channels, and determines the response delay, enforcing a minimum of 2.0 seconds. Logs a warning if deprecated configuration options are used or if channels are not mapped.
76
76
  """
77
77
  # Allow plugin_name to be passed as a parameter for simpler initialization
78
78
  # This maintains backward compatibility while providing a cleaner API
@@ -132,26 +132,43 @@ class BasePlugin(ABC):
132
132
  f"Plugin '{self.plugin_name}': Channels {invalid_channels} are not mapped in configuration."
133
133
  )
134
134
 
135
- # Get the response delay from the meshtastic config only
136
- self.response_delay = 3 # Default value
135
+ # Get the response delay from the meshtastic config
136
+ self.response_delay = DEFAULT_MESSAGE_DELAY
137
137
  if config is not None:
138
- self.response_delay = config.get("meshtastic", {}).get(
139
- "plugin_response_delay", self.response_delay
140
- )
138
+ meshtastic_config = config.get("meshtastic", {})
139
+
140
+ # Check for new message_delay option first, with fallback to deprecated option
141
+ delay = None
142
+ delay_key = None
143
+ if "message_delay" in meshtastic_config:
144
+ delay = meshtastic_config["message_delay"]
145
+ delay_key = "message_delay"
146
+ elif "plugin_response_delay" in meshtastic_config:
147
+ delay = meshtastic_config["plugin_response_delay"]
148
+ delay_key = "plugin_response_delay"
149
+ # Show deprecated warning only once globally
150
+ global _deprecated_warning_shown
151
+ if not _deprecated_warning_shown:
152
+ self.logger.warning(
153
+ "Configuration option 'plugin_response_delay' is deprecated. "
154
+ "Please use 'message_delay' instead. Support for 'plugin_response_delay' will be removed in a future version."
155
+ )
156
+ _deprecated_warning_shown = True
157
+
158
+ if delay is not None:
159
+ self.response_delay = delay
160
+ # Enforce minimum delay of 2 seconds due to firmware constraints
161
+ if self.response_delay < 2.0:
162
+ self.logger.warning(
163
+ f"{delay_key} of {self.response_delay}s is below minimum of 2.0s (firmware constraint). Using 2.0s."
164
+ )
165
+ self.response_delay = 2.0
141
166
 
142
167
  def start(self):
143
- """Start the plugin and set up scheduled tasks if configured.
144
-
145
- Called automatically when the plugin is loaded. Checks plugin configuration
146
- for scheduling settings and sets up background jobs accordingly.
147
-
148
- Supported schedule formats in config:
149
- - schedule.hours + schedule.at: Run every N hours at specific time
150
- - schedule.minutes + schedule.at: Run every N minutes at specific time
151
- - schedule.hours: Run every N hours
152
- - schedule.minutes: Run every N minutes
168
+ """
169
+ Starts the plugin and configures scheduled background tasks based on plugin settings.
153
170
 
154
- Creates a daemon thread to run the scheduler if any schedule is configured.
171
+ If scheduling options are present in the plugin configuration, sets up periodic execution of the `background_job` method using the specified schedule. Runs scheduled jobs in a separate daemon thread. If no scheduling is configured, the plugin starts without background tasks.
155
172
  """
156
173
  if "schedule" not in self.config or (
157
174
  "at" not in self.config["schedule"]
@@ -224,28 +241,64 @@ class BasePlugin(ABC):
224
241
  return data
225
242
 
226
243
  def get_response_delay(self):
227
- """Get the configured response delay for meshtastic messages.
244
+ """
245
+ Return the configured delay in seconds before sending a Meshtastic response.
228
246
 
229
- Returns:
230
- int: Delay in seconds before sending responses (default: 3)
247
+ The delay is determined by the `meshtastic.message_delay` configuration option, defaulting to 2.2 seconds with a minimum of 2.0 seconds. The deprecated `plugin_response_delay` option is also supported for backward compatibility.
231
248
 
232
- Used to prevent message flooding and ensure proper radio etiquette.
233
- Delay is configured via meshtastic.plugin_response_delay in config.
249
+ Returns:
250
+ float: The response delay in seconds.
234
251
  """
235
252
  return self.response_delay
236
253
 
237
- def is_channel_enabled(self, channel, is_direct_message=False):
238
- """Check if the plugin should respond on a specific channel.
254
+ def send_message(self, text: str, channel: int = 0, destination_id=None) -> bool:
255
+ """
256
+ Send a message to the Meshtastic network via the message queue.
239
257
 
240
- Args:
241
- channel: Channel identifier to check
242
- is_direct_message (bool): Whether this is a direct message
258
+ Automatically queues the message for broadcast or direct delivery, applying rate limiting as configured. Returns True if the message was successfully queued, or False if the Meshtastic client is unavailable.
259
+
260
+ Parameters:
261
+ text (str): The message text to send.
262
+ channel (int, optional): Channel index to send the message on. Defaults to 0.
263
+ destination_id (optional): Destination node ID for direct messages; if None, the message is broadcast.
243
264
 
244
265
  Returns:
245
- bool: True if plugin should respond, False otherwise
266
+ bool: True if the message was queued successfully, False otherwise.
267
+ """
268
+ from mmrelay.meshtastic_utils import connect_meshtastic
269
+
270
+ meshtastic_client = connect_meshtastic()
271
+ if not meshtastic_client:
272
+ self.logger.error("No Meshtastic client available")
273
+ return False
274
+
275
+ description = (
276
+ f"Plugin {self.plugin_name}: {text[:50]}{'...' if len(text) > 50 else ''}"
277
+ )
278
+
279
+ send_kwargs = {
280
+ "text": text,
281
+ "channelIndex": channel,
282
+ }
283
+ if destination_id:
284
+ send_kwargs["destinationId"] = destination_id
285
+
286
+ return queue_message(
287
+ meshtastic_client.sendText,
288
+ description=description,
289
+ **send_kwargs,
290
+ )
291
+
292
+ def is_channel_enabled(self, channel, is_direct_message=False):
293
+ """
294
+ Determine whether the plugin should respond to a message on the specified channel or direct message.
295
+
296
+ Parameters:
297
+ channel: The channel identifier to check.
298
+ is_direct_message (bool): Set to True if the message is a direct message.
246
299
 
247
- Direct messages always return True if the plugin is active.
248
- For channel messages, checks if channel is in plugin's configured channels list.
300
+ Returns:
301
+ bool: True if the plugin should respond on the given channel or to a direct message; False otherwise.
249
302
  """
250
303
  if is_direct_message:
251
304
  return True # Always respond to DMs if the plugin is active
@@ -3,6 +3,10 @@ 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
+ # Message prefix customization (Meshtastic → Matrix direction)
7
+ #prefix_enabled: true # Enable prefixes on messages from mesh (e.g., "[Alice/MyMesh]: message")
8
+ #prefix_format: "[{long}/{mesh}]: " # Default format. Variables: {long1-20}, {long}, {short}, {mesh1-20}, {mesh}
9
+
6
10
  matrix_rooms: # Needs at least 1 room & channel, but supports all Meshtastic channels
7
11
  - id: "#someroomalias:example.matrix.org" # Matrix room aliases & IDs supported
8
12
  meshtastic_channel: 0
@@ -15,9 +19,6 @@ meshtastic:
15
19
  serial_port: /dev/ttyUSB0 # Only used when connection is "serial"
16
20
  ble_address: AA:BB:CC:DD:EE:FF # Only used when connection is "ble" - Uses either an address or name from a `meshtastic --ble-scan`
17
21
  meshnet_name: Your Meshnet Name # This is displayed in full on Matrix, but is truncated when sent to a Meshnet
18
- broadcast_enabled: true # Must be set to true to enable Matrix to Meshtastic messages
19
- detection_sensor: true # Must be set to true to forward messages of Meshtastic's detection sensor module
20
- plugin_response_delay: 3 # Default response delay in seconds for plugins that respond on the mesh;
21
22
  message_interactions: # Configure reactions and replies (both require message storage in database)
22
23
  reactions: false # Enable reaction relaying between platforms
23
24
  replies: false # Enable reply relaying between platforms
@@ -29,6 +30,15 @@ meshtastic:
29
30
  # # Note: BLE connections use real-time disconnection detection and skip periodic checks
30
31
  # # Legacy: heartbeat_interval at meshtastic level still supported but deprecated
31
32
 
33
+ # Additional configuration options (commented out with defaults)
34
+ #broadcast_enabled: true # Must be set to true to enable Matrix to Meshtastic messages
35
+ #detection_sensor: true # Must be set to true to forward messages of Meshtastic's detection sensor module
36
+ #message_delay: 2.2 # Delay in seconds between messages sent to mesh (minimum: 2.0 due to firmware)
37
+
38
+ # Message prefix customization (Matrix → Meshtastic direction)
39
+ #prefix_enabled: true # Enable username prefixes on messages sent to mesh (e.g., "Alice[M]: message")
40
+ #prefix_format: "{display5}[M]: " # Default format. See EXTRA_CONFIGURATION.md for all variables.
41
+
32
42
  logging:
33
43
  level: info
34
44
  #log_to_file: true # Set to true to enable file logging
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mmrelay
3
- Version: 1.1.2
3
+ Version: 1.1.3
4
4
  Summary: Bridge between Meshtastic mesh networks and Matrix chat rooms
5
5
  Home-page: https://github.com/geoffwhittington/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/geoffwhittington/meshtastic-matrix-relay/issues
9
9
  Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
11
11
  Classifier: Operating System :: OS Independent
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Topic :: Communications
@@ -24,7 +24,7 @@ Requires-Dist: haversine==2.9.0
24
24
  Requires-Dist: schedule==1.2.2
25
25
  Requires-Dist: platformdirs==4.3.8
26
26
  Requires-Dist: py-staticmaps>=0.4.0
27
- Requires-Dist: rich==14.0.0
27
+ Requires-Dist: rich==14.1.0
28
28
  Requires-Dist: setuptools==80.9.0
29
29
  Dynamic: author
30
30
  Dynamic: author-email
@@ -58,11 +58,11 @@ A powerful and easy-to-use relay between Meshtastic devices and Matrix chat room
58
58
  - ✨️ _Bidirectional replies and reactions support_ ✨️ **NEW!!**
59
59
  - ✨️ _Native Docker support_ ✨️ **NEW!!**
60
60
 
61
- _We would love to support [Matrix E2EE rooms](https://github.com/geoffwhittington/meshtastic-matrix-relay/issues/33), but this is currently not implemented._
61
+ _We would love to support [Matrix E2EE rooms](https://github.com/jeremiah-k/meshtastic-matrix-relay/issues/33), but this is currently not implemented._
62
62
 
63
63
  ## Documentation
64
64
 
65
- Visit our [Wiki](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki) for comprehensive guides and information.
65
+ Visit our [Wiki](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki) for comprehensive guides and information.
66
66
 
67
67
  - [Installation Instructions](docs/INSTRUCTIONS.md) - Setup and configuration guide
68
68
 
@@ -101,15 +101,13 @@ Docker provides isolated environment, easy deployment, automatic restarts, and v
101
101
 
102
102
  For detailed Docker setup instructions, see the [Docker Guide](docs/DOCKER.md).
103
103
 
104
- > **Note**: Docker builds currently use a temporary fork of the meshtastic library with BLE hanging fixes. PyPI releases use the upstream library. This will be resolved when the fixes are merged upstream.
105
-
106
104
  ---
107
105
 
108
106
  ## Windows Installer
109
107
 
110
108
  ![Windows Installer Screenshot](https://user-images.githubusercontent.com/1770544/235249050-8c79107a-50cc-4803-b989-39e58100342d.png)
111
109
 
112
- The latest installer is available in the [releases section](https://github.com/geoffwhittington/meshtastic-matrix-relay/releases).
110
+ The latest installer is available in the [releases section](https://github.com/jeremiah-k/meshtastic-matrix-relay/releases).
113
111
 
114
112
  ---
115
113
 
@@ -127,7 +125,7 @@ Produce high-level details about your mesh:
127
125
 
128
126
  ![Mesh Details Screenshot](https://user-images.githubusercontent.com/1770544/235245873-1ddc773b-a4cd-4c67-b0a5-b55a29504b73.png)
129
127
 
130
- See the full list of [core plugins](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki/Core-Plugins).
128
+ See the full list of [core plugins](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki/Core-Plugins).
131
129
 
132
130
  ### Community & Custom Plugins
133
131
 
@@ -136,9 +134,9 @@ MMRelay's plugin system allows you to extend functionality in two ways:
136
134
  - **Custom Plugins**: Create personal plugins for your own use, stored in `~/.mmrelay/plugins/custom/`
137
135
  - **Community Plugins**: Share your creations with others or use plugins developed by the community
138
136
 
139
- Check the [Community Plugins Development Guide](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki/Community-Plugin-Development-Guide) in our wiki to get started.
137
+ Check the [Community Plugins Development Guide](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki/Community-Plugin-Development-Guide) in our wiki to get started.
140
138
 
141
- ✨️ Visit the [Community Plugins List](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki/Community-Plugin-List)!
139
+ ✨️ Visit the [Community Plugins List](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki/Community-Plugin-List)!
142
140
 
143
141
  #### Install a Community Plugin
144
142
 
@@ -164,7 +162,7 @@ Plugins make it easy to extend functionality without modifying the core program.
164
162
 
165
163
  ## Getting Started with Matrix
166
164
 
167
- See our Wiki page [Getting Started With Matrix & MM Relay](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki/Getting-Started-With-Matrix-&-MM-Relay).
165
+ See our Wiki page [Getting Started With Matrix & MM Relay](https://github.com/jeremiah-k/meshtastic-matrix-relay/wiki/Getting-Started-With-Matrix-&-MM-Relay).
168
166
 
169
167
  ---
170
168
 
@@ -1,16 +1,17 @@
1
- mmrelay/__init__.py,sha256=ofK1VtDZwWBsSvfj0gcmsvkTTVHq_Go5MpGdU5NxdHM,594
1
+ mmrelay/__init__.py,sha256=4ciaRmcwzGfuaU_HuNDXVr4Qk0WVkPydhrdXIVo9VOs,120
2
2
  mmrelay/cli.py,sha256=hdPTlcGsXTJC9GEUiScG7b3IFp02B3lwhqgwFpU3NsM,13835
3
3
  mmrelay/config.py,sha256=5VZag8iSc5yLQgvwI76bbpizbtqag74cHnfXCrWHNyA,7910
4
4
  mmrelay/config_checker.py,sha256=UnoHVTXzfdTfFkbmXv9r_Si76v-sxXLb5FOaQSOM45E,4909
5
5
  mmrelay/db_utils.py,sha256=eTMMkYVWsmO_DkrBfnZMw4ohg_xa0S9TXJoBjRFTwzo,13590
6
6
  mmrelay/log_utils.py,sha256=1zVHBJ5qSOG1O4cq4Ebngq9dp81vaZOEq5khulAFuuM,6611
7
- mmrelay/main.py,sha256=-usvB02bl4ubwQ4obUzncV-5pKTRaplfOvvKcVNWBK8,12493
8
- mmrelay/matrix_utils.py,sha256=XSOHztRrdIjFGyYt8QhGBL6nMv_6iodeYL288pG9voA,45813
9
- mmrelay/meshtastic_utils.py,sha256=9H5kt7X5KXx8FvnWm4fU-CVoFq35JjE-YQC2j98Miq0,31012
10
- mmrelay/plugin_loader.py,sha256=NRiXF6Ty1WD9jNXXKvzJh7kE0ba5oICXNVAfMaTPqH4,39247
7
+ mmrelay/main.py,sha256=46J-B6wDRawB392u71kP6pxNoayBdmwOiKcqsleikhU,13182
8
+ mmrelay/matrix_utils.py,sha256=Ans7Wroh693un0LOp4x2p8NPfGFJ9z6TnG6ApXRXg7Q,55686
9
+ mmrelay/meshtastic_utils.py,sha256=iy7BwMlqOwpkqSB0pTx2n8oqaKs2kWQ4PXFk4y16ys8,31440
10
+ mmrelay/message_queue.py,sha256=spLK7pVugnl9djVLIh5-P7iHZ7kRtZEZIWTcQ4X1TfI,18529
11
+ mmrelay/plugin_loader.py,sha256=UJ-i6cL2q_hwMTqjRkaOAQDTj6uUrmyj56-XbUVGcng,39231
11
12
  mmrelay/setup_utils.py,sha256=N6qdScHKHEMFKDmT1l7dcLDPNTusZXPkyxrLXjFLhRI,19910
12
13
  mmrelay/plugins/__init__.py,sha256=KVMQIXRhe0wlGj4O3IZ0vOIQRKFkfPYejHXhJL17qrc,51
13
- mmrelay/plugins/base_plugin.py,sha256=Gf3xrWdYnXu2dnY4TcOhCGy9fZDISna8OI_Pgt_QX8Q,15415
14
+ mmrelay/plugins/base_plugin.py,sha256=DJdM-l-69sMnx6Fgn0rweWF5CuWilnQQAT3nm6eq8f4,18359
14
15
  mmrelay/plugins/debug_plugin.py,sha256=adX0cRJHUEDLldajybPfiRDDlvytkZe5aN_dSgNKP2Y,870
15
16
  mmrelay/plugins/drop_plugin.py,sha256=0GOz0dgLnFST1HTgqrMayrjwmYlnu02QxfnTZtdPZ3U,4671
16
17
  mmrelay/plugins/health_plugin.py,sha256=svV_GfpAVL0QhiVzi3PVZ1mNpsOL1NHSmkRF-Mn_ExE,2250
@@ -25,10 +26,10 @@ mmrelay/tools/__init__.py,sha256=WFjDQjdevgg19_zT6iEoL29rvb1JPqYSd8708Jn5D7A,838
25
26
  mmrelay/tools/mmrelay.service,sha256=3vqK1VbfXvVftkTrTEOan77aTHeOT36hIAL7HqJsmTg,567
26
27
  mmrelay/tools/sample-docker-compose.yaml,sha256=vVgJrh-6l48hkj5F-52JA5tpDWPBjiPQ36CE9Pkqn44,1251
27
28
  mmrelay/tools/sample.env,sha256=RP-o3rX3jnEIrVG2rqCZq31O1yRXou4HcGrXWLVbKKw,311
28
- mmrelay/tools/sample_config.yaml,sha256=57LkzZUuCFNmfLzeBn9Vs1rtZ_DLdwjWLjiH3-bN6GY,4094
29
- mmrelay-1.1.2.dist-info/licenses/LICENSE,sha256=yceWauM1c0-FHxVplsD7W1-AbSeRaUNlmqT4UO1msBU,1073
30
- mmrelay-1.1.2.dist-info/METADATA,sha256=OeWp6ooATRMHmJuFjpdYHtKLZioC03-GYU2ci5WnFOg,6705
31
- mmrelay-1.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
32
- mmrelay-1.1.2.dist-info/entry_points.txt,sha256=SJZwGUOEpQ-qx4H8UL4xKFnKeInGUaZNW1I0ddjK7Ws,45
33
- mmrelay-1.1.2.dist-info/top_level.txt,sha256=B_ZLCRm7NYAmI3PipRUyHGymP-C-q16LSeMGzmqJfo4,8
34
- mmrelay-1.1.2.dist-info/RECORD,,
29
+ mmrelay/tools/sample_config.yaml,sha256=grS70MKHFd9e_lZ3GkmzPi4RRW-PdahMOMPCAg07MWs,4718
30
+ mmrelay-1.1.3.dist-info/licenses/LICENSE,sha256=aB_07MhnK-bL5WLI1ucXLUSdW_yBVoepPRYB0kaAOl8,35204
31
+ mmrelay-1.1.3.dist-info/METADATA,sha256=gNG_TVwJfpvt0s7sd3WDEceXl8Li2WCLGHTkYkXOWVQ,6493
32
+ mmrelay-1.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
+ mmrelay-1.1.3.dist-info/entry_points.txt,sha256=SJZwGUOEpQ-qx4H8UL4xKFnKeInGUaZNW1I0ddjK7Ws,45
34
+ mmrelay-1.1.3.dist-info/top_level.txt,sha256=B_ZLCRm7NYAmI3PipRUyHGymP-C-q16LSeMGzmqJfo4,8
35
+ mmrelay-1.1.3.dist-info/RECORD,,