update the light library

also replaces smbus by smbus2 to allow for cleaner setups
This commit is contained in:
Romain Bazile 2020-11-30 00:17:30 +01:00
parent 156286a8da
commit 51ff3b7375
5 changed files with 22 additions and 67 deletions

View file

@ -327,8 +327,7 @@ class ImagerProcess(multiprocessing.Process):
# Publish the status "Interrupted" to via MQTT to Node-RED
self.imager_client.client.publish("status/imager", '{"status":"Interrupted"}')
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 0)
planktoscope.light.interrupted()
# Change state to Stop
self.__imager.change(planktoscope.imager_state_machine.Stop)
@ -542,6 +541,9 @@ class ImagerProcess(multiprocessing.Process):
def __pump_message(self):
"""Sends a message to the pump process"""
planktoscope.light.pumping()
# Pump during a given volume
self.imager_client.client.publish(
"actuator/pump",
@ -595,22 +597,15 @@ class ImagerProcess(multiprocessing.Process):
f"The integrity file already exists in this export path {self.__export_path}"
)
# Set the LEDs as Blue
planktoscope.light.setRGB(0, 0, 255)
self.__pump_message()
# FIXME We should probably update the global metadata here with the current datetime/position/etc...
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 0)
# Change state towards Waiting for pump
self.__imager.change(planktoscope.imager_state_machine.Waiting)
def __state_capture(self):
# Set the LEDs as Cyan
planktoscope.light.setRGB(0, 255, 255)
planktoscope.light.imaging()
filename = f"{datetime.datetime.now().strftime('%H_%M_%S_%f')}.jpg"
@ -638,13 +633,9 @@ class ImagerProcess(multiprocessing.Process):
self.__img_done = 0
# Change state towards stop
self.__imager.change(planktoscope.imager_state_machine.Stop)
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 255)
planktoscope.light.error()
return
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 0)
# Add the checksum of the captured image to the integrity file
try:
planktoscope.integrity.append_to_integrity_file(filename_path)
@ -672,13 +663,10 @@ class ImagerProcess(multiprocessing.Process):
# Change state towards done
self.__imager.change(planktoscope.imager_state_machine.Stop)
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 255)
planktoscope.light.ready()
return
else:
# We have not reached the final stage, let's keep imaging
# Set the LEDs as Blue
planktoscope.light.setRGB(0, 0, 255)
# subscribe to status/pump
self.imager_client.client.subscribe("status/pump")
@ -688,9 +676,6 @@ class ImagerProcess(multiprocessing.Process):
self.__pump_message()
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 0)
# Change state towards Waiting for pump
self.__imager.change(planktoscope.imager_state_machine.Waiting)

View file

@ -8,13 +8,14 @@
# Logger library compatible with multiprocessing
from loguru import logger
import subprocess # nosec
# Library to send command over I2C for the light module on the fan
try:
import smbus2 as smbus
except ModuleNotFoundError:
subprocess.Popen("pip3 install smbus2".split(), stdout=subprocess.PIPE) # nosec
except ModuleNotFoundError: # We need this to install the library on machine that do not have the module yet
import subprocess # nosec
subprocess.run("pip3 install smbus2".split()) # nosec
import smbus2 as smbus
import enum
@ -57,11 +58,6 @@ class EffectColor(enum.IntEnum):
################################################################################
# LEDs functions
################################################################################
def i2c_update():
# Update the I2C Bus in order to really update the LEDs new values
subprocess.Popen("i2cdetect -y 1".split(), stdout=subprocess.PIPE) # nosec
def setRGB(R, G, B):
"""Update all LED at the same time"""
try:
@ -72,7 +68,6 @@ def setRGB(R, G, B):
bus.write_byte_data(DEVICE_ADDRESS, Register.red, R & 0xFF)
bus.write_byte_data(DEVICE_ADDRESS, Register.green, G & 0xFF)
bus.write_byte_data(DEVICE_ADDRESS, Register.blue, B & 0xFF)
# i2c_update()
except Exception as e:
logger.exception(f"An Exception has occured in the light library at {e}")
@ -82,7 +77,6 @@ def setRGBOff():
try:
with smbus.SMBus(1) as bus:
bus.write_byte_data(DEVICE_ADDRESS, Register.rgb_off, 0x00)
# i2c_update()
except Exception as e:
logger.exception(f"An Exception has occured in the light library at {e}")
@ -130,7 +124,6 @@ def ready():
setRGBColor(bus, EffectColor.Green)
setRGBSpeed(bus, 1)
setRGBEffect(bus, Effect.Breathing)
# i2c_update()
def error():
@ -138,7 +131,6 @@ def error():
setRGBColor(bus, EffectColor.Red)
setRGBSpeed(bus, 3)
setRGBEffect(bus, Effect.Water)
# i2c_update()
def interrupted():
@ -146,7 +138,6 @@ def interrupted():
setRGBColor(bus, EffectColor.Yellow)
setRGBSpeed(bus, 3)
setRGBEffect(bus, Effect.Water)
# i2c_update()
def pumping():
@ -154,7 +145,6 @@ def pumping():
setRGBColor(bus, EffectColor.Blue)
setRGBSpeed(bus, 3)
setRGBEffect(bus, Effect.Water)
# i2c_update()
def focusing():
@ -162,7 +152,6 @@ def focusing():
setRGBColor(bus, EffectColor.Purple)
setRGBSpeed(bus, 3)
setRGBEffect(bus, Effect.Water)
# i2c_update()
def imaging():
@ -170,7 +159,6 @@ def imaging():
setRGBColor(bus, EffectColor.White)
setRGBSpeed(bus, 1)
setRGBEffect(bus, Effect.Breathing)
# i2c_update()
def segmenting():
@ -178,7 +166,6 @@ def segmenting():
setRGBColor(bus, EffectColor.Purple)
setRGBSpeed(bus, 1)
setRGBEffect(bus, Effect.Breathing)
# i2c_update()
# This is called if this script is launched directly

