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

Sorry, fixed. Was missing another dependency, and needed to prevent the sensor part from running until I'm ready to integrate it with the new settings format. Should work now!

The biggest problem I'm having at the moment is how to show the friendly name of devices in the add/edit modals and in the table in settings, but store the model code (which will be needed to load the correct configuration for the sensor library I plan to add later).

Well, it looks like the add/edit is working just fine with the select list for me.

As for the table list, I think all you need to do is create a new function to bind to that translates the model to friendly name, something like this...

self.lookup_device = function(model) {
    return self.supportedDevices[model];
}

then in your jinja template bind to data-bind="text: lookup_device(model())"

At least, I think that will work.

BTW, you should either change the button classes in your view model or bundle fontawesome 5...it's probably looking ok for you because you have one of my plugins installed that bundles it.

Just played with the edit a little more and it appears that you're causing duplication rather than editing, so long way to go there. I would change the "Add" button in the editor to be Save from a UI perspective. Take out this data-bind="click: $root.addDeviceToSettings" from the button too, that's causing the duplicates and might resolve the model issue.

Thanks for that! I couldn't figure out the right way to reference the function and pass the model in the data-bind (I'm new to JS). Fixed the icons too.

I'm fighting with Edit at the moment. I'm trying to load in the values, then let you edit them as a new object so you can either apply them when happy or discard them if not when you close the modal, but I'm having trouble updating the values. I think it's more referencing trouble

Yeah, that might be difficult because of the way knockout bindings reference each other when you put them in a new observable (selectedDevice). It might be hard to see but because you are passing observable (device) in that selectedDevice there is a link between the data in the table on the list and in the data in the editor. You might be able to use a ko.toJS(device) approach to maybe get around that linking.

Edit is now working.

On start up and when the printer connection port changes, SensorManager now builds a new serial_ports list of objects representing each port (excluding the printer port). I need to get that that serial_ports list to the client side so that it can be a KO observable and be used in the settings...

Anyone know of any examples of something similar - getting plugin variables through from python through to the view? I can't spot a ViewModel that does this, but also unsure how to create my own (if that's even what's needed here)

send_plugin_message is one way to send the data from python to javascript and assign it to the observable.

https://docs.octoprint.org/en/master/modules/plugin.html

Or use ajax api calls to your javascript and implement simpleapiplugin mixin. Didn't I pray that before, seems familiar...

Thanks, I've got that sending an updated dict of serial devices to the client on printer connection now.

Next I'll make the serial port selectable in the settings, then show additional info about the connected serial port, then an API so you can manually refresh the devices from the settings page, and then a way to activate/deactivate a device based on whether or not the COM port is available.

There's a lot more to this than I thought.

It's all about familiarity with the framework. I've done 36+ plugins and still am learning new stuff.

Made some progress on settings, but I'm stuck on this:

  1. Add a device with a port selected, and save.
  2. Edit that device.
  3. Unplug the port
  4. Click the refresh button

What should happen is that, as the selected port is no longer in the list of found serial ports, it is re-added by the computed KO serialPortsListEdit, and still available as an option in the Edit modal (once this is working, I can add a warning, this way you don't lose your ports if you know it's only temporarily unavailable).

Watching the console as I log these values, it does work once - I can see the saved port re-added to the array of available ports after it's not found from the latest refresh, but the computed variable computers twice in a row, and on the second time it loses the old port value. I think I understand why it computes twice (there are two observables used for the compute that have changed), but I cannot figure out why the re-added port is no longer treated as the selected value after the first time, and consequently lost the second time.

Have you seen anything like this before? Any ideas?

See if this makes a difference. You can use a compare to see the changes in github. I don't have any of these devices, or a Py3 environment on a pi to test.

I've made a few more changes to make it clearer what's happening because I don't think I explained it very well. Console breakdown:

I believe that when the select field options (serialPortsListEdit) are changed after the 3rd compute, the select field is deselecting COM4 as the value, even through the above proves it's still in the bound options list at that point.

