Closed danbates2 closed 4 years ago
tested, ready to merge. @TrystanLea @glynhudson
Thanks @danbates2 this is great!
Unfortunately Im having trouble with the blocking nature of the read function, when you try and restart or stop emonhub it just hangs there until its finished the latest set of readings. I've had a go at trying to call del from a signal or trigger from the main emonhub thread but no luck so far.
I've also made some other minor modifications here https://github.com/openenergymonitor/emonhub/commits/sds011
I tired adding adding the following to emonhub.py in the close section to then call a close method in the interfacer
def close(self):
"""Close hub. Do some cleanup before leaving."""
self._log.info("Exiting hub...")
for I in self._interfacers.values():
close = getattr(I, "close", None)
if callable(close):
I.close()
for I in self._interfacers.values():
I.stop = True
I.join()
and then in the SDS011 interfacer:
def close(self):
self._log.info("Closing SDS011")
# self.sds.ser = False
sds.__del__()
But no luck, need to somehow get the message that emonhub needs to close/restart into the SDS011 library thread...
Perhaps using this library might be easier? https://github.com/ikalchev/py-sds011
Hmm not sure that Im getting that library to work ... might be that the sds011 has the settings from the previous library and there's some conflict between active and passive mode not sure..
@TrystanLea
Unfortunately Im having trouble with the blocking nature of the read function
Right, I see what you mean with the emonhub restarts.
That other library could be the solution in that case.. (that other library gives us easier control of sleep times and readings too..)
I guess another way would be to put the process into a thread.
I also don't know the procedure for emonhub stopping interfacers. Is there a function it calls to stop interfacers?
I also don't know the procedure for emonhub stopping interfacers. Is there a function it calls to stop interfacers?
Yes and I tried tried to get that to work above, see 3rd comment back, but no luck in affecting the underlying thread unfortunately..
Sure. Who knows emonhub better? What's the procedure for closing interfacers?
That wasnt the issue, the close command was getting through to the interfacer, it was just that it wasnt getting into the sds011 library thread to close it as it where..
When stopping emonhub, the interfacers get stopped too. Is this always by this?..
def close(self):
Because one option is to put the serial stuff into a thread, and stop the thread when closing the interfacer.
The interfacers have a run method with a while loop, this loop exists if the stop flag is set to true: https://github.com/openenergymonitor/emonhub/blob/new_config_format/src/emonhub_interfacer.py#L94
the stop flag is set from emonhub.py when the users attempts to stop/restart emonhub here: https://github.com/openenergymonitor/emonhub/blob/new_config_format/src/emonhub.py#L148
the run method calls the read method that you see in the SDS011 interfacer: https://github.com/openenergymonitor/emonhub/blob/new_config_format/src/emonhub_interfacer.py#L99
Cool. But what about calling
def close(self):
? I can't see that anywhere.
I can see the stops in the main emonhub, but I can't see how each interfacer is actually closed. I think emonhub just waits for a read to finish, and doesn't do any more reads. That seems quite brittle to me.
Guess that's why a non-blocking read is important for being able to stop/start emonhub or an interfacer.
but I can't see how each interfacer is actually closed.
I think its just that the loop exits when it receives the flag and the interfacer closes automatically, I tried adding an additional close method above that would then have the ability to close a thread within an interfacer e.g by calling sds.del()
Looking at the code behind sds.del() it appears to only delete the socket, but we are not using sockets so I dont think it does anything..
I see what you mean... Like I say, I think the interfacer just doesn't do any more reads, it's not exiting the def read(). You see what I mean?
In the case of SDS011 or more generally? Yes the original library was blocking during read()
Yes more generally. I mean emonhub isn't able to exit an interfacer's read(), instead it's dependent on it returning a value. So the blocking library caused a problem. I'm not fluent with this python anyway. I'm sure an expert would have implemented a blocking library better.
@TrystanLea I've changed the library and now everything is broken. It was working on my laptop with the sensor plugged in by usb, but not on the rpi. Not sure if command from previous library has put the sds011 on the rpi in some mode I'm not aware of. Shouldn't be the case. I've tried a few of the extra mode related functions from the new library. Or there's a datatype issue in emonhub I've missed.
if you're trying the new one :
$ sudo pip3 uninstall sds011 $ sudo pip3 install py-sds011
New problem too, if changing setting in emonhub it jamms up here:
INFO MainThread Deleting interfacer 'SDS011'
this is what I'm running on the laptop to test it. might help.
@TrystanLea Got it. Try this one.
remember to uninstall the old module and install the new.
line 54: self.sensor.set_work_period(read=False, work_time=0) is what did it, set the mode of the sensor to something compatible with the new method.
@TrystanLea I've been testing the new methods for 24h and it's looking good.
Thanks for this Dan, works a treat!
PS: here's the code to optionally load the module https://github.com/openenergymonitor/emonhub/commit/db4e02cbc707c552818a021a84e3ffd5ae60aabe
Handy.
Where did the sudo pip3 install py-sds011
command have to go in the end?
This uses a much improved library to manage the SDS011 dust sensor. It enables the rate at which the sensor is read to be changed to assist in the internal laser lasting longer. As we know, the laser, running 24/7, will reach it's rated life in less than a year. Setting readinterval to 5 will give a dust sensor reading ever 5 minutes, elongating the life of the sensor to something more like 5 years.
Below is required to install the python library.
$ sudo pip3 install sds011