View file

@ -53,7 +53,6 @@
# We can use collections.deque https://docs.python.org/3/library/collections.html#collections.deque
import paho.mqtt.client as mqtt
import json
import planktoscope.light
# Logger library compatible with multiprocessing
from loguru import logger
@ -117,8 +116,6 @@ class MQTT_Client:
)
# When connected, run subscribe()
self.client.subscribe(self.topic)
# Turn green the light module
planktoscope.light.setRGB(0, 255, 0)
@logger.catch
# Run this function in order to subscribe to all the topics begining by actuator

View file

@ -60,7 +60,6 @@ class SegmenterProcess(multiprocessing.Process):
if not os.path.exists(self.__objects_base_path):
# create the path!
os.makedirs(self.__objects_base_path)
# Morphocut's pipeline will be created at runtime otherwise shit ensues
logger.success("planktoscope.segmenter is initialised and ready to go!")
@ -82,8 +81,7 @@ class SegmenterProcess(multiprocessing.Process):
lambda p: os.path.splitext(os.path.basename(p))[0], abs_path
)
# Set the LEDs as Green
morphocut.Call(planktoscope.light.setRGB, 0, 255, 0)
morphocut.Call(planktoscope.light.segmenting())
# Read image
img = morphocut.image.ImageReader(abs_path)
@ -143,9 +141,6 @@ class SegmenterProcess(multiprocessing.Process):
mask, img_gray, min_area=1000, padding=10, warn_empty=name
)
# Set the LEDs as Purple
morphocut.Call(planktoscope.light.setRGB, 255, 0, 255)
# For an object, extract a vignette/ROI from the image
roi_orig = morphocut.image.ExtractROI(img, regionprops, bg_color=255)
@ -212,8 +207,6 @@ class SegmenterProcess(multiprocessing.Process):
id_json,
)
# Set the LEDs as Green
morphocut.Call(planktoscope.light.setRGB, 0, 255, 0)
logger.info("Morphocut's Pipeline has been created")
@logger.catch
@ -287,6 +280,7 @@ class SegmenterProcess(multiprocessing.Process):
try:
self.__pipe.run()
except Exception as e:
planktoscope.light.error()
logger.exception(f"There was an error in the pipeline {e}")
logger.info(f"Pipeline has been run for {path}")
else:
@ -299,14 +293,7 @@ class SegmenterProcess(multiprocessing.Process):
self.segmenter_client.client.publish(
"status/segmenter", '{"status":"Done"}'
)
# Set the LEDs as White
planktoscope.light.setRGB(255, 255, 255)
# cmd = os.popen("rm -rf /home/pi/PlanktonScope/tmp/*.jpg")
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 0)
planktoscope.light.ready()
elif action == "stop":
logger.info("The segmentation has been interrupted.")
@ -315,6 +302,7 @@ class SegmenterProcess(multiprocessing.Process):
self.segmenter_client.client.publish(
"status/segmenter", '{"status":"Interrupted"}'
)
planktoscope.light.interrupted()
elif action == "update_config":
logger.error("We can't update the configuration while we are segmenting.")

View file

@ -269,13 +269,11 @@ class StepperProcess(multiprocessing.Process):
"status/pump", '{"status":"Interrupted"}'
)
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 0)
planktoscope.light.ready()
elif last_message["action"] == "move":
logger.debug("We have received a move pump command")
# Set the LEDs as Blue
planktoscope.light.setRGB(0, 0, 255)
planktoscope.light.pumping()
if (
"direction" not in last_message
@ -315,13 +313,11 @@ class StepperProcess(multiprocessing.Process):
"status/focus", '{"status":"Interrupted"}'
)
# Set the LEDs as Green
planktoscope.light.setRGB(0, 255, 0)
planktoscope.light.ready()
elif last_message["action"] == "move":
logger.debug("We have received a move focus command")
# Set the LEDs as Yellow
planktoscope.light.setRGB(255, 255, 0)
planktoscope.light.focusing()
if "direction" not in last_message or "distance" not in last_message:
logger.error(
@ -354,7 +350,6 @@ class StepperProcess(multiprocessing.Process):
# If the command is "pump"
if command == "pump":
self.__message_pump(last_message)
# If the command is "focus"
elif command == "focus":
self.__message_focus(last_message)
@ -507,15 +502,18 @@ class StepperProcess(multiprocessing.Process):
# check if a new message has been received
self.treat_command()
if self.pump_stepper.move():
planktoscope.light.ready()
self.actuator_client.client.publish(
"status/pump",
'{"status":"Done"}',
)
if self.focus_stepper.move():
planktoscope.light.ready()
self.actuator_client.client.publish(
"status/focus",
'{"status":"Done"}',
)
time.sleep(0.0001)
logger.info("Shutting down the stepper process")
self.actuator_client.client.publish("status/pump", '{"status":"Dead"}')
self.actuator_client.client.publish("status/focus", '{"status":"Dead"}')