Skip to content

Fixing connect/disconnect and adding UI elements - connect/disconnect buttons and status indicator#155

Open
mspnr wants to merge 7 commits into
OctoPrint:masterfrom
mspnr:master
Open

Fixing connect/disconnect and adding UI elements - connect/disconnect buttons and status indicator#155
mspnr wants to merge 7 commits into
OctoPrint:masterfrom
mspnr:master

Conversation

@mspnr
Copy link
Copy Markdown

@mspnr mspnr commented Oct 16, 2025

This PR addresses the issue where OctoPrint-MQTT fails to reconnect after the MQTT broker (Home Assistant) restarts. See #151

Note: It was also requested to merge with devel branch, but it is 14 commit behind master, so I am not sure it makes sense.

Bug Fixes

1. Fixed MQTT disconnect/reconnect logic

  • Problem: The mqtt_disconnect() method never called self._mqtt.disconnect(), so the broker didn't receive a
    proper disconnect packet. This caused reconnection attempts to fail because the broker thought the client was still
    connected.
  • Solution:
  • Added self._mqtt.disconnect() call before stopping the network loop

2. Fixed invalid topic subscription error

  • Problem: When reconnecting, the plugin attempted to subscribe to topics from the subscription list, but some
    entries had invalid/empty topic values, causing a ValueError: Invalid topic exception. This prevented
    _mqtt_connected from being set to True.
  • Solution:
  • Added filtering to exclude invalid topics (None or empty strings) before subscribing
  • Added exception handling in _on_mqtt_connect() to log errors without breaking the connection

New Features

Added manual Connect/Disconnect controls in settings UI

  • Added Connection Status indicator showing real-time connection state (Connected/Disconnected)
  • Added Disconnect button (red) to manually disconnect from broker
  • Added Connect button (green) to manually reconnect to broker
  • Implemented SimpleApiPlugin with admin-only API endpoints:
  • POST /api/plugin/mqtt with command connect - initiates connection
  • POST /api/plugin/mqtt with command disconnect - disconnects from broker
  • GET /api/plugin/mqtt - returns current connection status
  • Connection status uses is_connected() from Paho MQTT client for accurate real-time status

Benefits

  • Users can now manually reconnect to MQTT broker after Home Assistant restarts without restarting OctoPrint
  • Visual feedback shows current connection state
  • Proper disconnect/reconnect sequence ensures clean broker sessions
  • Admin-only API access ensures security

Screenshots

image image

mspnr added 3 commits October 16, 2025 18:39
	- Filter out None/empty topics before subscribing
	- Add exception handling in _on_mqtt_connect() callback
- Add Connect and Disconnect buttons in MQTT settings
- Add connection status indicator (Connected/Disconnected)
- Implement SimpleApiPlugin with admin-only endpoints:
	- POST /api/plugin/mqtt command=connect
	- POST /api/plugin/mqtt command=disconnect
	- GET /api/plugin/mqtt (returns connection status)
- Add is_api_protected() and is_api_adminonly() for API security
Copy link
Copy Markdown
Collaborator

@jneilliii jneilliii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution, just a couple of code comments.

Comment thread octoprint_mqtt/__init__.py Outdated
Comment thread octoprint_mqtt/__init__.py Outdated
…ailability

    - Update setup.py: change "paho-mqtt<2" to "paho-mqtt>=1.4.0,<2"

  - Remove unnecessary exception handling in on_api_get()
    - is_connected() is now guaranteed to be available
    - Simplify code by removing try/except fallback logic

  - Replace bare exception handling with explicit is_connected() checks
    - mqtt_disconnect(): check connection before calling disconnect()
    - Add connection check before publishing Last Will Testament
    - Eliminates bare except: clauses that could hide unexpected errors
@mspnr
Copy link
Copy Markdown
Author

mspnr commented Oct 17, 2025

@jneilliii added 200d681 according to your suggestions:

Changes Made

Thank you for the review feedback! I've addressed both suggestions:

1. Dependency Management

Pinned minimum paho-mqtt version to 1.4.0 (when is_connected() was introduced)

  • Updated setup.py: "paho-mqtt>=1.4.0,<2"
  • This ensures the method is always available without needing fallback logic

2. Proper Use of is_connected()

Removed bare exception handling and replaced with explicit connection checks:

In on_api_get() (lines 386-397):

  • Removed try/except wrapper around is_connected() call
  • No longer needed since we guarantee paho-mqtt >= 1.4.0

In mqtt_disconnect() (lines 456-476):

  • Replaced try: self._mqtt.disconnect() except: pass with if self._mqtt.is_connected(): self._mqtt.disconnect()
  • Added connection check before publishing LWT message
  • Prevents unnecessary operations when already disconnected

Why Option A (1.4.0+) vs Option B (2.x)?

I chose the conservative approach to maintain Python 2.7+ compatibility as specified in
__plugin_pythoncompat__. If you prefer upgrading to paho-mqtt 2.x, I can update the Python compatibility
requirement as well.

These changes eliminate bare exception handling while maintaining backward compatibility. Ready for another review!

@jneilliii
Copy link
Copy Markdown
Collaborator

@Kunsi I don't see any other code issues related to this PR, but haven't tested yet. I feel like there could be some changes to how the connect/disconnect buttons and connection status area are handled to utilize ko bindings instead of DOM manipulation via js, but technically should still work as-is in this PR.

  - Replace jQuery DOM manipulation with ko.observables
  - Add computed observables for connection status and button states
  - Update template to use data-bind attributes instead of IDs
  - Remove all $("#...") selectors from mqtt.js
@mspnr
Copy link
Copy Markdown
Author

mspnr commented Oct 17, 2025

Testing and bonus effects

Every time before pushing commits I test the function on my instance of OctoPrint.

Moreover - after making these changes - OctoPrint keeps connection even after restart of Home Assistant, issue described here #151

DOM manipulation vs ko bindings

As I understood you have concern about this commit 2a74c82 . Fair enough - I improved the situation here: 70514e3

I've refactored the connect/disconnect buttons and connection status to use ko.observables and computed observables
instead of jQuery DOM manipulation. The changes include:

  • Added observables: isConnected, isConnecting, isDisconnecting
  • Created computed observables for status HTML and button states
  • Removed all $("#...") selectors and direct DOM manipulation
  • Updated template to use data-bind attributes

The UI now follows OctoPrint's standard ViewModel patterns and is more maintainable. All functionality remains the
same - just implemented properly with reactive bindings.

@jneilliii
Copy link
Copy Markdown
Collaborator

I made some adjustments to AI's disable button observables to include isConnected() checks in mspnr@b3802b8. One last issue I notice is that the connection state isn't getting updated in the front-end when the back-end loses the connection to the broker. To test this yourself, be in a connected state and stop your MQTT broker. The plugin will lose it's connection but the UI still thinks it's connected. Same for when you start the broker back up and plugin is in disconnected state.

image

Probably need to add a self._plugin_manager.send_plugin_message(self._identifier, {"connected": False}) to _on_mqtt_disconnect function and self._plugin_manager.send_plugin_message(self._identifier, {"connected": True}) to the _on_mqtt_connect function and call the newly added updateConnectionStatus with data.connected payload.

@mspnr
Copy link
Copy Markdown
Author

mspnr commented Oct 20, 2025

Thank you for improving buttons behavior!

I added sync MQTT connection status between backend and frontend and also tested that. It is working just fine. Actually pressing connect is not needed anymore, because my tests showed, that OctoPrint always connected back to the broker as soon as it became available again. I would keep Connect/Disconnect buttons for debugging or testing edge cases in configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants