Releases: LN4CY/mqtt-proxy
v1.6.4
v1.6.3
Release v1.6.3
Virtual Channel RF Crosstalk Prevention
This release fixes a critical bug where Virtual Channel packets injected into the local radio (via EXTRA_MQTT_ROOTS) could be decrypted and rebroadcast over RF to nearby nodes, effectively bridging two independent MQTT server regions against the user's intent.
🐛 Bug Fixes
- Fix: Virtual Channel RF Crosstalk (PR #41)
- Root Cause: The radio firmware uses
packet.channel— a PSK hash integer embedded in theServiceEnvelopeprotobuf payload — to look up its decryption key. Because the topic-only rewrite (NC-LongFast) left the original PSK hash intact, the radio could still match its local channel key and decrypt the packet, causing it to rebroadcast over RF. - Fix: The proxy now mutates the
packet.channelfield in the protobuf payload before injecting it into the radio:packet.channel— replaced with a synthetic hash unique to the virtual channel name that no local radio will ever have configured
- The
packet.encryptedbytes and originalchannel_idstring are left completely untouched. MeshMonitor natively decrypts the message using its standard Channel Database. Known Defect: Because the PSK hash is faked, MeshMonitor's "Enforce Channel Name Validation" cannot be used. Consequently, if multiple channels share the exact same key, MeshMonitor will decode and merge their traffic into a single channel display. - Added
INFO-level log entry on every virtual channel rewrite for easy discovery of exact virtual channel names.
- Root Cause: The radio firmware uses
📝 Documentation
- Updated
CONFIG.mdVirtual Channels section to accurately describe the payload mutation mechanism and added MeshMonitor Channel Database setup instructions explaining which channel name and key to configure for each virtual channel.
Release v1.6.2
This release introduces two major new features to handle advanced broker routing and to improve fidelity with Meshtastic node configurations: Virtual Channels (Multi-Root) and Per-Channel Uplink/Downlink Filtering.
✨ New Features
Virtual Channels & Extra MQTT Roots (PR #38)
EXTRA_MQTT_ROOTSConfiguration: You can now configure the proxy to listen to multiple MQTT root topics simultaneously. This allows you to monitor and interact with additional roots seamlessly without complex external broker forwarding rules.- Topic Rewriting: Traffic from extra MQTT roots is automatically rewritten to appear as local "Virtual Channels" (e.g., matching the root name like
NC-LongFast), preventing cross-talk while making remote region traffic accessible in standard clients such as MeshMonitor.
Per-Channel Uplink/Downlink Filtering (PR #37)
- Respect Node Configuration: The proxy now fully parses and respects the per-channel
uplink_enabledanddownlink_enabledsettings configured directly on your physical Meshtastic node. - Selective Forwarding: Only packets on channels explicitly permitted for uplink or downlink will be forwarded between the MQTT broker and the local radio queue, saving serial bandwidth and perfectly matching the firmware's intended behavior.
📝 Documentation
- Documented the new channel-based filtering and extra MQTT roots features.
- Updated configuration documentation (
CONFIG.mdandREADME.md) to clearly explainEXTRA_MQTT_ROOTS.
Release v1.5.3
🚀 New Features
Windows Standalone Executables
- Zero-Setup Windows Deployment: Added an automated PyInstaller build pipeline that compiles
mqtt-proxyinto a standalone, click-and-run.exefor Windows users.- No Python installation or virtual environment is required.
- Windows AMD64 binaries are now automatically generated via GitHub Actions and attached directly to Releases.
- Subprocess-Ready: The executable is specially configured to force line-buffered
stdoutandstderrstreams usingutf-8encoding. This prevents buffering lags andcp1252encoding crashes when embedded and executed natively by external tools or desktop apps on Windows. - Updated configuration documentation to recommend this execution method for easiest integration with the MeshMonitor Desktop App.
Version Tracking & Identification
- Single Source of Truth: Introduced
version.pyto manage the application version globally. - Improved Visibility:
- The binary version is now printed in the startup logs:
🚀 MQTT Proxy v1.5.3 starting.... - Added a
--versionflag to the CLI for quick verification. - Added a version tag to the
README.mdfor consistent project tracking.
- The binary version is now printed in the startup logs:
Command-Line Interface (CLI) Arguments
- Argparse Support: The proxy now fully supports standard command-line flags to configure connection settings directly on launch.
- Supported execution flags:
--interface,--tcp-host,--tcp-port,--serial-port,--log-level, and--version. - Backwards-compatible: Existing environment variables and
.envfiles still function normally as fallbacks for any omitted flags.
- Supported execution flags:
📦 Dependencies
- Bump Meshtastic to 2.7.8: Upgraded python
meshtasticdependency to the latest2.7.8version for compatibility with the newest firmware module configs (e.g. Traffic Management and StatusMessage).
🛠️ Infrastructure & CI/CD
- Docker Build Fixes:
- Fixed a missing build context issue where
version.pywas not copied into the container, preventing the proxy from launching. - Enabled multi-arch (AMD64/Arm64/Armv7) Docker image pushes for internal Pull Requests, allowing real-time testing on devices like Raspberry Pi.
- Fixed a missing build context issue where
- Workflow Optimizations:
- Fixed a "double build" issue in CI by removing redundant triggers on feature branches.
- Resolved
WinError 10106by setting the PyInstaller runtime temporary directory to%LOCALAPPDATA%\Temp. - Added detailed "Releasing New Versions" documentation to guide developers through PR-safe tagging workflows on protected branches.
🧹 Refactoring
- Simplify Echo Bypass: Cached prefixed node ID and cleaned up the
_on_messageboolean logic structure. Thank you @NearlCrews!
Release v1.4.2
🐛 Bug Fixes
Echo Bypass is Too Broad (Issue #25)
- Narrowed Implicit ACK Echo Bypass: Fixed an issue where the loop prevention bypass was too broad, causing unencrypted routing, position, and telemetry packets to echo back to the node unnecessarily.
- Instead of bypassing loop protection for all packets from the local gateway, the proxy now explicitly checks if the packet is
encryptedor has a validrequest_id. - Administrative/plain packets are properly dropped by the loop tracker to minimize unnecessary RF traffic.
- Instead of bypassing loop protection for all packets from the local gateway, the proxy now explicitly checks if the packet is
🧪 Test Coverage
- Added new test cases in
tests/test_echo_bypass.pyto ensure only correct packet types (encrypted, request_id) explicitly bypass loop prevention.
Full Changelog: v1.4.1...v1.4.2
Release v1.4.1
🐛 Bug Fixes
"Proxy to Client" Ack Restoration (The "Red X" Fix)
- Implicit ACK Echoes: Fixed a critical bug where
mqtt-proxy's strict loop protection dropped echoed messages from the MQTT Broker.- When the Meshtastic firmware has
proxy_to_client_enabled: trueset, it stops generating automatic "Implicit ACKs" for transmissions. - Instead, the firmware expects the MQTT broker to echo the message back so it knows it was successfully delivered.
- By bypassing the deduplicator specifically for echoed messages (where
gateway_idmatches the local node ID), the firmware now receives the delivery confirmation it needs. - This prevents
MAX_RETRANSMITtimeouts and fixes the "Red X" (Failed delivery status) issue in MeshMonitor for both DMs and Channel Broadcasts.
- When the Meshtastic firmware has
📝 Documentation
- CONFIG.md: Added warnings and explanations around the
proxy_to_client_enabledsetting and how it alters firmware timeout behavior. - README.md: Added "Implicit ACK Restoration" to the core features list and clarified the Architecture section's "How It Works".
Full Changelog: v1.3.0...v1.4.0
Release v1.3.0
🐛 Bug Fixes
Missed Messages (False Positive ACKs)
- Ignored Implicit ACKs from Self/Local: Fixed an issue where local routing confirmation packets were incorrectly interpreted as successful delivery acknowledgments from remote nodes.
- The proxy now explicitly checks the
senderofROUTING_APPpackets. - Packets where
sender == 0(local routing confirmation) are ignored. - Packets where
sender == myNodeNum(echoes from self) are ignored. - This ensures
meshtastic.ackevents are only emitted for high-confidence confirmations, improving message reliability logic.
- The proxy now explicitly checks the
🧪 Test Coverage
- Added new unit tests in
tests/test_meshtastic_extended.pyto verify implicit ACK suppression for self and sender 0.
Full Changelog: v1.2.0...v1.3.0
Release v1.2.0
🛡️ Reliability & Stability Improvements
Thread-Safe Radio Interactions
- Locked Radio Access: Implemented thread-safe
_sendToRadiousing the interface's internal locking mechanism.- Prevents potential race conditions when multiple handlers attempt to send data to the radio simultaneously.
- Added fallback with warning if
_sendToRadiois missing (e.g., in oldermeshtasticlibrary versions).
Enhanced Packet Management
- Improved Deduplication: Refined the deduplication logic to better handle packet IDs and sender tracking.
- Prevents message loops when proxying traffic between MQTT and the mesh network.
Robust Health Monitoring
- Configuration Race Condition Fix: Addressed a race condition in MQTT handler initialization to ensure reliable startup and state management.
- Improved Health Checks: Enhanced watchdog mech...
v1.6.2
This release introduces two major new features to handle advanced broker routing and to improve fidelity with Meshtastic node configurations: Virtual Channels (Multi-Root) and Per-Channel Uplink/Downlink Filtering.
✨ New Features
Virtual Channels & Extra MQTT Roots (PR #38)
EXTRA_MQTT_ROOTSConfiguration: You can now configure the proxy to listen to multiple MQTT root topics simultaneously. This allows you to monitor and interact with additional roots seamlessly without complex external broker forwarding rules.- Topic Rewriting: Traffic from extra MQTT roots is automatically rewritten to appear as local "Virtual Channels" (e.g., matching the root name like
NC-LongFast), preventing cross-talk while making remote region traffic accessible in standard clients such as MeshMonitor.
Per-Channel Uplink/Downlink Filtering (PR #37)
- Respect Node Configuration: The proxy now fully parses and respects the per-channel
uplink_enabledanddownlink_enabledsettings configured directly on your physical Meshtastic node. - Selective Forwarding: Only packets on channels explicitly permitted for uplink or downlink will be forwarded between the MQTT broker and the local radio queue, saving serial bandwidth and perfectly matching the firmware's intended behavior.
📝 Documentation
- Documented the new channel-based filtering and extra MQTT roots features.
- Updated configuration documentation (
CONFIG.mdandREADME.md) to clearly explainEXTRA_MQTT_ROOTS.
v1.5.3
🚀 New Features
Windows Standalone Executables
- Zero-Setup Windows Deployment: Added an automated PyInstaller build pipeline that compiles
mqtt-proxyinto a standalone, click-and-run.exefor Windows users.- No Python installation or virtual environment is required.
- Windows AMD64 binaries are now automatically generated via GitHub Actions and attached directly to Releases.
- Subprocess-Ready: The executable is specially configured to force line-buffered
stdoutandstderrstreams usingutf-8encoding. This prevents buffering lags andcp1252encoding crashes when embedded and executed natively by external tools or desktop apps on Windows. - Updated configuration documentation to recommend this execution method for easiest integration with the MeshMonitor Desktop App.
Version Tracking & Identification
- Single Source of Truth: Introduced
version.pyto manage the application version globally. - Improved Visibility:
- The binary version is now printed in the startup logs:
🚀 MQTT Proxy v1.5.3 starting.... - Added a
--versionflag to the CLI for quick verification. - Added a version tag to the
README.mdfor consistent project tracking.
- The binary version is now printed in the startup logs:
Command-Line Interface (CLI) Arguments
- Argparse Support: The proxy now fully supports standard command-line flags to configure connection settings directly on launch.
- Supported execution flags:
--interface,--tcp-host,--tcp-port,--serial-port,--log-level, and--version. - Backwards-compatible: Existing environment variables and
.envfiles still function normally as fallbacks for any omitted flags.
- Supported execution flags:
📦 Dependencies
- Bump Meshtastic to 2.7.8: Upgraded python
meshtasticdependency to the latest2.7.8version for compatibility with the newest firmware module configs (e.g. Traffic Management and StatusMessage).
🛠️ Infrastructure & CI/CD
- Docker Build Fixes:
- Fixed a missing build context issue where
version.pywas not copied into the container, preventing the proxy from launching. - Enabled multi-arch (AMD64/Arm64/Armv7) Docker image pushes for internal Pull Requests, allowing real-time testing on devices like Raspberry Pi.
- Fixed a missing build context issue where
- Workflow Optimizations:
- Fixed a "double build" issue in CI by removing redundant triggers on feature branches.
- Resolved
WinError 10106by setting the PyInstaller runtime temporary directory to%LOCALAPPDATA%\Temp. - Added detailed "Releasing New Versions" documentation to guide developers through PR-safe tagging workflows on protected branches.
🧹 Refactoring
- Simplify Echo Bypass: Cached prefixed node ID and cleaned up the
_on_messageboolean logic structure. Thank you @NearlCrews!
v1.5.2
🚀 New Features
Windows Standalone Executables
- Zero-Setup Windows Deployment: Added an automated PyInstaller build pipeline that compiles
mqtt-proxyinto a standalone, click-and-run.exefor Windows users.- No Python installation or virtual environment is required.
- Windows AMD64 binaries are now automatically generated via GitHub Actions and attached directly to Releases.
- Subprocess-Ready: The executable is specially configured to force line-buffered
stdoutandstderrstreams usingutf-8encoding. This prevents buffering lags andcp1252encoding crashes when embedded and executed natively by external tools or desktop apps on Windows. - Updated configuration documentation to recommend this execution method for easiest integration with the MeshMonitor Desktop App.
Version Tracking & Identification
- Single Source of Truth: Introduced
version.pyto manage the application version globally. - Improved Visibility:
- The binary version is now printed in the startup logs:
🚀 MQTT Proxy v1.5.2 starting.... - Added a
--versionflag to the CLI for quick verification. - Added a version tag to the
README.mdfor consistent project tracking.
- The binary version is now printed in the startup logs:
Command-Line Interface (CLI) Arguments
- Argparse Support: The proxy now fully supports standard command-line flags to configure connection settings directly on launch.
- Supported execution flags:
--interface,--tcp-host,--tcp-port,--serial-port,--log-level, and--version. - Backwards-compatible: Existing environment variables and
.envfiles still function normally as fallbacks for any omitted flags.
- Supported execution flags:
📦 Dependencies
- Bump Meshtastic to 2.7.8: Upgraded python
meshtasticdependency to the latest2.7.8version for compatibility with the newest firmware module configs (e.g. Traffic Management and StatusMessage).
🛠️ Infrastructure & CI/CD
- Docker Build Fixes:
- Fixed a missing build context issue where
version.pywas not copied into the container, preventing the proxy from launching. - Enabled multi-arch (AMD64/Arm64/Armv7) Docker image pushes for internal Pull Requests, allowing real-time testing on devices like Raspberry Pi.
- Fixed a missing build context issue where
- Workflow Optimizations:
- Fixed a "double build" issue in CI by removing redundant triggers on feature branches.
- Resolved
WinError 10106by setting the PyInstaller runtime temporary directory to%LOCALAPPDATA%\Temp. - Added detailed "Releasing New Versions" documentation to guide developers through PR-safe tagging workflows on protected branches.
🧹 Refactoring
- Simplify Echo Bypass: Cached prefixed node ID and cleaned up the
_on_messageboolean logic structure. Thank you @NearlCrews!
What's Changed
Full Changelog: v1.5.1...v1.5.2
v1.5.1
🚀 New Features
Windows Standalone Executables
- Zero-Setup Windows Deployment: Added an automated PyInstaller build pipeline that compiles
mqtt-proxyinto a standalone, click-and-run.exefor Windows users.- No Python installation or virtual environment is required.
- Windows AMD64 binaries are now automatically generated via GitHub Actions and attached directly to Releases.
- Subprocess-Ready: The executable is specially configured to force line-buffered
stdoutandstderrstreams usingutf-8encoding. This prevents buffering lags andcp1252encoding crashes when embedded and executed natively by external tools or desktop apps on Windows. - Updated configuration documentation to recommend this execution method for easiest integration with the MeshMonitor Desktop App.
Version Tracking & Identification
- Single Source of Truth: Introduced
version.pyto manage the application version globally. - Improved Visibility:
- The binary version is now printed in the startup logs:
🚀 MQTT Proxy v1.5.1 starting.... - Added a
--versionflag to the CLI for quick verification. - Added a version tag to the
README.mdfor consistent project tracking.
- The binary version is now printed in the startup logs:
Command-Line Interface (CLI) Arguments
- Argparse Support: The proxy now fully supports standard command-line flags to configure connection settings directly on launch.
- Supported execution flags:
--interface,--tcp-host,--tcp-port,--serial-port,--log-level, and--version. - Backwards-compatible: Existing environment variables and
.envfiles still function normally as fallbacks for any omitted flags.
- Supported execution flags:
📦 Dependencies
- Bump Meshtastic to 2.7.8: Upgraded python
meshtasticdependency to the latest2.7.8version for compatibility with the newest firmware module configs (e.g. Traffic Management and StatusMessage).
🛠️ Infrastructure & CI/CD
- Docker Build Fixes:
- Fixed a missing build context issue where
version.pywas not copied into the container, preventing the proxy from launching. - Enabled multi-arch (AMD64/Arm64/Armv7) Docker image pushes for internal Pull Requests, allowing real-time testing on devices like Raspberry Pi.
- Fixed a missing build context issue where
- Workflow Optimizations:
- Fixed a "double build" issue in CI by removing redundant triggers on feature branches.
- Resolved
WinError 10106by setting the PyInstaller runtime temporary directory to%LOCALAPPDATA%\Temp. - Added detailed "Releasing New Versions" documentation to guide developers through PR-safe tagging workflows on protected branches.
🧹 Refactoring
- Simplify Echo Bypass: Cached prefixed node ID and cleaned up the
_on_messageboolean logic structure. Thank you @NearlCrews!
What's Changed
- feat: automate release notes extraction by @LN4CY in #29
- fix: automated release notes extraction in CI by @LN4CY in #30
- Release v1.5.1 by @LN4CY in #31
Full Changelog: v1.5.0...v1.5.1
v1.5.0
What's Changed
- refactor: simplify echo bypass logic and cache prefixed node ID by @NearlCrews in #27
- feat: Windows Executable Action and CLI args by @LN4CY in #28
New Contributors
- @NearlCrews made their first contribution in #27
Full Changelog: v1.4.2...v1.5.0
v1.4.2
🐛 Bug Fixes
Echo Bypass is Too Broad (Issue #25)
- Narrowed Implicit ACK Echo Bypass: Fixed an issue where the loop prevention bypass was too broad, causing unencrypted routing, position, and telemetry packets to echo back to the node unnecessarily.
- Instead of bypassing loop protection for all packets from the local gateway, the proxy now explicitly checks if the packet is
encryptedor has a validrequest_id. - Administrative/plain packets are properly dropped by the loop tracker to minimize unnecessary RF traffic.
- Instead of bypassing loop protection for all packets from the local gateway, the proxy now explicitly checks if the packet is
🧪 Test Coverage
- Added new test cases in
tests/test_echo_bypass.pyto ensure only correct packet types (encrypted, request_id) explicitly bypass loop prevention.
Full Changelog: v1.4.1...v1.4.2
v1.4.1
Release v1.4.1
🐛 Bug Fixes
"Proxy to Client" Ack Restoration (The "Red X" Fix)
- Implicit ACK Echoes: Fixed a critical bug where
mqtt-proxy's strict loop protection dropped echoed messages from the MQTT Broker.- When the Meshtastic firmware has
proxy_to_client_enabled: trueset, it stops generating automatic "Implicit ACKs" for transmissions. - Instead, the firmware expects the MQTT broker to echo the message back so it knows it was successfully delivered.
- By bypassing the deduplicator specifically for echoed messages (where
gateway_idmatches the local node ID), the firmware now receives the delivery confirmation it needs. - This prevents
MAX_RETRANSMITtimeouts and fixes the "Red X" (Failed delivery status) issue in MeshMonitor for both DMs and Channel Broadcasts.
- When the Meshtastic firmware has
📝 Documentation
- CONFIG.md: Added warnings and explanations around the
proxy_to_client_enabledsetting and how it alters firmware timeout behavior. - README.md: Added "Implicit ACK Restoration" to the core features list and clarified the Architecture section's "How It Works".
Release v1.3.0
🐛 Bug Fixes
Missed Messages (False Positive ACKs)
- Ignored Implicit ACKs from Self/Local: Fixed an issue where local routing confirmation packets were incorrectly interpreted as successful delivery acknowledgments from remote nodes.
- The proxy now explicitly checks the
senderofROUTING_APPpackets. - Packets where
sender == 0(local routing confirmation) are ignored. - Packets where
sender == myNodeNum(echoes from self) are ignored. - This ensures
meshtastic.ackevents are only emitted for high-confidence confirmations, improving message reliability logic.
- The proxy now explicitly checks the
🧪 Test Coverage
- Added new unit tests in
tests/test_meshtastic_extended.pyto verify implicit ACK suppression for self and sender 0.
Full Changelog: v1.2.0...v1.3.0