Every function should return json format with the wanted data from the database | Every function should return json format with the wanted data from the database | ||||
""" | """ | ||||
import paho.mqtt.client as mqtt | import paho.mqtt.client as mqtt | ||||
from plantdatabase import PlantDataBase | |||||
def data_handler(client: mqtt.Client, message) -> dict: | |||||
def data_handler(client: mqtt.Client, message: mqtt.MQTTMessage, mydatabase: PlantDataBase) -> None: | |||||
""" | """ | ||||
main entrypoint for a message handling method | main entrypoint for a message handling method | ||||
:param client: | |||||
:param message: | |||||
:return: | |||||
:param mydatabase: database with plant data | |||||
:param client: mqtt client | |||||
:param message: received message | |||||
:return: None | |||||
""" | """ | ||||
if message.topic.startwith('BackEnd'): | |||||
if message.topic == "BackEnd/Action/All": | |||||
action_all(client, message) | |||||
elif message.topic == "BackEnd/Action/GetPosition": | |||||
action_get_position(client, message) | |||||
elif message.topic == "BackEnd/Action/GetBattery": | |||||
action_get_battery(client, message) | |||||
elif message.topic == "BackEnd/Action/GetAllData": | |||||
action_get_all_data(client, message) | |||||
elif message.topic.startwith('Robot'): | |||||
if message.topic == "Robot/Data/SensorData": | |||||
if message.topic.startswith('Robot'): | |||||
if message.topic == 'Robot/Action/SensorData': | |||||
data_sensordata(client, message) | data_sensordata(client, message) | ||||
elif message.topic == "Robot/Data/Position": | |||||
elif message.topic == 'Robot/Action/Position': | |||||
data_position(client, message) | data_position(client, message) | ||||
elif message.topic == "Robot/Data/Battery": | |||||
elif message.topic == 'Robot/Action/Battery': | |||||
data_battery(client, message) | data_battery(client, message) | ||||
elif message.topic == "Robot/Data/Picture": | |||||
data_picture(client, message) | |||||
elif message.topic.startswith('BackEnd'): | |||||
if message.topic == 'BackEnd/Action/Drive': | |||||
action_drive(client, message) | |||||
elif message.topic == 'BackEnd/Action/GetPosition': | |||||
action_getposition(client) | |||||
elif message.topic == 'BackEnd/Action/GetBattery': | |||||
action_getbattery(client) | |||||
elif message.topic == 'BackEnd/Action/GetAllData': | |||||
action_getalldata(client) | |||||
# START ACTION FUNCTION DEFINITIONS | |||||
# Robot Channel Reactions | |||||
def action_all(client, message): | |||||
def data_sensordata(client: mqtt.Client, message: mqtt.MQTTMessage): | |||||
# TODO: Store data in database | |||||
pass | pass | ||||
def action_get_position(client, message): | |||||
def data_position(client: mqtt.Client, message: mqtt.MQTTMessage): | |||||
# TODO: Publish as json | |||||
pass | pass | ||||
def action_get_battery(client, message): | |||||
def data_battery(client: mqtt.Client, message: mqtt.MQTTMessage): | |||||
# TODO: Publish as json | |||||
pass | pass | ||||
def action_get_all_data(client, message): | |||||
pass | |||||
# FrontEnd Channel Reactions | |||||
def action_drive(client: mqtt.Client, message: mqtt.MQTTMessage): | |||||
client.publish('Robot/Action/Drive', message.payload).decode("utf-8") | |||||
# END ACTION FUNCTION DEFINITIONS | |||||
# START ROBOT FUNCTION DEFINITIONS | |||||
def action_getposition(client: mqtt.Client): | |||||
client.publish('Robot/Action/GetPosition') | |||||
def data_sensordata(client, message): | |||||
pass | |||||
def action_getbattery(client: mqtt.Client): | |||||
client.publish('Robot/Action/GetBattery') | |||||
def data_position(client, message): | |||||
pass | |||||
def data_battery(client, message): | |||||
def action_getalldata(client: mqtt.Client): | |||||
# TODO: get data from database | |||||
pass | pass | ||||
def data_picture(client, message): | |||||
pass | |||||
# END ROBOT FUNCTION DEFINITIONS |
while True: | while True: | ||||
randNumber = uniform(20.0, 21.0) | randNumber = uniform(20.0, 21.0) | ||||
client.publish("planttest", randNumber) | |||||
client.publish("Robot/Data/Battery") | |||||
print("Just published " + str(randNumber) + " to topic TEMPERATURE") | print("Just published " + str(randNumber) + " to topic TEMPERATURE") | ||||
time.sleep(0.5) | time.sleep(0.5) | ||||
from plantdatabase import PlantDataBase | from plantdatabase import PlantDataBase | ||||
from data_handling_functions import data_handler | from data_handling_functions import data_handler | ||||
# inits | |||||
mydatabase = PlantDataBase() | |||||
mydatabase.create_table() | |||||
def on_message(client, userdata, message): | |||||
def on_message(client: mqtt.Client, userdata, message): | |||||
""" | |||||
This method gets called, if a subscribed channel gets a new message. | |||||
Message gets forwarded to the data handler | |||||
:param client: mqtt client object | |||||
:param userdata: | |||||
:param message: received message object | |||||
:return: None | |||||
""" | |||||
print(type(message)) | |||||
print(f'message received! {message.topic}') | print(f'message received! {message.topic}') | ||||
data_handler(client, message) | |||||
data_handler(client, message, mydatabase) | |||||
def on_connect(client, userdata, flags, rc): | |||||
def on_connect(client: mqtt.Client, userdata, flags, rc): | |||||
""" | |||||
This method gets called, when it connects to a mqtt broker. | |||||
It is used to subscribe to the specific topics | |||||
:param client: mqtt client object | |||||
:param userdata: | |||||
:param flags: | |||||
:param rc: connection flag | |||||
:return: | |||||
""" | |||||
if rc == 0: | if rc == 0: | ||||
print("connected") | print("connected") | ||||
# TOPIC SUBSCRIPTIONS | # TOPIC SUBSCRIPTIONS | ||||
client.subscribe("planttest") | |||||
# Robot topics | |||||
client.subscribe("Robot/Data/SensorData") | |||||
client.subscribe("Robot/Data/Position") | |||||
client.subscribe("Robot/Data/Battery") | |||||
client.subscribe("Robot/Data/Picture") | |||||
# FrontEnd topics | |||||
client.subscribe("BackEnd/Action/All") | |||||
client.subscribe("BackEnd/Action/GetPosition") | |||||
client.subscribe("BackEnd/Action/GetBattery") | |||||
client.subscribe("BackEnd/Action/GetAllData") | |||||
# From Robot: | |||||
client.subscribe('Robot/Data/SensorData') | |||||
client.subscribe('Robot/Data/Position') | |||||
client.subscribe('Robot/Data/Battery') | |||||
# client.subscribe('Robot/Data/Picture') | |||||
# From FrontEnd: | |||||
client.subscribe('BackEnd/Action/Drive') | |||||
client.subscribe('BackEnd/Action/GetPosition') | |||||
client.subscribe('BackEnd/Action/GetBattery') | |||||
client.subscribe('BackEnd/Action/GetAllData') | |||||
# END TOPIC SUBSCRIPTIONS | # END TOPIC SUBSCRIPTIONS | ||||
else: | else: | ||||
print("connection failed") | print("connection failed") | ||||
def main(): | def main(): | ||||
mydatabase = PlantDataBase() | |||||
mydatabase.create_table() | |||||
client = mqtt.Client() | client = mqtt.Client() | ||||
client.on_connect = on_connect | client.on_connect = on_connect | ||||
client.on_message = on_message | client.on_message = on_message |
def create_table(self): | def create_table(self): | ||||
table_config = "CREATE TABLE IF NOT EXISTS plants " \ | table_config = "CREATE TABLE IF NOT EXISTS plants " \ | ||||
"(plant_ID INTEGER PRIMARY KEY AUTOINCREMENT," \ | "(plant_ID INTEGER PRIMARY KEY AUTOINCREMENT," \ | ||||
" gps TEXT," \ | |||||
" plant_type TEXT)" | |||||
" gps TEXT)" | |||||
self.cur.execute(table_config) | self.cur.execute(table_config) | ||||
table_config = "CREATE TABLE IF NOT EXISTS measurement_values " \ | table_config = "CREATE TABLE IF NOT EXISTS measurement_values " \ | ||||
"plant_ID INTEGER, " \ | "plant_ID INTEGER, " \ | ||||
"sensordata_temp REAL," \ | "sensordata_temp REAL," \ | ||||
"sensordata_humidity REAL," \ | "sensordata_humidity REAL," \ | ||||
"sensordata_ground_humidity REAL," \ | |||||
"sensordata_soil_moisture REAL," \ | |||||
"pest_infestation INTEGER," \ | "pest_infestation INTEGER," \ | ||||
"light_intensity REAL," \ | "light_intensity REAL," \ | ||||
"FOREIGN KEY (plant_ID)" \ | "FOREIGN KEY (plant_ID)" \ | ||||
pest_infestation, | pest_infestation, | ||||
light_intensity): | light_intensity): | ||||
self.cur.execute(f"INSERT INTO measurement_values (plant_ID, sensordata_temp, sensordata_humidity," | self.cur.execute(f"INSERT INTO measurement_values (plant_ID, sensordata_temp, sensordata_humidity," | ||||
f" sensordata_ground_humidity, pest_infestation, light_intensity) VALUES " | |||||
f" sensordata_soil_moisture, pest_infestation, light_intensity) VALUES " | |||||
f"({plant_id}, {sensordata_temp}, {sensordata_humidity}, {sensordata_ground_humidity}, {pest_infestation}" | f"({plant_id}, {sensordata_temp}, {sensordata_humidity}, {sensordata_ground_humidity}, {pest_infestation}" | ||||
f", {light_intensity})") | f", {light_intensity})") | ||||
self.conn.commit() | self.conn.commit() | ||||
"timestamp": data[1], | "timestamp": data[1], | ||||
"sensordata_temp": data[3], | "sensordata_temp": data[3], | ||||
"sensordata_humidity": data[4], | "sensordata_humidity": data[4], | ||||
"sensordata_ground_humidity": data[5], | |||||
"sensordata_soil_moisture": data[5], | |||||
"pest_infestation": data[6], | "pest_infestation": data[6], | ||||
"light_intensity": data[7] | "light_intensity": data[7] | ||||
} | } |