OctoPrint considers serial port as the printer until proven otherwise in new auto-detect

I've been developing this Air Quality / Health Impact Plugin for a while on and off. After updating from OctoPrint 1.4.0 to 1.4.2, I'm finding that, without a printer port set, OctoPrint is assuming that another serial port is the printer until it proves it isn't, which means my plugin can't build its list of serial sensors (I've made it ignore the printer port so it doesn't cause issues) on startup, and it doesn't return the port until later, so I'm currently needing to manually trigger a refresh of the sensor initialisation.

How can I solve this? Is there a way I can listen for when OctoPrint is done testing the serial ports to find a printer, and then do my sensor initialisation? Am I still using a sensible method to exclude the printer port? Is this going to change again over the next few releases?

This self._printer.get_current_connection()[1] is how I've been detecting the printer port in https://github.com/stantond/OctoPrint-AirQuality/blob/3d7fbd5c87806f5b6e010927e195cfc54fe61614/octoprint_airquality/SensorsManager.py#L89

Can you elaborate on what precisely you are seeing? The way auto detection works is that OctoPrint iterates over all serial ports that match its patterns, and then on those tries to get a handshake to complete on 250000 and 115200 baud (or the specified one if the user selected one). The only time that OctoPrint will "consider a port a printer" is when it is actively connected to it. That's also the only time it exclusively locks the port (unless that is disabled), in order to reduce the likelihood of horrible things from happening if something else tries to concurrently access the serial port.

When I start octoprint with no printer plugged in and one sensor on COM4, when I first read self._printer.get_current_connection()[1], then the value is COM4. When I check this value again once I know the auto-detect process has finished, it is cleared/no longer COM4, but by that point I've already assumed COM4 is the printer port and excluded it.

I think I need a way to start my sensor detection after OctoPrint is sure what the printer port is, or is sure that there is not a printer connected. I'm currently doing this on_after_startup here but it seems that's still too soon.

Hook into connection events:

https://docs.octoprint.org/en/master/events/index.html#printer-communication

via the EventHandlerPlugin mixin:

https://docs.octoprint.org/en/master/plugins/mixins.html#eventhandlerplugin

I could rebuild the sensor list after each Connected event instead of on_after_startup, but what about when auto-detect finishes after it cannot detect a printer? Is there an event for this?

Hook into the printer state change event, detect when it switches to detection state, set a timer, if it never connects even after x seconds you have your answer.

edit better even: you should see the full state cycle in that event hook that you also see in the state panel in the UI. If auto connect fails, the state goes back to a disconnected one. You can react to that.

1 Like

Using the PrinterStateChanged event, I can see the states going through DETECT_SERIAL to ERROR to OFFLINE, so I could run this on OFFLINE, but looking at the possible values in get_state_id() there isn't a CONNECTED value. Is this just missing in the docs, or is PrinterStateChanged missing this state? I know there's a separate connected event, but feels like that shouldn't matter regarding PrinterStateChanged.

Sorry, ignore that, you'd need to add port to the payload when state_id is CONNECTED, so while it might make sense to add CONNECTED to PrinterStateChanged, most use cases would still need the Connected event with the new port anyway.

The real problem I'm having is that, during auto-detect, get_current_connection()[1] returns a port that is not the printer port, which I assume means that whatever underlying variable stores the actual printer port is being used during autodetect process before octoprint is sure if the port is correct or not, but I'm struggling to find the autodetect code that does this to confirm. Would be helpful if get_current_connection() represented the uncertainty by returning None during autodetection, rather than giving what might be an incorrect port, or if the underlying variable used for autodetect was separate from the variable used to represent a confirmed printer port. Pretty sure this is new behaviour in 1.4.1 or 1.4.2, because I never previously got an incorrect port back from get_current_connection() during autodetect.