Error Handling BackEnd added, logging included, order list and robot class added
This commit is contained in:
parent
0385aa7792
commit
4e60cd9ad0
14
.idea/deployment.xml
generated
Normal file
14
.idea/deployment.xml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PublishConfigData" serverName="backend" remoteFilesAllowedToDisappearOnAutoupload="false">
|
||||
<serverData>
|
||||
<paths name="backend">
|
||||
<serverdata>
|
||||
<mappings>
|
||||
<mapping deploy="/home/lego/SMARTGARDENING" local="$PROJECT_DIR$/software" web="/" />
|
||||
</mappings>
|
||||
</serverdata>
|
||||
</paths>
|
||||
</serverData>
|
||||
</component>
|
||||
</project>
|
8
.idea/sshConfigs.xml
generated
Normal file
8
.idea/sshConfigs.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SshConfigs">
|
||||
<configs>
|
||||
<sshConfig authType="PASSWORD" host="lego-K53SV" id="40359a92-2c87-41df-943b-cfac73c7ea3d" port="22" nameFormat="DESCRIPTIVE" username="lego" useOpenSSHConfig="true" />
|
||||
</configs>
|
||||
</component>
|
||||
</project>
|
14
.idea/webServers.xml
generated
Normal file
14
.idea/webServers.xml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="WebServers">
|
||||
<option name="servers">
|
||||
<webServer id="1b3e9e3f-7394-4cbc-a32d-b95ef2abda52" name="backend">
|
||||
<fileTransfer accessType="SFTP" host="lego-K53SV" port="22" sshConfigId="40359a92-2c87-41df-943b-cfac73c7ea3d" sshConfig="lego@lego-K53SV:22 password">
|
||||
<advancedOptions>
|
||||
<advancedOptions dataProtectionLevel="Private" keepAliveTimeout="0" passiveMode="true" shareSSLContext="true" />
|
||||
</advancedOptions>
|
||||
</fileTransfer>
|
||||
</webServer>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -29,4 +29,4 @@ urllib3==1.26.14
|
||||
Werkzeug==2.2.3
|
||||
zipp==3.15.0
|
||||
python-ev3dev2==2.1.0.post1
|
||||
pytest
|
||||
pytest==7.3.1
|
Binary file not shown.
@ -10,73 +10,103 @@ from software.defines import Topics, MAX_PLANT_COUNT
|
||||
import json
|
||||
import uuid
|
||||
from typing import Union
|
||||
from datetime import datetime
|
||||
import logging
|
||||
from robot import Robot
|
||||
|
||||
|
||||
# Robot Channel Reactions
|
||||
|
||||
def data_sensordata(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase,
|
||||
order_handler: list):
|
||||
print("message received")
|
||||
# TODO: Store data in database
|
||||
robot: Robot):
|
||||
str_in = str(message.payload.decode("UTF-8"))
|
||||
payload = json.loads(str_in)
|
||||
print("Received data: ", json.dumps(payload))
|
||||
logging.info("ROBOT_DATA_SENSORDATA Received data: " + json.dumps(payload))
|
||||
drive_data = {
|
||||
"PlantID": payload['PlantID'],
|
||||
"ActionID": payload['ActionID']
|
||||
}
|
||||
|
||||
order_handler.remove(payload['ActionID'])
|
||||
try:
|
||||
robot.delete_order(drive_data)
|
||||
except Exception as e:
|
||||
logging.error("Could not delete order: " + str(e))
|
||||
|
||||
mydatabase.insert_measurement_data(plant_id=payload['PlantID'],
|
||||
sensordata_temp=payload['AirTemperature'],
|
||||
sensordata_humidity=payload['AirHumidity'],
|
||||
sensordata_soil_moisture=payload['SoilMoisture'],
|
||||
sensordata_brightness=payload['Brightness'])
|
||||
logging.debug("Inserted to data base: " + json.dumps(payload))
|
||||
|
||||
|
||||
def data_position(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
# TODO: Forward to frontend in json format
|
||||
client.publish(Topics['BACKEND_DATA_POSITION'], message.payload.decode("utf-8"))
|
||||
def data_position(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
logging.info("ROBOT_DATA_POSITION Received data: " + json.dumps(message.payload.decode("UTF-8")))
|
||||
robot.store_position(json.loads(message.payload.decode("UTF-8"))["Position"])
|
||||
position_data = {
|
||||
"Position": robot.get_position(),
|
||||
"Timestamp": str(datetime.now())
|
||||
}
|
||||
client.publish(Topics['BACKEND_DATA_POSITION'], json.dumps(position_data))
|
||||
|
||||
|
||||
def data_battery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
# TODO: Forward to frontend in json format
|
||||
client.publish(Topics['BACKEND_DATA_BATTERY'], message.payload.decode("utf-8"))
|
||||
def data_battery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
logging.info("ROBOT_DATA_BATTERY Received data: " + json.dumps(message.payload.decode("UTF-8")))
|
||||
robot.store_battery(json.loads(message.payload.decode("UTF-8"))["Battery"])
|
||||
battery_data = {
|
||||
"Battery": robot.get_battery(),
|
||||
"Timestamp": str(datetime.now())
|
||||
}
|
||||
client.publish(Topics['BACKEND_DATA_BATTERY'], json.dumps(battery_data))
|
||||
|
||||
|
||||
# FrontEnd Channel Reactions
|
||||
|
||||
def action_drive(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase,
|
||||
order_handler: list):
|
||||
# TODO: ROBOT READY CHECK
|
||||
if len(order_handler) < 5:
|
||||
order_handler.append(uuid.uuid4())
|
||||
robot: Robot):
|
||||
plant_id = mydatabase.get_plant_id(plant_name=json.loads(message.payload.decode("UTF-8"))["PlantName"])
|
||||
action_id = str(uuid.uuid4())
|
||||
drive_data = {
|
||||
"PlantID": plant_id,
|
||||
"ActionID": action_id
|
||||
}
|
||||
|
||||
if robot.get_order_number() < 5 and robot.get_robot_status() is True:
|
||||
robot.add_order(drive_data)
|
||||
client.publish(Topics['ROBOT_ACTION_DRIVE'], json.dumps(drive_data))
|
||||
logging.info("BACKEND_ACTION_DRIVE Drive Command published: " + json.dumps(drive_data))
|
||||
else:
|
||||
# TODO: What to do when no place in order_list left
|
||||
pass
|
||||
client.publish(Topics['ROBOT_ACTION_DRIVE'], message.payload.decode("utf-8"))
|
||||
if robot.get_order_number() < 5:
|
||||
robot.add_order(drive_data)
|
||||
logging.info("BACKEND_ACTION_DRIVE New data added to order list: " + str(drive_data))
|
||||
elif robot.get_order_number() >= 5:
|
||||
logging.error("Could not add Order to list. Order discarded")
|
||||
client.publish(Topics['BACKEND_DATA_ERROR'], "Could not add Order to list. Order discarded")
|
||||
|
||||
|
||||
def action_driveall(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
def action_driveall(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase,
|
||||
robot: Robot):
|
||||
# TODO: Implement here
|
||||
pass
|
||||
print("HELLO")
|
||||
|
||||
|
||||
def action_getposition(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
client.publish(Topics['ROBOT_ACTION_GETPOSITION'])
|
||||
logging.info("BACKEND_ACTION_GETPOSITION message forwarded to Robot")
|
||||
|
||||
|
||||
def action_getbattery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
def action_getbattery(client: mqtt.Client, userdata, message: mqtt.MQTTMessage):
|
||||
client.publish(Topics['ROBOT_ACTION_GETBATTERY'])
|
||||
logging.info("BACKEND_ACTION_GETBATTERY message forwarded to Robot")
|
||||
|
||||
|
||||
def action_getalldata(client: mqtt.Client, userdata, message: Union[mqtt.MQTTMessage, list], mydatabase: PlantDataBase):
|
||||
plant_names = mydatabase.get_plant_names()
|
||||
print(type(plant_names))
|
||||
alldata = []
|
||||
for i in plant_names:
|
||||
print("I Type: " + str(type(i)))
|
||||
print("I: " + i[0])
|
||||
alldata.append(mydatabase.get_latest_data(plant_name=i[0]))
|
||||
client.publish(Topics['BACKEND_DATA_SENSORDATAALL'], json.dumps(alldata))
|
||||
print("BACKEND_DATA_SENSORDATAALL SEND DATA:" + str(alldata))
|
||||
logging.info("BACKEND_DATA_SENSORDATAALL got data from database:" + str(alldata))
|
||||
|
||||
|
||||
def action_newplant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
@ -87,8 +117,7 @@ def action_newplant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, my
|
||||
sensordata_humidity=plant_data["AirHumidity"],
|
||||
sensordata_soil_moisture=plant_data["SoilMoisture"],
|
||||
sensordata_brightness=plant_data["Brightness"])
|
||||
print("BACKEND_ACTION_NEWPLANT RECEIVED DATA: " + str(plant_data))
|
||||
print(mydatabase.get_plant_names())
|
||||
logging.info("BACKEND_ACTION_NEWPLANT new plant data received and inserted: " + str(plant_data))
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
|
||||
|
||||
@ -100,14 +129,14 @@ def action_configureplant(client: mqtt.Client, userdata, message: mqtt.MQTTMessa
|
||||
sensordata_humidity=plant_data["AirHumidity"],
|
||||
sensordata_soil_moisture=plant_data["SoilMoisture"],
|
||||
sensordata_brightness=plant_data["Brightness"])
|
||||
print("BACKEND_ACTION_CONFIGUREPLANT RECEIVED DATA: " + str(plant_data))
|
||||
logging.info("BACKEND_ACTION_CONFIGUREPLANT configure plant data received and inserted: " + str(plant_data))
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
|
||||
|
||||
def action_deleteplant(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, mydatabase: PlantDataBase):
|
||||
delete_plant = json.loads(message.payload.decode("UTF-8"))
|
||||
mydatabase.delete_plant(plant_id=delete_plant)
|
||||
print("BACKEND_ACTION_DELETEPLANT RECEIVED DATA: " + str(delete_plant))
|
||||
logging.info("BACKEND_ACTION_DELETEPLANT delete plant data received and deleted: " + str(delete_plant))
|
||||
action_getalldata(client, userdata, message, mydatabase)
|
||||
|
||||
|
||||
@ -118,4 +147,20 @@ def action_countplants(client: mqtt.Client, userdata, message: mqtt.MQTTMessage,
|
||||
"MaxCount": MAX_PLANT_COUNT
|
||||
}
|
||||
client.publish(Topics["BACKEND_DATA_PLANTCOUNT"], json.dumps(count_payload))
|
||||
print("BACKEND_DATA_PLANTCOUNT SEND DATA: " + str(count_payload))
|
||||
logging.info("BACKEND_DATA_PLANTCOUNT forwarded plant count to FrontEnd: " + str(count_payload))
|
||||
|
||||
|
||||
def data_error(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
robot.store_last_error(message.payload.decode("UTF-8"))
|
||||
logging.error("ROBOT_DATA_ERROR new error received from Robot: " + robot.get_last_error())
|
||||
client.publish(Topics['BACKEND_DATA_ERROR'], message.payload.decode("UTF-8"))
|
||||
|
||||
|
||||
def data_robotready(client: mqtt.Client, userdata, message: mqtt.MQTTMessage, robot: Robot):
|
||||
robot.change_robot_status(message.payload.decode("UTF-8") == 'True')
|
||||
if robot.get_robot_status() is True and robot.get_order_number() >= 1:
|
||||
client.publish(Topics['ROBOT_ACTION_DRIVE'], json.dumps(robot.get_next_order()))
|
||||
logging.info("Waiting Order send to Robot")
|
||||
|
||||
logging.info("ROBOT_DATA_ROBOTREADY status updated: " + str(robot.get_robot_status()))
|
||||
client.publish(Topics['BACKEND_DATA_ROBOTREADY'], message.payload.decode("UTF-8"))
|
||||
|
@ -1,10 +1,12 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
import software.defines
|
||||
from software.defines import MQTT_BROKER_LOCAL
|
||||
from random import randrange, uniform
|
||||
import time
|
||||
import json
|
||||
from software.defines import Topics, PLANTDATA
|
||||
mqttBroker = "192.168.178.182"
|
||||
mqttBroker = software.defines.MQTT_BROKER_GLOBAL
|
||||
|
||||
|
||||
def on_connect(client, userdata, flags, rc):
|
||||
@ -20,17 +22,10 @@ client.on_connect = on_connect
|
||||
client.connect(mqttBroker)
|
||||
|
||||
plantdata = {
|
||||
"AirTemperature": 20.4,
|
||||
"AirHumidity": 7.0,
|
||||
"SoilMoisture": 5.0,
|
||||
"Brightness": 39,
|
||||
"PlantID": 2,
|
||||
"Timestamp": "hallo",
|
||||
"MeasurementID": 187
|
||||
"PlantName": "Kemal"
|
||||
}
|
||||
|
||||
print(type(PLANTDATA))
|
||||
while True:
|
||||
client.publish("TEST", json.dumps(plantdata))
|
||||
print(json.dumps(plantdata))
|
||||
time.sleep(2)
|
||||
client.publish("BACKEND/ACTION/GETBATTERY", json.dumps(plantdata))
|
||||
print(json.dumps(plantdata))
|
||||
time.sleep(2)
|
||||
|
@ -12,17 +12,17 @@ import paho.mqtt.client as mqtt
|
||||
from software.defines import MQTT_BROKER_LOCAL, MQTT_BROKER_GLOBAL, Topics, BACKEND_CLIENT_ID, DATABASE_NAME
|
||||
from plantdatabase import PlantDataBase
|
||||
import data_functions
|
||||
|
||||
# inits
|
||||
mydatabase = PlantDataBase(database_name=DATABASE_NAME)
|
||||
mydatabase.create_tables()
|
||||
order_handler = [] # will contain UUIDS with Order IDs
|
||||
import logging
|
||||
import sys
|
||||
from robot import Robot
|
||||
|
||||
|
||||
def on_connect(_client: mqtt.Client, _userdata, _flags, _rc):
|
||||
def on_connect(_client: mqtt.Client, _userdata, _flags, _rc, _mydatabase, _robot):
|
||||
"""
|
||||
This method gets called, when it connects to a mqtt broker.
|
||||
It is used to subscribe to the specific topics
|
||||
:param _robot:
|
||||
:param _mydatabase:
|
||||
:param _client: mqtt client object
|
||||
:param _userdata:
|
||||
:param _flags:
|
||||
@ -37,25 +37,25 @@ def on_connect(_client: mqtt.Client, _userdata, _flags, _rc):
|
||||
# From Robot:
|
||||
_client.subscribe(Topics['ROBOT_DATA_SENSORDATA'])
|
||||
_client.message_callback_add(Topics['ROBOT_DATA_SENSORDATA'], lambda client, userdata, message: data_functions.
|
||||
data_sensordata(client, userdata, message, mydatabase, order_handler))
|
||||
data_sensordata(client, userdata, message, _mydatabase, _robot))
|
||||
|
||||
_client.subscribe(Topics['ROBOT_DATA_POSITION'])
|
||||
_client.message_callback_add(Topics['ROBOT_DATA_POSITION'], data_functions.data_position)
|
||||
|
||||
_client.subscribe(Topics['ROBOT_DATA_BATTERY'])
|
||||
_client.message_callback_add(Topics['ROBOT_DATA_BATTERY'], lambda client, userdata, message: data_functions.
|
||||
data_battery(client, userdata, message, mydatabase))
|
||||
data_battery(client, userdata, message))
|
||||
|
||||
# client.subscribe('Robot/Data/Picture')
|
||||
|
||||
# From FrontEnd:
|
||||
_client.subscribe(Topics['BACKEND_ACTION_DRIVE'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_DRIVE'], lambda client, userdata, message: data_functions.
|
||||
action_drive(client, userdata, message, mydatabase, order_handler))
|
||||
action_drive(client, userdata, message, _mydatabase, _robot))
|
||||
|
||||
_client.subscribe(Topics['BACKEND_ACTION_DRIVEALL'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_DRIVE'], lambda client, userdata, message: data_functions.
|
||||
action_driveall(client, userdata, message, mydatabase))
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_DRIVEALL'], lambda client, userdata, message: data_functions.
|
||||
action_driveall(client, userdata, message, _mydatabase, _robot))
|
||||
|
||||
_client.subscribe(Topics['BACKEND_ACTION_GETPOSITION'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_GETPOSITION'], data_functions.action_getposition)
|
||||
@ -66,35 +66,54 @@ def on_connect(_client: mqtt.Client, _userdata, _flags, _rc):
|
||||
_client.subscribe(Topics['BACKEND_ACTION_GETALLDATA'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_GETALLDATA'],
|
||||
lambda client, userdata, message: data_functions.
|
||||
action_getalldata(client, userdata, message, mydatabase))
|
||||
action_getalldata(client, userdata, message, _mydatabase))
|
||||
|
||||
_client.subscribe(Topics['BACKEND_ACTION_NEWPLANT'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_NEWPLANT'], lambda client, userdata, message: data_functions.
|
||||
action_newplant(client, userdata, message, mydatabase))
|
||||
action_newplant(client, userdata, message, _mydatabase))
|
||||
|
||||
_client.subscribe(Topics['BACKEND_ACTION_CONFIGUREPLANT'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_CONFIGUREPLANT'], lambda client, userdata, message: data_functions.
|
||||
action_configureplant(client, userdata, message, mydatabase))
|
||||
action_configureplant(client, userdata, message, _mydatabase))
|
||||
|
||||
_client.subscribe(Topics['BACKEND_ACTION_DELETEPLANT'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_DELETEPLANT'],
|
||||
lambda client, userdata, message: data_functions.
|
||||
action_deleteplant(client, userdata, message, mydatabase))
|
||||
action_deleteplant(client, userdata, message, _mydatabase))
|
||||
|
||||
_client.subscribe(Topics['BACKEND_ACTION_PLANTCOUNT'])
|
||||
_client.message_callback_add(Topics['BACKEND_ACTION_PLANTCOUNT'], lambda client, userdata, message: data_functions.
|
||||
action_countplants(client, userdata, message, mydatabase))
|
||||
action_countplants(client, userdata, message, _mydatabase))
|
||||
|
||||
_client.subscribe(Topics['ROBOT_DATA_ERROR'])
|
||||
_client.message_callback_add(Topics['ROBOT_DATA_ERROR'], lambda client, userdata, message: data_functions.
|
||||
data_error(client, userdata, message, _robot))
|
||||
|
||||
_client.subscribe(Topics['ROBOT_DATA_ROBOTREADY'])
|
||||
_client.message_callback_add(Topics['ROBOT_DATA_ROBOTREADY'], lambda client, userdata, message: data_functions.
|
||||
data_robotready(client, userdata, message, _robot))
|
||||
# END TOPIC SUBSCRIPTIONS
|
||||
else:
|
||||
print("connection failed")
|
||||
|
||||
|
||||
def main():
|
||||
client = mqtt.Client(BACKEND_CLIENT_ID)
|
||||
client.on_connect = on_connect
|
||||
client.connect(MQTT_BROKER_GLOBAL)
|
||||
client.loop_forever()
|
||||
robot = Robot()
|
||||
my_database = PlantDataBase(database_name=DATABASE_NAME)
|
||||
my_database.create_tables()
|
||||
mqttclient = mqtt.Client(BACKEND_CLIENT_ID)
|
||||
mqttclient.on_connect = lambda client, userdata, flags, rc: on_connect(_client=client,
|
||||
_userdata=userdata,
|
||||
_flags=flags,
|
||||
_rc=rc,
|
||||
_mydatabase=my_database,
|
||||
_robot=robot)
|
||||
mqttclient.connect(MQTT_BROKER_GLOBAL)
|
||||
logging.basicConfig(filename="server.log", filemode="a", encoding="utf-8", level=logging.DEBUG,
|
||||
format='%(asctime)s %(name)s %(levelname)s %(message)s',
|
||||
datefmt="%d-%m-%Y %H:%M:%S")
|
||||
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
|
||||
mqttclient.loop_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -1,6 +1,7 @@
|
||||
# file to create a database via python script
|
||||
import sqlite3
|
||||
from typing import Optional
|
||||
import logging
|
||||
|
||||
|
||||
class PlantDataBase:
|
||||
@ -13,9 +14,8 @@ class PlantDataBase:
|
||||
self.conn = None
|
||||
try:
|
||||
self.conn = sqlite3.connect(self.db_file, check_same_thread=False)
|
||||
print(sqlite3.version)
|
||||
except sqlite3.Error as e:
|
||||
print(e)
|
||||
logging.error("Database init error: " + str(e))
|
||||
self.cur = self.conn.cursor()
|
||||
|
||||
def create_tables(self):
|
||||
@ -38,32 +38,36 @@ class PlantDataBase:
|
||||
self.cur.execute(table_config)
|
||||
return True
|
||||
except sqlite3.Warning as e:
|
||||
return e
|
||||
logging.error("Could not create tables: " + str(e))
|
||||
return False
|
||||
|
||||
def insert_plant(self, plantname: str, plant_id: int):
|
||||
def insert_plant(self, plantname: str, plant_id: int) -> bool:
|
||||
try:
|
||||
self.cur.execute("INSERT INTO plants (PlantName, PlantID) VALUES (?,?)", (plantname, plant_id))
|
||||
self.conn.commit()
|
||||
return True
|
||||
except (sqlite3.NotSupportedError, sqlite3.Warning) as e:
|
||||
return e
|
||||
except Exception as e:
|
||||
logging.error("Could not insert plant: " + str(e))
|
||||
return False
|
||||
|
||||
def configure_plant(self, plant_id: int, plantname: str):
|
||||
def configure_plant(self, plant_id: int, plantname: str) -> bool:
|
||||
try:
|
||||
self.cur.execute("UPDATE plants SET PlantID = ?, PlantName = ? WHERE PlantID= ?",
|
||||
(plant_id, plantname, plant_id))
|
||||
self.conn.commit()
|
||||
return True
|
||||
except (sqlite3.NotSupportedError, sqlite3.Warning) as e:
|
||||
return e
|
||||
except Exception as e:
|
||||
logging.error("Could not configure plant: " + str(e))
|
||||
return False
|
||||
|
||||
def delete_plant(self, plant_id):
|
||||
try:
|
||||
self.cur.execute('DELETE FROM plants WHERE PlantID = ?', (plant_id,))
|
||||
self.conn.commit()
|
||||
return True
|
||||
except (sqlite3.NotSupportedError, sqlite3.Warning) as e:
|
||||
return e
|
||||
except Exception as e:
|
||||
logging.error("Could not delete plant: " + str(e))
|
||||
return False
|
||||
|
||||
def insert_measurement_data(self, plant_id,
|
||||
sensordata_temp,
|
||||
@ -72,13 +76,14 @@ class PlantDataBase:
|
||||
sensordata_brightness) -> bool:
|
||||
try:
|
||||
self.cur.execute(f"INSERT INTO measurement_values (PlantID, AirTemperature, AirHumidity,"
|
||||
f"SoilMoisture, Brightness) VALUES "
|
||||
f"({plant_id}, {sensordata_temp}, {sensordata_humidity}, {sensordata_soil_moisture}"
|
||||
f", {sensordata_brightness})")
|
||||
f"SoilMoisture, Brightness) VALUES "
|
||||
f"({plant_id}, {sensordata_temp}, {sensordata_humidity}, {sensordata_soil_moisture}"
|
||||
f", {sensordata_brightness})")
|
||||
self.conn.commit()
|
||||
return True
|
||||
except (sqlite3.NotSupportedError, sqlite3.Warning) as e:
|
||||
return e
|
||||
except Exception as e:
|
||||
logging.error("Could not insert measurement data: " + str(e))
|
||||
return False
|
||||
|
||||
def get_latest_data(self, plant_name: Optional[str] = None, plant_id: Optional[int] = None):
|
||||
"""
|
||||
@ -108,27 +113,42 @@ class PlantDataBase:
|
||||
"PlantName": plant_name
|
||||
}
|
||||
return json_file
|
||||
except (sqlite3.Warning, TypeError) as e:
|
||||
return e
|
||||
|
||||
except Exception as e:
|
||||
logging.error("Could not get measurement values: " + str(e))
|
||||
|
||||
def delete_data(self, table_name):
|
||||
self.cur.execute(f'DELETE FROM {table_name}')
|
||||
self.conn.commit()
|
||||
return True
|
||||
|
||||
# TODO: Kemals Scheiß implementieren
|
||||
try:
|
||||
self.cur.execute(f'DELETE FROM {table_name}')
|
||||
self.conn.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
logging.error("Could not delete data: " + str(e))
|
||||
|
||||
def plant_count(self) -> int:
|
||||
"""
|
||||
returns the number of plants registered in the database
|
||||
:return:
|
||||
"""
|
||||
self.cur.execute("SELECT COUNT(*) FROM plants")
|
||||
return self.cur.fetchone()[0]
|
||||
try:
|
||||
self.cur.execute("SELECT COUNT(*) FROM plants")
|
||||
return self.cur.fetchone()[0]
|
||||
except Exception as e:
|
||||
logging.error("Could not count plants: " + str(e))
|
||||
|
||||
def get_plant_names(self) -> list:
|
||||
self.cur.execute("SELECT PlantName FROM plants")
|
||||
return self.cur.fetchall()
|
||||
try:
|
||||
self.cur.execute("SELECT PlantName FROM plants")
|
||||
return self.cur.fetchall()
|
||||
except Exception as e:
|
||||
logging.error("Could not get plant names: " + str(e))
|
||||
|
||||
def get_plant_id(self, plant_name: str) -> int:
|
||||
try:
|
||||
self.cur.execute("SELECT PlantID FROM plants WHERE PlantName=?", (plant_name,))
|
||||
return self.cur.fetchone()[0]
|
||||
except Exception as e:
|
||||
logging.error("Could not get plant id: " + str(e))
|
||||
|
||||
def __del__(self):
|
||||
self.conn.close()
|
||||
|
47
software/backend/robot.py
Normal file
47
software/backend/robot.py
Normal file
@ -0,0 +1,47 @@
|
||||
class Robot:
|
||||
"""
|
||||
This class contains the features of the robot. It is used as an interface for the main to avoid global variables and
|
||||
store them instead in an instance of this robot object
|
||||
"""
|
||||
def __init__(self):
|
||||
self.robot_ready = True
|
||||
self.order_handler = []
|
||||
self.battery = 0
|
||||
self.position = ""
|
||||
self.last_error = ""
|
||||
|
||||
def change_robot_status(self, status: bool):
|
||||
self.robot_ready = status
|
||||
|
||||
def add_order(self, drivedata):
|
||||
self.order_handler.append(drivedata)
|
||||
|
||||
def delete_order(self, drivedata):
|
||||
self.order_handler.remove(drivedata)
|
||||
|
||||
def get_next_order(self):
|
||||
return self.order_handler[0]
|
||||
|
||||
def get_order_number(self):
|
||||
return len(self.order_handler)
|
||||
|
||||
def store_battery(self, battery):
|
||||
self.battery = battery
|
||||
|
||||
def store_position(self, position):
|
||||
self.position = position
|
||||
|
||||
def store_last_error(self, error):
|
||||
self.last_error = error
|
||||
|
||||
def get_battery(self):
|
||||
return self.battery
|
||||
|
||||
def get_position(self):
|
||||
return self.position
|
||||
|
||||
def get_last_error(self):
|
||||
return self.last_error
|
||||
|
||||
def get_robot_status(self):
|
||||
return self.robot_ready
|
Binary file not shown.
@ -21,6 +21,8 @@ Topics = {
|
||||
"ROBOT_DATA_BATTERY": "ROBOT/DATA/BATTERY",
|
||||
"ROBOT_DATA_POSITION": "ROBOT/DATA/POSITION",
|
||||
"ROBOT_DATA_PICTURE": "ROBOT/DATA/PICTURE",
|
||||
"ROBOT_DATA_ERROR": "ROBOT/DATA/ERROR",
|
||||
"ROBOT_DATA_ROBOTREADY": "ROBOT/DATA/ROBOTREADY",
|
||||
|
||||
"BACKEND_ACTION_DRIVE": "BACKEND/ACTION/DRIVE",
|
||||
"BACKEND_ACTION_DRIVEALL": "BACKEND/ACTION/DRIVEALL",
|
||||
@ -38,7 +40,8 @@ Topics = {
|
||||
"BACKEND_DATA_BATTERY": "BACKEND/DATA/BATTERY",
|
||||
"BACKEND_DATA_PICTURE": "BACKEND/DATA/PICTURE",
|
||||
"BACKEND_DATA_PLANTCOUNT": "BACKEND/DATA/PLANTCOUNT",
|
||||
|
||||
"BACKEND_DATA_ERROR": "BACKEND/DATA/ERROR",
|
||||
"BACKEND_DATA_ROBOTREADY": "BACKEND/DATA/ROBOTREADY"
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user