[Idea] Air Quality / Health Impact Plugin - HELP WANTED!

You're not wrong, and that's definitely something worth doing for those more technically able, but I'm really aiming for any 3D printer user with this project. End goal would be a single purchase (maybe a bundle from an AliExpress seller) that a user just plugs into their Pi, and with a couple clicks they're ready to go.

1 Like

Just had a look at the tasmota plugin, isn't it just for sonoff power control?

The newer versions can read/graph sensor data, and power data.

this mentions hepa filter types useful down to 0.1-0.2μm
(i have no clue what i am looking at just saw the number in the middle of the screen)

Can you indicate where you saw this? HEPA filter types have lots of designations. For example, the N95 is a common one you'll find for use in shop vacuum cleaners as well as home vacuum cleaners. You'll also see this same rating for home air filters.

This particular one traps a high percentage of particles 0.3μm or larger. Note that my third-world quality water filter is a 0.2μm filter and yet water passes through it. The definition of UFP means that they're very small indeed. It's suggested in an earlier article that they're smaller than the typical 0.3μm filter in use in many HEPA-certified devices.

Has anyone built a plugin that reads sensors before? I could use some advice:

When/where do I instantiate a SensorManager object that will manage all of the sensors? In plugin_load?
The SensorManager will be responsible for getting the settings that define the sensor(s), checking if they're valid, then looping through the sensors to get readings. How do I make this happen continuously in the background? Do I need to learn about threading in Python, or are plugins already handled this way?

I've had a look at the SDS plugin and the Enclosure plugin, but without guidance I just can't figure this out.

Loads more questions, but I'm starting super simple. Disappointed but not surprised that very few people are interested in a project that might expose a negative health impact from their favourite hobby :slightly_frowning_face: so I'm struggling on with this myself.

I take it that you're perhaps here in the documentation. You could instantiate your SensorManager object here.

If you're going to loop through things in an almost-endless loop you may want to consider creating things in a function and then using Python's threading to start that function in a thread. Your main thread then would probably be more responsive to OctoPrint.

You might review the CookieCutter part of getting started. It will bring more things together so that you have code more suitable for publishing later on.

You might also look at one of the filament runout sensor plugins. My assumption those would be way simpler to start off with from an understanding perspective.

I would think that doing the polling of sensor data would be best served by reacting to temperature events and print progress events so I would focus my efforts on reading the docs for ProgressPlugin mixin and octoprint.comm.protocol.temperatures.received hook. Then throw the looping/polling into it's own thread.

1 Like

@stringonfire, this plugin might actually be a huge help to you in your adventure.

Thanks, that was helpful, I've added some basics for the threading/reading now.

Started the settings based on the TP Link Smart Plug plugin, as I'll need something similar to add multiple devices. Done a KO tutorial so I understand what I'm looking at, but struggling to get it working. At the moment, the "Add" button on the table in the Plugin Settings just doesn't do anything. If anyone has time time to see if I've done something stupid, that'd be great! https://github.com/stantond/OctoPrint-AirQuality/tree/develop

Look inside your browser's developer console for binding errors, chrome is best for this.

Thanks - it was a stupid mistake...

Got a question on the TP Link plugin. Now I've adapted how the settings work... the data model (representing a Smart Plug or Sensor) is in the View-Model. Isn't it best practice to have the data model as a Python class, separating the data model from the view model? Assuming plugins are meant to be MVVM. This also explains the slightly odd way of adding and editing items, all instant rather than only submitting changes once a form is submitted.

I get the feeling I'll need to learn to implement OctoPrint/Flask APIs to actually do it this way though, with the Knockout mapping plugin

So for the graphing on that one the data model is stored on the back end in a sqlite database. The python side tells the javascript side that there is an update, refresh your data, and the the javascript side calls a SimpleApiPlugin mixin implementation to grab the data to display and uses the returned data in the graph.

You could probably take out the middle man javascript side that tells the javascript side to do the work, and either just tell the javascript side of updated data (send_plugin_message) and graph that, or have your javascript side poll the SimpleApiPlugin implementation and retrieve the data using a setInterval.

Admittedly I didn't get that far - I'm still on Settings. I was thinking something like a Device python class, with one Device object per physical device to contain both the active configuration/settings for that device and any other non-settings data, like "detected" or "state". Storing/loading from settings would be part of Device or DeviceManager. But to do this, I'd need an API that the frontend could call to create, edit and delete, rather than just creating them in the FE using KO as you've done with Smart Plug settings. Not sure if it's really worth the effort.

I haven't personally tried it but that is what I believe the on_settings_load callback is for. Either that or get_settings_preprocessors maybe.

I was overthinking it - I've made some progress on https://github.com/stantond/OctoPrint-AirQuality/tree/develop but I'm getting stuck on the dictionary. I'm trying to do this:

  • Maintain a single dictionary of sensor models with friendly names (currently in the view model)
  • Show the friendly name in the settings drop down, while saving the model number (working for add, but the way I'm adding an observableArray just to pass these values through in addDevice then removing them again in addDeviceToSettings feels like a botch, and it won't work for edit, so I'm definitely doing this wrong)
  • Show the friendly name in the table that lists all existing sensors (totally struggling with this)

Any pointers would be really helpful!

Is it because your mappedDictionary function is returning non-observables? You may want to check out some of the hints on this article if you haven't already seen it.


I tried installing to understand better what you were talking about but am getting this error on startup.

probably because it's in windows and the pyserial dependency doesn't load?