The deselect would explain the 4th compute (as there's a change to selectedDevice, the other KO variable used in the compute), and consequently the end result.

I'm not sure how to break this down any further. My only guesses are either that the re-added "COM4" in the array is somehow different to the original COM4 in the array (they should both just be identical strings?), so the Select field doesn't recognise it as the same option and cannot keep the same value selected, or COM4 is the same both before and after and there's a knockout bug.

By the way - I'm developing this on a Windows laptop and an FTDI usb to serial adapter, currently without any sensor plugged in. I'll add actual sensors into the mix once I have the settings, threading, management nailed.

I was utterly oblivious of the health aspect of 3D printing, but now, after checking out your links, I am so freaked out that I also suspended any 3D printing until I build an enclosure with ventilation, something like this: https://www.instructables.com/id/Easy-and-Cheap-3D-Printer-Fume-Hood/

According to those links, the main potential health issue is the emission of nanoparticles or ultrafine particles during printing. As far as I can tell none of those sensors you listed can detect particles that are that small. Or am I missing something?

By the way, big thank you for bringing this issue up; I am amazed how much there is a lack of public awareness of these health concerns.

Yeah, it's a little scary. Pretty sure the particulate matter sensors (I'm using the PMS A003) do measure these particles. Haven't looked into best options for VOCs yet.

According to most researches (for example, https://www.ehs.pitt.edu/sites/default/files/docs/03-0253Dprinters.pdf or https://pubs.rsc.org/en/content/articlelanding/2019/ra/c9ra03248g#!divAbstract), printers emit particles with sizes less than 0.1um. The size of the smallest particles PMSA003 or SDS011 can detect is 0.3um. I'm not aware of any affordable sensors that can measure particles under 0.1um.

Ah I see, yes you're right. I was thinking of PM1, which is >=1um. I'll be using the finest standard I can - seems more than likely PM emissions are across a spectrum of sizes, not exclusively <0.3um.

I'll also be monitoring various VOCs across as wide a range as I can cover.

Having said that, progress is difficult, it takes me a day or so to do something that would take an experienced developer 10 minutes, so this is a long, long term project.

AFAIK there is no effective DIY ventilation solution on Thingiverse or elsewhere from the 3D printing community. I remember finding only one that had any testing, and the result was that it didn't do the job. At least when this project is ready, it'll be easy for creators to measure the effectiveness of their solutions.

This research found that over 99% of the particles emitted by 3D printers are nanoparticles, i.e., smaller than 0.1u: https://www.sciencedirect.com/science/article/abs/pii/S187155321630038X
Unfortunately, if that’s true it means that there is little point using these cheap sensors.

VOC detection should be possible though, I just ordered this sensor: https://www.aliexpress.com/item/4001158887646.html. Edit: just realized that's not the right sensor for the task. This is a better choice: https://www.aliexpress.com/item/32866392932.html

Because of the small sizes of the particles they can’t be filtered out by ordinary HIPAA filters. The only solution seems to be is to use an enclosure and ventilating the air out from it, like in the Instructable link I posted before, but there are several similar projects out there. This research found that the combination of enclosure and ventilation can reduce the presence of particles by 97%: https://www.hse.gov.uk/research/rrpdf/rr1146.pdf

There are a couple things I remember reading before starting this project that gave me some hope, but I don't know which article I read them in, so may not be accurate...

The 0.1um particles don't stay 0.1um forever - they bond to each other fairly quickly to create larger particles. If that is true, measuring larger particles will have some use. If not, I'll need to find a better sensor.

HEPA filters can work on particles this size if they're thick enough - not because the particles can't get through the holes as with larger particles, but because while they can get through the holes, there's no straight path, so they rebound and rebound, losing energy, until they no longer have enough energy to escape the other side and become trapped in the filter. I don't know how thick the filter needs to be.

I don't know if this has been discussed in this thread or not but I will say that the UFPs will in all certainty possess a negative charge. Grounding a metallic or electrically-conductive filter would in theory help to trap the particles. Applying a positive charge would be even better.