mmrelay 1.0.10__tar.gz → 1.1.0__tar.gz
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-1.0.10/src/mmrelay.egg-info → mmrelay-1.1.0}/PKG-INFO +49 -25
- {mmrelay-1.0.10 → mmrelay-1.1.0}/README.md +34 -20
- mmrelay-1.1.0/requirements.txt +15 -0
- mmrelay-1.1.0/setup.cfg +4 -0
- mmrelay-1.1.0/setup.py +46 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/__init__.py +1 -1
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/db_utils.py +61 -9
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/log_utils.py +56 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/main.py +11 -12
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/matrix_utils.py +385 -73
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/meshtastic_utils.py +158 -30
- mmrelay-1.1.0/src/mmrelay/tools/sample-docker-compose.yaml +32 -0
- mmrelay-1.1.0/src/mmrelay/tools/sample.env +10 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/tools/sample_config.yaml +6 -3
- {mmrelay-1.0.10 → mmrelay-1.1.0/src/mmrelay.egg-info}/PKG-INFO +49 -25
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay.egg-info/SOURCES.txt +3 -1
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay.egg-info/requires.txt +4 -4
- mmrelay-1.0.10/requirements.txt +0 -12
- mmrelay-1.0.10/setup.cfg +0 -52
- {mmrelay-1.0.10 → mmrelay-1.1.0}/LICENSE +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/MANIFEST.in +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/pyproject.toml +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/cli.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/config.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/config_checker.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugin_loader.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/__init__.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/base_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/debug_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/drop_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/health_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/help_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/map_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/mesh_relay_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/nodes_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/ping_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/telemetry_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/plugins/weather_plugin.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/setup_utils.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/tools/__init__.py +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay/tools/mmrelay.service +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay.egg-info/dependency_links.txt +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay.egg-info/entry_points.txt +0 -0
- {mmrelay-1.0.10 → mmrelay-1.1.0}/src/mmrelay.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mmrelay
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
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
|
|
@@ -14,19 +14,29 @@ Classifier: Topic :: Communications
|
|
|
14
14
|
Requires-Python: >=3.8
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: meshtastic
|
|
18
|
-
Requires-Dist: Pillow==11.
|
|
17
|
+
Requires-Dist: meshtastic>=2.6.4
|
|
18
|
+
Requires-Dist: Pillow==11.3.0
|
|
19
19
|
Requires-Dist: matrix-nio==0.25.2
|
|
20
20
|
Requires-Dist: matplotlib==3.10.1
|
|
21
|
-
Requires-Dist: requests==2.32.
|
|
22
|
-
Requires-Dist: markdown==3.8
|
|
21
|
+
Requires-Dist: requests==2.32.4
|
|
22
|
+
Requires-Dist: markdown==3.8.2
|
|
23
23
|
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
27
|
Requires-Dist: rich==14.0.0
|
|
28
28
|
Requires-Dist: setuptools==80.9.0
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: author-email
|
|
31
|
+
Dynamic: classifier
|
|
32
|
+
Dynamic: description
|
|
33
|
+
Dynamic: description-content-type
|
|
34
|
+
Dynamic: home-page
|
|
29
35
|
Dynamic: license-file
|
|
36
|
+
Dynamic: project-url
|
|
37
|
+
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
Dynamic: summary
|
|
30
40
|
|
|
31
41
|
# M<>M Relay
|
|
32
42
|
|
|
@@ -34,13 +44,26 @@ Dynamic: license-file
|
|
|
34
44
|
|
|
35
45
|
A powerful and easy-to-use relay between Meshtastic devices and Matrix chat rooms, allowing seamless communication across platforms. This opens the door for bridging Meshtastic devices to [many other platforms](https://matrix.org/bridges/).
|
|
36
46
|
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
- Bidirectional message relay between Meshtastic devices and Matrix chat rooms, capable of supporting multiple meshnets
|
|
50
|
+
- Supports serial, network, and **_BLE (now too!)_** connections for Meshtastic devices
|
|
51
|
+
- Custom fields are embedded in Matrix messages for relaying messages between multiple meshnets
|
|
52
|
+
- Truncates long messages to fit within Meshtastic's payload size
|
|
53
|
+
- SQLite database to store node information for improved functionality
|
|
54
|
+
- Customizable logging level for easy debugging
|
|
55
|
+
- Configurable through a simple YAML file
|
|
56
|
+
- Supports mapping multiple rooms and channels 1:1
|
|
57
|
+
- Relays messages to/from an MQTT broker, if configured in the Meshtastic firmware
|
|
58
|
+
- ✨️ _Bidirectional replies and reactions support_ ✨️ **NEW!!**
|
|
59
|
+
|
|
60
|
+
_We would love to support [Matrix E2EE rooms](https://github.com/geoffwhittington/meshtastic-matrix-relay/issues/33), but this is currently not implemented._
|
|
61
|
+
|
|
37
62
|
## Documentation
|
|
38
63
|
|
|
39
64
|
Visit our [Wiki](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki) for comprehensive guides and information.
|
|
40
65
|
|
|
41
66
|
- [Installation Instructions](docs/INSTRUCTIONS.md) - Setup and configuration guide
|
|
42
|
-
- [v1.0 Release Announcement](docs/ANNOUNCEMENT.md) - New changes in v1.0
|
|
43
|
-
- [Upgrade Guide](docs/UPGRADE_TO_V1.md) - Migration guidance for existing users
|
|
44
67
|
|
|
45
68
|
---
|
|
46
69
|
|
|
@@ -61,22 +84,23 @@ mmrelay --install-service
|
|
|
61
84
|
|
|
62
85
|
For detailed installation and configuration instructions, see the [Installation Guide](docs/INSTRUCTIONS.md).
|
|
63
86
|
|
|
64
|
-
|
|
87
|
+
## Docker
|
|
65
88
|
|
|
66
|
-
|
|
89
|
+
MMRelay includes official Docker support for easy deployment and management:
|
|
67
90
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- Supports mapping multiple rooms and channels 1:1
|
|
76
|
-
- Relays messages to/from an MQTT broker, if configured in the Meshtastic firmware
|
|
77
|
-
- ✨️ _Cross-platform reactions support_ ✨️ **NEW!!**
|
|
91
|
+
```bash
|
|
92
|
+
# Quick setup with Docker
|
|
93
|
+
make setup # Copy config and open editor (first time)
|
|
94
|
+
make build # Build the Docker image
|
|
95
|
+
make run # Start the container
|
|
96
|
+
make logs # View logs
|
|
97
|
+
```
|
|
78
98
|
|
|
79
|
-
|
|
99
|
+
Docker provides isolated environment, easy deployment, automatic restarts, and volume persistence.
|
|
100
|
+
|
|
101
|
+
For detailed Docker setup instructions, see the [Docker Guide](DOCKER.md).
|
|
102
|
+
|
|
103
|
+
> **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.
|
|
80
104
|
|
|
81
105
|
---
|
|
82
106
|
|
|
@@ -84,7 +108,7 @@ _We would love to support [Matrix E2EE rooms](https://github.com/geoffwhittingto
|
|
|
84
108
|
|
|
85
109
|

|
|
86
110
|
|
|
87
|
-
The latest installer is available [
|
|
111
|
+
The latest installer is available in the [releases section](https://github.com/geoffwhittington/meshtastic-matrix-relay/releases).
|
|
88
112
|
|
|
89
113
|
---
|
|
90
114
|
|
|
@@ -102,7 +126,7 @@ Produce high-level details about your mesh:
|
|
|
102
126
|
|
|
103
127
|

|
|
104
128
|
|
|
105
|
-
See the full list of core plugins
|
|
129
|
+
See the full list of [core plugins](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki/Core-Plugins).
|
|
106
130
|
|
|
107
131
|
### Community & Custom Plugins
|
|
108
132
|
|
|
@@ -147,6 +171,6 @@ See our Wiki page [Getting Started With Matrix & MM Relay](https://github.com/ge
|
|
|
147
171
|
|
|
148
172
|
Join us!
|
|
149
173
|
|
|
150
|
-
- Our project's room: [#mmrelay:
|
|
151
|
-
- Part of the Meshtastic Community Matrix space: [#
|
|
152
|
-
- Public Relay Room: [#relay-room:
|
|
174
|
+
- Our project's room: [#mmrelay:matrix.org](https://matrix.to/#/#mmrelay:matrix.org)
|
|
175
|
+
- Part of the Meshtastic Community Matrix space: [#meshnetclub:matrix.org](https://matrix.to/#/#meshnetclub:matrix.org)
|
|
176
|
+
- Public Relay Room: [#mmrelay-relay-room:matrix.org](https://matrix.to/#/#mmrelay-relay-room:matrix.org) - Where we bridge multiple meshnets. Feel free to join us, with or without a relay!
|
|
@@ -4,13 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
A powerful and easy-to-use relay between Meshtastic devices and Matrix chat rooms, allowing seamless communication across platforms. This opens the door for bridging Meshtastic devices to [many other platforms](https://matrix.org/bridges/).
|
|
6
6
|
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Bidirectional message relay between Meshtastic devices and Matrix chat rooms, capable of supporting multiple meshnets
|
|
10
|
+
- Supports serial, network, and **_BLE (now too!)_** connections for Meshtastic devices
|
|
11
|
+
- Custom fields are embedded in Matrix messages for relaying messages between multiple meshnets
|
|
12
|
+
- Truncates long messages to fit within Meshtastic's payload size
|
|
13
|
+
- SQLite database to store node information for improved functionality
|
|
14
|
+
- Customizable logging level for easy debugging
|
|
15
|
+
- Configurable through a simple YAML file
|
|
16
|
+
- Supports mapping multiple rooms and channels 1:1
|
|
17
|
+
- Relays messages to/from an MQTT broker, if configured in the Meshtastic firmware
|
|
18
|
+
- ✨️ _Bidirectional replies and reactions support_ ✨️ **NEW!!**
|
|
19
|
+
|
|
20
|
+
_We would love to support [Matrix E2EE rooms](https://github.com/geoffwhittington/meshtastic-matrix-relay/issues/33), but this is currently not implemented._
|
|
21
|
+
|
|
7
22
|
## Documentation
|
|
8
23
|
|
|
9
24
|
Visit our [Wiki](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki) for comprehensive guides and information.
|
|
10
25
|
|
|
11
26
|
- [Installation Instructions](docs/INSTRUCTIONS.md) - Setup and configuration guide
|
|
12
|
-
- [v1.0 Release Announcement](docs/ANNOUNCEMENT.md) - New changes in v1.0
|
|
13
|
-
- [Upgrade Guide](docs/UPGRADE_TO_V1.md) - Migration guidance for existing users
|
|
14
27
|
|
|
15
28
|
---
|
|
16
29
|
|
|
@@ -31,22 +44,23 @@ mmrelay --install-service
|
|
|
31
44
|
|
|
32
45
|
For detailed installation and configuration instructions, see the [Installation Guide](docs/INSTRUCTIONS.md).
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
## Docker
|
|
35
48
|
|
|
36
|
-
|
|
49
|
+
MMRelay includes official Docker support for easy deployment and management:
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- Supports mapping multiple rooms and channels 1:1
|
|
46
|
-
- Relays messages to/from an MQTT broker, if configured in the Meshtastic firmware
|
|
47
|
-
- ✨️ _Cross-platform reactions support_ ✨️ **NEW!!**
|
|
51
|
+
```bash
|
|
52
|
+
# Quick setup with Docker
|
|
53
|
+
make setup # Copy config and open editor (first time)
|
|
54
|
+
make build # Build the Docker image
|
|
55
|
+
make run # Start the container
|
|
56
|
+
make logs # View logs
|
|
57
|
+
```
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
Docker provides isolated environment, easy deployment, automatic restarts, and volume persistence.
|
|
60
|
+
|
|
61
|
+
For detailed Docker setup instructions, see the [Docker Guide](DOCKER.md).
|
|
62
|
+
|
|
63
|
+
> **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.
|
|
50
64
|
|
|
51
65
|
---
|
|
52
66
|
|
|
@@ -54,7 +68,7 @@ _We would love to support [Matrix E2EE rooms](https://github.com/geoffwhittingto
|
|
|
54
68
|
|
|
55
69
|

|
|
56
70
|
|
|
57
|
-
The latest installer is available [
|
|
71
|
+
The latest installer is available in the [releases section](https://github.com/geoffwhittington/meshtastic-matrix-relay/releases).
|
|
58
72
|
|
|
59
73
|
---
|
|
60
74
|
|
|
@@ -72,7 +86,7 @@ Produce high-level details about your mesh:
|
|
|
72
86
|
|
|
73
87
|

|
|
74
88
|
|
|
75
|
-
See the full list of core plugins
|
|
89
|
+
See the full list of [core plugins](https://github.com/geoffwhittington/meshtastic-matrix-relay/wiki/Core-Plugins).
|
|
76
90
|
|
|
77
91
|
### Community & Custom Plugins
|
|
78
92
|
|
|
@@ -117,6 +131,6 @@ See our Wiki page [Getting Started With Matrix & MM Relay](https://github.com/ge
|
|
|
117
131
|
|
|
118
132
|
Join us!
|
|
119
133
|
|
|
120
|
-
- Our project's room: [#mmrelay:
|
|
121
|
-
- Part of the Meshtastic Community Matrix space: [#
|
|
122
|
-
- Public Relay Room: [#relay-room:
|
|
134
|
+
- Our project's room: [#mmrelay:matrix.org](https://matrix.to/#/#mmrelay:matrix.org)
|
|
135
|
+
- Part of the Meshtastic Community Matrix space: [#meshnetclub:matrix.org](https://matrix.to/#/#meshnetclub:matrix.org)
|
|
136
|
+
- Public Relay Room: [#mmrelay-relay-room:matrix.org](https://matrix.to/#/#mmrelay-relay-room:matrix.org) - Where we bridge multiple meshnets. Feel free to join us, with or without a relay!
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# TEMPORARY: Using fork with BLE hanging fix until upstream merge
|
|
2
|
+
# Commit: 33d23e9c28508a740da6567627e42d81552c9b58
|
|
3
|
+
# For PyPI compatibility, setup.py uses upstream meshtastic>=2.6.4
|
|
4
|
+
meshtastic @ git+https://github.com/jeremiah-k/meshtastic-python.git@33d23e9c28508a740da6567627e42d81552c9b58
|
|
5
|
+
Pillow==11.3.0
|
|
6
|
+
matrix-nio==0.25.2
|
|
7
|
+
matplotlib==3.10.1
|
|
8
|
+
requests==2.32.4
|
|
9
|
+
markdown==3.8.2
|
|
10
|
+
haversine==2.9.0
|
|
11
|
+
schedule==1.2.2
|
|
12
|
+
platformdirs==4.3.8
|
|
13
|
+
py-staticmaps>=0.4.0
|
|
14
|
+
rich==14.0.0
|
|
15
|
+
setuptools==80.9.0
|
mmrelay-1.1.0/setup.cfg
ADDED
mmrelay-1.1.0/setup.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from setuptools import find_packages, setup
|
|
2
|
+
|
|
3
|
+
# Read README file with proper resource management
|
|
4
|
+
with open("README.md", encoding="utf-8") as f:
|
|
5
|
+
long_description = f.read()
|
|
6
|
+
|
|
7
|
+
setup(
|
|
8
|
+
name="mmrelay",
|
|
9
|
+
version="1.1.0",
|
|
10
|
+
author="Geoff Whittington, Jeremiah K., and contributors",
|
|
11
|
+
author_email="jeremiahk@gmx.com",
|
|
12
|
+
description="Bridge between Meshtastic mesh networks and Matrix chat rooms",
|
|
13
|
+
long_description=long_description,
|
|
14
|
+
long_description_content_type="text/markdown",
|
|
15
|
+
url="https://github.com/geoffwhittington/meshtastic-matrix-relay",
|
|
16
|
+
project_urls={
|
|
17
|
+
"Bug Tracker": "https://github.com/geoffwhittington/meshtastic-matrix-relay/issues"
|
|
18
|
+
},
|
|
19
|
+
classifiers=[
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Development Status :: 4 - Beta",
|
|
24
|
+
"Topic :: Communications",
|
|
25
|
+
],
|
|
26
|
+
python_requires=">=3.8",
|
|
27
|
+
install_requires=[
|
|
28
|
+
"meshtastic>=2.6.4",
|
|
29
|
+
"Pillow==11.3.0",
|
|
30
|
+
"matrix-nio==0.25.2",
|
|
31
|
+
"matplotlib==3.10.1",
|
|
32
|
+
"requests==2.32.4",
|
|
33
|
+
"markdown==3.8.2",
|
|
34
|
+
"haversine==2.9.0",
|
|
35
|
+
"schedule==1.2.2",
|
|
36
|
+
"platformdirs==4.3.8",
|
|
37
|
+
"py-staticmaps>=0.4.0",
|
|
38
|
+
"rich==14.0.0",
|
|
39
|
+
"setuptools==80.9.0",
|
|
40
|
+
],
|
|
41
|
+
packages=find_packages(where="src"),
|
|
42
|
+
package_dir={"": "src"},
|
|
43
|
+
include_package_data=True,
|
|
44
|
+
package_data={"mmrelay.tools": ["sample_config.yaml"]},
|
|
45
|
+
entry_points={"console_scripts": ["mmrelay = mmrelay.cli:main"]},
|
|
46
|
+
)
|
|
@@ -8,17 +8,57 @@ from mmrelay.log_utils import get_logger
|
|
|
8
8
|
# Global config variable that will be set from main.py
|
|
9
9
|
config = None
|
|
10
10
|
|
|
11
|
+
# Cache for database path to avoid repeated logging and path resolution
|
|
12
|
+
_cached_db_path = None
|
|
13
|
+
_db_path_logged = False
|
|
14
|
+
_cached_config_hash = None
|
|
15
|
+
|
|
11
16
|
logger = get_logger(name="db_utils")
|
|
12
17
|
|
|
13
18
|
|
|
19
|
+
def clear_db_path_cache():
|
|
20
|
+
"""Clear the cached database path to force re-resolution on next call.
|
|
21
|
+
|
|
22
|
+
This is useful for testing or if the application supports runtime
|
|
23
|
+
configuration changes.
|
|
24
|
+
"""
|
|
25
|
+
global _cached_db_path, _db_path_logged, _cached_config_hash
|
|
26
|
+
_cached_db_path = None
|
|
27
|
+
_db_path_logged = False
|
|
28
|
+
_cached_config_hash = None
|
|
29
|
+
|
|
30
|
+
|
|
14
31
|
# Get the database path
|
|
15
32
|
def get_db_path():
|
|
16
33
|
"""
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
34
|
+
Resolve and return the file path to the SQLite database, using configuration overrides if provided.
|
|
35
|
+
|
|
36
|
+
By default, returns the path to `meshtastic.sqlite` in the standard data directory (`~/.mmrelay/data`).
|
|
37
|
+
If a custom path is specified in the configuration under `database.path` (preferred) or `db.path` (legacy),
|
|
38
|
+
that path is used instead. The resolved path is cached for subsequent calls, and the directory is created
|
|
39
|
+
if it does not exist. Cache is automatically invalidated if the relevant configuration changes.
|
|
20
40
|
"""
|
|
21
|
-
global config
|
|
41
|
+
global config, _cached_db_path, _db_path_logged, _cached_config_hash
|
|
42
|
+
|
|
43
|
+
# Create a hash of the relevant config sections to detect changes
|
|
44
|
+
current_config_hash = None
|
|
45
|
+
if config is not None:
|
|
46
|
+
# Hash only the database-related config sections
|
|
47
|
+
db_config = {
|
|
48
|
+
"database": config.get("database", {}),
|
|
49
|
+
"db": config.get("db", {}), # Legacy format
|
|
50
|
+
}
|
|
51
|
+
current_config_hash = hash(str(sorted(db_config.items())))
|
|
52
|
+
|
|
53
|
+
# Check if cache is valid (path exists and config hasn't changed)
|
|
54
|
+
if _cached_db_path is not None and current_config_hash == _cached_config_hash:
|
|
55
|
+
return _cached_db_path
|
|
56
|
+
|
|
57
|
+
# Config changed or first call - clear cache and re-resolve
|
|
58
|
+
if current_config_hash != _cached_config_hash:
|
|
59
|
+
_cached_db_path = None
|
|
60
|
+
_db_path_logged = False
|
|
61
|
+
_cached_config_hash = current_config_hash
|
|
22
62
|
|
|
23
63
|
# Check if config is available
|
|
24
64
|
if config is not None:
|
|
@@ -30,7 +70,12 @@ def get_db_path():
|
|
|
30
70
|
db_dir = os.path.dirname(custom_path)
|
|
31
71
|
if db_dir:
|
|
32
72
|
os.makedirs(db_dir, exist_ok=True)
|
|
33
|
-
|
|
73
|
+
|
|
74
|
+
# Cache the path and log only once
|
|
75
|
+
_cached_db_path = custom_path
|
|
76
|
+
if not _db_path_logged:
|
|
77
|
+
logger.info(f"Using database path from config: {custom_path}")
|
|
78
|
+
_db_path_logged = True
|
|
34
79
|
return custom_path
|
|
35
80
|
|
|
36
81
|
# Check legacy format (db section)
|
|
@@ -41,13 +86,20 @@ def get_db_path():
|
|
|
41
86
|
db_dir = os.path.dirname(custom_path)
|
|
42
87
|
if db_dir:
|
|
43
88
|
os.makedirs(db_dir, exist_ok=True)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
89
|
+
|
|
90
|
+
# Cache the path and log only once
|
|
91
|
+
_cached_db_path = custom_path
|
|
92
|
+
if not _db_path_logged:
|
|
93
|
+
logger.warning(
|
|
94
|
+
"Using 'db.path' configuration (legacy). 'database.path' is now the preferred format and 'db.path' will be deprecated in a future version."
|
|
95
|
+
)
|
|
96
|
+
_db_path_logged = True
|
|
47
97
|
return custom_path
|
|
48
98
|
|
|
49
99
|
# Use the standard data directory
|
|
50
|
-
|
|
100
|
+
default_path = os.path.join(get_data_dir(), "meshtastic.sqlite")
|
|
101
|
+
_cached_db_path = default_path
|
|
102
|
+
return default_path
|
|
51
103
|
|
|
52
104
|
|
|
53
105
|
# Initialize SQLite database
|
|
@@ -30,6 +30,17 @@ log_file_path = None
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
def get_logger(name):
|
|
33
|
+
"""
|
|
34
|
+
Create and configure a logger with console and optional file output, supporting colorized output and log rotation.
|
|
35
|
+
|
|
36
|
+
The logger's level, color usage, and file logging behavior are determined by global configuration and command line arguments. Console output uses rich formatting if enabled. File logging supports log rotation and stores logs in a configurable or default location. The log file path is stored globally if the logger name is "M<>M Relay".
|
|
37
|
+
|
|
38
|
+
Parameters:
|
|
39
|
+
name (str): The name of the logger to create.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
logging.Logger: The configured logger instance.
|
|
43
|
+
"""
|
|
33
44
|
logger = logging.getLogger(name=name)
|
|
34
45
|
|
|
35
46
|
# Default to INFO level if config is not available
|
|
@@ -134,3 +145,48 @@ def get_logger(name):
|
|
|
134
145
|
logger.addHandler(file_handler)
|
|
135
146
|
|
|
136
147
|
return logger
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def setup_upstream_logging_capture():
|
|
151
|
+
"""
|
|
152
|
+
Redirects warning and error log messages from upstream libraries and the root logger into the application's formatted logging system.
|
|
153
|
+
|
|
154
|
+
This ensures that log output from external dependencies (such as "meshtastic", "bleak", and "asyncio") appears with consistent formatting alongside the application's own logs. Only messages at WARNING level or higher are captured, and messages originating from the application's own loggers are excluded to prevent recursion.
|
|
155
|
+
"""
|
|
156
|
+
# Get our main logger
|
|
157
|
+
main_logger = get_logger("Upstream")
|
|
158
|
+
|
|
159
|
+
# Create a custom handler that redirects root logger messages
|
|
160
|
+
class UpstreamLogHandler(logging.Handler):
|
|
161
|
+
def emit(self, record):
|
|
162
|
+
# Skip if this is already from our logger to avoid recursion
|
|
163
|
+
"""
|
|
164
|
+
Redirects log records from external sources to the main logger, mapping their severity and prefixing with the original logger name.
|
|
165
|
+
|
|
166
|
+
Skips records originating from the application's own loggers to prevent recursion.
|
|
167
|
+
"""
|
|
168
|
+
if record.name.startswith("mmrelay") or record.name == "Upstream":
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
# Map the log level and emit through our logger
|
|
172
|
+
if record.levelno >= logging.ERROR:
|
|
173
|
+
main_logger.error(f"[{record.name}] {record.getMessage()}")
|
|
174
|
+
elif record.levelno >= logging.WARNING:
|
|
175
|
+
main_logger.warning(f"[{record.name}] {record.getMessage()}")
|
|
176
|
+
elif record.levelno >= logging.INFO:
|
|
177
|
+
main_logger.info(f"[{record.name}] {record.getMessage()}")
|
|
178
|
+
else:
|
|
179
|
+
main_logger.debug(f"[{record.name}] {record.getMessage()}")
|
|
180
|
+
|
|
181
|
+
# Add our handler to the root logger
|
|
182
|
+
root_logger = logging.getLogger()
|
|
183
|
+
upstream_handler = UpstreamLogHandler()
|
|
184
|
+
upstream_handler.setLevel(logging.WARNING) # Only capture warnings and errors
|
|
185
|
+
root_logger.addHandler(upstream_handler)
|
|
186
|
+
|
|
187
|
+
# Also set up specific loggers for known upstream libraries
|
|
188
|
+
for logger_name in ["meshtastic", "bleak", "asyncio"]:
|
|
189
|
+
upstream_logger = logging.getLogger(logger_name)
|
|
190
|
+
upstream_logger.addHandler(upstream_handler)
|
|
191
|
+
upstream_logger.setLevel(logging.WARNING)
|
|
192
|
+
upstream_logger.propagate = False # Prevent duplicate messages via root logger
|
|
@@ -20,7 +20,7 @@ from mmrelay.db_utils import (
|
|
|
20
20
|
update_shortnames,
|
|
21
21
|
wipe_message_map,
|
|
22
22
|
)
|
|
23
|
-
from mmrelay.log_utils import get_logger
|
|
23
|
+
from mmrelay.log_utils import get_logger, setup_upstream_logging_capture
|
|
24
24
|
from mmrelay.matrix_utils import connect_matrix, join_matrix_room
|
|
25
25
|
from mmrelay.matrix_utils import logger as matrix_logger
|
|
26
26
|
from mmrelay.matrix_utils import on_room_member, on_room_message
|
|
@@ -50,13 +50,12 @@ def print_banner():
|
|
|
50
50
|
|
|
51
51
|
async def main(config):
|
|
52
52
|
"""
|
|
53
|
-
|
|
54
|
-
Includes logic for wiping the message_map if configured in database.msg_map.wipe_on_restart
|
|
55
|
-
or db.msg_map.wipe_on_restart (legacy format).
|
|
56
|
-
Also updates longnames and shortnames periodically as before.
|
|
53
|
+
Sets up and runs the asynchronous relay between Meshtastic and Matrix, managing connections, event handling, and graceful shutdown.
|
|
57
54
|
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
This function initializes the database, configures logging, loads plugins, connects to both Meshtastic and Matrix, joins specified Matrix rooms, and registers event callbacks for message and membership events. It periodically updates node names from the Meshtastic network and manages the Matrix sync loop, handling reconnections and shutdown signals. If configured, it wipes the message map on startup and shutdown.
|
|
56
|
+
|
|
57
|
+
Parameters:
|
|
58
|
+
config: The loaded configuration dictionary containing Matrix, Meshtastic, and database settings.
|
|
60
59
|
"""
|
|
61
60
|
# Extract Matrix configuration
|
|
62
61
|
from typing import List
|
|
@@ -69,6 +68,9 @@ async def main(config):
|
|
|
69
68
|
# Initialize the SQLite database
|
|
70
69
|
initialize_database()
|
|
71
70
|
|
|
71
|
+
# Set up upstream logging capture to format library messages consistently
|
|
72
|
+
setup_upstream_logging_capture()
|
|
73
|
+
|
|
72
74
|
# Check database config for wipe_on_restart (preferred format)
|
|
73
75
|
database_config = config.get("database", {})
|
|
74
76
|
msg_map_config = database_config.get("msg_map", {})
|
|
@@ -131,11 +133,8 @@ async def main(config):
|
|
|
131
133
|
# On Windows, we can't use add_signal_handler, so we'll handle KeyboardInterrupt
|
|
132
134
|
pass
|
|
133
135
|
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
# so its while loop runs in parallel with the matrix sync loop
|
|
137
|
-
# Use "_" to avoid trunk's "assigned but unused variable" warning
|
|
138
|
-
# -------------------------------------------------------------------
|
|
136
|
+
# Start connection health monitoring using getMetadata() heartbeat
|
|
137
|
+
# This provides proactive connection detection for all interface types
|
|
139
138
|
_ = asyncio.create_task(meshtastic_utils.check_connection())
|
|
140
139
|
|
|
141
140
|
# Start the Matrix client sync loop
|