diff --git a/src/actuator/actuator.py b/src/actuator/actuator.py index 147bfdc..bf94f63 100644 --- a/src/actuator/actuator.py +++ b/src/actuator/actuator.py @@ -1,12 +1,11 @@ +from distutils.command.config import config from tools.status import Status -# Actuator Interface - class Actuator: """Actuator Interface class, to be overriden by actuator subclasses.""" - MAIN_LISTEN_TOPIC = "pid_update" + MAIN_LISTEN_TOPIC = config.pid_update def __init__( self, diff --git a/src/actuator/fans.py b/src/actuator/fans.py index 06ce03a..74aab70 100644 --- a/src/actuator/fans.py +++ b/src/actuator/fans.py @@ -2,6 +2,7 @@ from actuator.actuator import Actuator from pubsub import pub import RPi.GPIO as GPIO +import tools.config as config class Fans(Actuator): @@ -25,7 +26,8 @@ def __init__(self, *args, **kwargs): self._fan_out_speed: float = 0.0 pub.subscribe( self.fan_status_listener, - f"{Actuator.MAIN_LISTEN_TOPIC}.actuator.fans_status", + f"{Actuator.MAIN_LISTEN_TOPIC}.{config.actuator}" + + f".{config.fan_status}", ) GPIO.setup(Fans.FAN_IN_PIN0, GPIO.OUT) GPIO.setup(Fans.FAN_IN_PIN1, GPIO.OUT) diff --git a/src/actuator/led_lights.py b/src/actuator/led_lights.py index 8afe9e4..b895840 100644 --- a/src/actuator/led_lights.py +++ b/src/actuator/led_lights.py @@ -2,6 +2,7 @@ from actuator.actuator import Actuator from pubsub import pub import RPi.GPIO as GPIO +import tools.config as config class LEDLights(Actuator): @@ -21,7 +22,8 @@ def __init__(self, *args, **kwargs): self._brightness = 0 pub.subscribe( self.light_status_listener, - f"{Actuator.MAIN_LISTEN_TOPIC}.actuator.light_status", + f"{Actuator.MAIN_LISTEN_TOPIC}.{config.actuator}" + + f".{config.light_status}", ) GPIO.setup(LEDLights.LED_PIN, GPIO.OUT) diff --git a/src/actuator/water_pump.py b/src/actuator/water_pump.py index 6b7ea26..f06182f 100644 --- a/src/actuator/water_pump.py +++ b/src/actuator/water_pump.py @@ -2,6 +2,7 @@ from actuator.actuator import Actuator from pubsub import pub import RPi.GPIO as GPIO +import tools.config as config class Waterpump(Actuator): @@ -21,7 +22,8 @@ def __init__(self, *args, **kwargs): self._is_on = True pub.subscribe( self.water_pump_listener, - f"{Actuator.MAIN_LISTEN_TOPIC}.actuator.pump_status", + f"{Actuator.MAIN_LISTEN_TOPIC}.{config.actuator}" + + f".{config.water_pump_status}", ) GPIO.setup(Waterpump.PUMP_PIN, GPIO.OUT) diff --git a/src/analyser/analyser.py b/src/analyser/analyser.py index e4d5b09..32844e1 100644 --- a/src/analyser/analyser.py +++ b/src/analyser/analyser.py @@ -1,5 +1,6 @@ from pubsub import pub from typing import List +import tools.config as config class Analyser: @@ -14,9 +15,12 @@ def __init__( self._id = analyser_id for topic in self._sensor_type_topics: pub.subscribe( - self.datastream_update_listener, "database_update." + topic + self.datastream_update_listener, + config.database_update + "." + topic, + ) + pub.subscribe( + self.analyser_listener, config.pid_update + "." + topic ) - pub.subscribe(self.analyser_listener, "pid_update." + topic) def analyser_listener(self, args, rest=None): pass diff --git a/src/analyser/brightness_analyser.py b/src/analyser/brightness_analyser.py index 4549174..bdc4953 100644 --- a/src/analyser/brightness_analyser.py +++ b/src/analyser/brightness_analyser.py @@ -1,5 +1,6 @@ from pubsub import pub from analyser.analyser import Analyser +import tools.config as config class BrightnessAnalyser(Analyser): @@ -16,17 +17,20 @@ def analyser_listener(self, args, rest=None): if brightness > 270: sensor_data.actuator_value = 0.5 pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.light_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.light_status}", + args=sensor_data, ) # Lights 50% on elif brightness > 270: sensor_data.actuator_value = 0.2 pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.light_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.light_status}", + args=sensor_data, ) # Lights 20% on else: sensor_data.actuator_value = 0 pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.light_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.light_status}", + args=sensor_data, ) def analyser_datastream_update_listener(self, args, rest=None): diff --git a/src/analyser/brightness_pid.py b/src/analyser/brightness_pid.py index 136f893..d9c57ae 100644 --- a/src/analyser/brightness_pid.py +++ b/src/analyser/brightness_pid.py @@ -1,21 +1,23 @@ from pubsub import pub from analyser.analyser import Analyser from pid.pid import PID +import tools.config as config +from tools.analysis_constants import Analysis_Constants as analysis class BrightnessPidAnalyser(Analyser): def __init__(self, *args, **kwargs): - super().__init__(["sensor_data.light_sensor"]) - self._p_parameter = 1.2 - self._i_parameter = 0.5 - self._d_parameter = 0.001 + super().__init__([config.sensor_data + "." + config.light_sensor]) + self._p_parameter = analysis.BRIGHTNESS_P + self._i_parameter = analysis.BRIGHTNESS_I + self._d_parameter = analysis.BRIGHTNESS_D self._pid = PID( self._p_parameter, self._i_parameter, self._d_parameter ) - self._pid.SetPoint = 270 + self._pid.SetPoint = analysis.BRIGHTNESS_SETPOINT def analyser_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "pid_update" # TODO move to enum/config file + MAIN_PUBSUB_TOPIC = config.pid_update # TODO move to enum/config file brightness = args.sensor_value sensor_data = args feedback = brightness @@ -27,11 +29,12 @@ def analyser_listener(self, args, rest=None): sensor_data.actuator_value = output pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.light_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.light_status}", + args=sensor_data, ) def datastream_update_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "database_update" + MAIN_PUBSUB_TOPIC = config.database_update brightness = args.sensor_value sensor_data = args feedback = brightness @@ -42,5 +45,6 @@ def datastream_update_listener(self, args, rest=None): output = max(0, min(output, 100)) sensor_data.actuator_value = output pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.light_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.light_status}", + args=sensor_data, ) diff --git a/src/analyser/humidity_pid.py b/src/analyser/humidity_pid.py index 0c1e135..224f851 100644 --- a/src/analyser/humidity_pid.py +++ b/src/analyser/humidity_pid.py @@ -1,21 +1,23 @@ from pubsub import pub from analyser.analyser import Analyser from pid.pid import PID +import tools.config as config +from tools.analysis_constants import Analysis_Constants as analysis class HumidityPidAnalyser(Analyser): def __init__(self, *args, **kwargs): - super().__init__(["sensor_data.humidity_sensor"]) - self._p_parameter = 1.2 - self._i_parameter = 0.5 - self._d_parameter = 0.001 + super().__init__([config.sensor_data + "." + config.humidity_sensor]) + self._p_parameter = analysis.HUMIDITY_P + self._i_parameter = analysis.HUMIDITY_I + self._d_parameter = analysis.HUMIDITY_D self._pid = PID( self._p_parameter, self._i_parameter, self._d_parameter ) - self._pid.SetPoint = 55 + self._pid.SetPoint = analysis.HUMIDITY_SETPOINT def analyser_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "pid_update" # TODO move to enum/config file + MAIN_PUBSUB_TOPIC = config.pid_update # TODO move to enum/config file humidity = args.sensor_value sensor_data = args feedback = humidity @@ -27,11 +29,12 @@ def analyser_listener(self, args, rest=None): sensor_data.actuator_value = output pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.fans_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.fans_status}", + args=sensor_data, ) def datastream_update_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "database_update" + MAIN_PUBSUB_TOPIC = config.database_update humidity = args.sensor_value sensor_data = args feedback = humidity @@ -44,5 +47,6 @@ def datastream_update_listener(self, args, rest=None): print("DB update: ", sensor_data) pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.fans_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.fans_status}", + args=sensor_data, ) diff --git a/src/analyser/moisture_analyser.py b/src/analyser/moisture_analyser.py index 5effe54..5bbf17a 100644 --- a/src/analyser/moisture_analyser.py +++ b/src/analyser/moisture_analyser.py @@ -2,21 +2,25 @@ from analyser.analyser import Analyser from pid.pid import PID import time +import tools.config as config +from tools.analysis_constants import Analysis_Constants as analysis class MoisturePidAnalyser(Analyser): def __init__(self, *args, **kwargs): - super().__init__(["sensor_data.soil_moisture_sensor"]) - self._p_parameter = 1.2 - self._i_parameter = 0.5 - self._d_parameter = 0.001 + super().__init__( + [config.sensor_data + "." + config.soil_moisture_sensor] + ) + self._p_parameter = analysis.MOISTURE_P + self._i_parameter = analysis.MOISTURE_I + self._d_parameter = analysis.MOISTURE_D self._pid = PID( self._p_parameter, self._i_parameter, self._d_parameter ) - self._pid.SetPoint = 50 + self._pid.SetPoint = analysis.MOISTURE_SETPOINT def analyser_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "pid_update" # TODO move to enum/config file + MAIN_PUBSUB_TOPIC = config.pid_update # TODO move to enum/config file soilmoisture = round(((args.sensor_value * 3300) / 1024), 0) sensor_data = args feedback = soilmoisture @@ -29,21 +33,27 @@ def analyser_listener(self, args, rest=None): # monitor/on/off state) clock = 5 pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.water_pump_status", args=1.0 + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}" + + f".{config.water_pump_status}", + args=1.0, ) # pump on time.sleep(output * clock) pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.water_pump_status", args=0 + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}" + + f".{config.water_pump_status}", + args=0, ) # pump off time.sleep(clock - (output * clock)) def datastream_update_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "database_update" + MAIN_PUBSUB_TOPIC = config.database_update sensor_data = args output = (100 - self._pid.output) / 100 sensor_data.actuator_value = output # TODO either change to send the on off status (will be inaccurate) # , or see issue #55 pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.water_pump_status", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}" + + f".{config.water_pump_status}", + args=sensor_data, ) diff --git a/src/analyser/water_level_analyser.py b/src/analyser/water_level_analyser.py index 5df0f5d..103ee25 100644 --- a/src/analyser/water_level_analyser.py +++ b/src/analyser/water_level_analyser.py @@ -1,13 +1,16 @@ from pubsub import pub from analyser.analyser import Analyser +import tools.config as config class WaterLevelAnalyser(Analyser): def __init__(self, *args, **kwargs): - super().__init__(["sensor_data.water_level_sensor"]) + super().__init__( + [config.sensor_data + "." + config.water_level_sensor] + ) def analyser_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "pid_update" # TODO move to enum/config file + MAIN_PUBSUB_TOPIC = config.pid_update # TODO move to enum/config file water_level = round(((args.sensor_value * 3300) / 1024), 0) sensor_data = args if water_level < 50: @@ -20,13 +23,15 @@ def analyser_listener(self, args, rest=None): -1 ) # Set actuator to -1 to avoid null values in DB pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.water_level", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.water_level}", + args=sensor_data, ) def datastream_update_listener(self, args, rest=None): - MAIN_PUBSUB_TOPIC = "database_update" + MAIN_PUBSUB_TOPIC = config.database_update sensor_data = args sensor_data.actuator_value = -1 pub.sendMessage( - f"{MAIN_PUBSUB_TOPIC}.actuator.water_level", args=sensor_data + f"{MAIN_PUBSUB_TOPIC}.{config.actuator}.{config.water_level}", + args=sensor_data, ) diff --git a/src/data_streamer/azure_database_manager.py b/src/data_streamer/azure_database_manager.py index 91a1bb0..9dd588a 100644 --- a/src/data_streamer/azure_database_manager.py +++ b/src/data_streamer/azure_database_manager.py @@ -3,10 +3,11 @@ from dotenv import load_dotenv import os import pyodbc +import tools.config as config class AzureDatabaseManager(DatabaseManager): - sensor_data_topic = "database_update.actuator" + sensor_data_topic = config.database_update + "." + config.actuator def __init__(self, database_path: str = "test.db"): super().__init__("azure_db") @@ -111,7 +112,7 @@ def get_current_time_iso_cut(): db.create_sensor_data_table() print(get_current_time_iso_cut()) pub.sendMessage( - "actuator", + config.actuator, args=SensorData( get_current_time_iso_cut(), -1, "test_sensor_type", -999, 50 ), @@ -120,25 +121,25 @@ def get_current_time_iso_cut(): val = 0 for x in range(3): pub.sendMessage( - "actuator", + config.actuator, args=SensorData( get_current_time_iso_cut(), 1, "brightness", 900 + val, 50 ), ) pub.sendMessage( - "actuator", + config.actuator, args=SensorData( get_current_time_iso_cut(), 2, "humidity", 55 + val, 50 ), ) pub.sendMessage( - "actuator", + config.actuator, args=SensorData( get_current_time_iso_cut(), 3, "temperature", 20 + val, 50 ), ) pub.sendMessage( - "actuator", + config.actuator, args=SensorData( get_current_time_iso_cut(), 4, "water level", 15 + val, 50 ), diff --git a/src/data_streamer/database_manager.py b/src/data_streamer/database_manager.py index 0b0b4dd..b555c8a 100644 --- a/src/data_streamer/database_manager.py +++ b/src/data_streamer/database_manager.py @@ -1,5 +1,6 @@ import sqlite3 from pubsub import pub +import tools.config as config class DatabaseManager: @@ -98,7 +99,7 @@ def __repr__(self) -> str: with DatabaseManager() as db: db.create_sensor_data_table() pub.sendMessage( - "actuator", + config.actuator, args=SensorData(time(), -1, "test_sensor_type", -999, 50), ) print(db) diff --git a/src/data_streamer/iot_hub_streamer.py b/src/data_streamer/iot_hub_streamer.py index 562d496..7d04b2b 100644 --- a/src/data_streamer/iot_hub_streamer.py +++ b/src/data_streamer/iot_hub_streamer.py @@ -3,10 +3,11 @@ from pubsub import pub from datetime import datetime import os +import tools.config as config class IoTHubStreamer: - sensor_data_topic = "database_update.actuator" + sensor_data_topic = config.database_update + "." + config.actuator MSG_TEXT = ( '{{"Timestamp": {timestamp},' '"SensorID": {sensor_id},' diff --git a/src/tools/analysis_constants.py b/src/tools/analysis_constants.py new file mode 100644 index 0000000..399d29c --- /dev/null +++ b/src/tools/analysis_constants.py @@ -0,0 +1,22 @@ +from enum import Enum + + +class Analysis_Constants(Enum): + + # Brightness + BRIGHTNESS_P = 1.2 + BRIGHTNESS_I = 0.5 + BRIGHTNESS_D = 0.001 + BRIGHTNESS_SETPOINT = 270 + + # Humidity + HUMIDITY_P = 1.2 + HUMIDITY_I = 0.5 + HUMIDITY_D = 0.001 + HUMIDITY_SETPOINT = 55 + + # Moisture + MOISTURE_P = 1.2 + MOISTURE_I = 0.5 + MOISTURE_D = 0.001 + MOISTURE_SETPOINT = 50 diff --git a/src/tools/config.ini b/src/tools/config.ini index f903f6b..3292011 100644 --- a/src/tools/config.ini +++ b/src/tools/config.ini @@ -1,32 +1,22 @@ +[MAIN TOPICS] +sensor_data = "sensor_data" +actuator = "actuator" +actuator_value = "actuator_value" +pid_update = "pid_update" +database_update = "database_update" + +[SENSOR TYPES] +light_sensor = "light_sensor" +humidity_sensor = "humidity_sensor" +soil_moisture_sensor = "soil_moisture_sensor" +water_level_sensor = "water_level_sensor" +ambient_temperature_sensor = "ambient_temperature_sensor" + +[ACTUATOR STATUS] +light_status = "light_status" +fans_status = "fans_status" +water_level = "water_level" +water_pump_status = "water_pump_status" -"sensor_data" - -"sensor_data.light_sensor" -"sensor_data.humidity_sensor" -"sensor_data.soil_moisture_sensor" -"sensor_data.water_level_sensor" - -"pid_update.actuator.light_status" -"pid_update.actuator.fans_status" -"pid_update.actuator.water_level" -"pid_update.actuator.water_pump_status" - -"database_update.actuator.light_status" -"database_update.actuator.fans_status" -"database_update.actuator.water_level" - -"actuator" -"actuator_value" - -"pid_update.sensor_data.light_sensor" -"pid_update.sensor_data.humidity_sensor" -"pid_update.sensor_data.ambient_temperature_sensor" -"pid_update.sensor_data.soil_moisture_sensor" -"pid_update.sensor_data.water_level_sensor" - -"database_update.sensor_data.light_sensor" -"database_update.sensor_data.humidity_sensor" -"database_update.sensor_data.ambient_temperature_sensor" -"database_update.sensor_data.water_level_sensor" diff --git a/src/tools/config.py b/src/tools/config.py index 165ca43..a334a89 100644 --- a/src/tools/config.py +++ b/src/tools/config.py @@ -2,6 +2,23 @@ config = configparser.ConfigParser() config.read("config.ini") -sensor = config["SENSOR"] -status = config["STATUS"] -actuator = config["ACTUATOR"] + +main_topics = config["MAIN TOPICS"] +sensor_data = main_topics["sensor_data"] +actuator = main_topics["actuator"] +actuator_value = main_topics["actuator_value"] +pid_update = main_topics["pid_update"] +database_update = main_topics["database_update"] + +sensor_types = config["SENSOR TYPES"] +light_sensor = sensor_types["light_sensor"] +humidity_sensor = sensor_types["humidity_sensor"] +soil_moisture_sensor = sensor_types["soil_moisture_sensor"] +water_level_sensor = sensor_types["water_level_sensor"] +ambient_temperature_sensor = sensor_types["ambient_temperature_sensor"] + +actuator_status = config["ACTUATOR STATUS"] +light_status = actuator_status["light_status"] +fans_status = actuator_status["fans_status"] +water_level = actuator_status["water_level"] +water_pump_status = actuator_status["water_pump_status"]