repository to manage all files related to the makeathon farm bot project (Software + Documentation).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mainProg.py 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. """
  2. created by waldluis
  3. This file contains the main script for the RaspberryPi of smart garden project
  4. It has the task to control the EV3 robot and take measurements with the mounted sensor
  5. The sensor data is published to MQTT topics to be available for the backend server
  6. Used protocol for interaction: mqtt (paho-mqtt module)
  7. Interaction with the EV3 via SSH
  8. """
  9. import paho.mqtt.client as mqtt
  10. import json
  11. import threading
  12. import os
  13. import time
  14. from raspy_sensors import RaspySensors
  15. from software.defines import Topics, RASPI_CLIENT_ID, MQTT_BROKER_GLOBAL
  16. #region global Varaibles
  17. sensors: RaspySensors
  18. #endregion
  19. #region global functions
  20. # TODO auslagern
  21. def measure_send_data(plantID, actionID, client: mqtt.Client):
  22. """
  23. Reads all sensors and publishes data via MQTT
  24. Args:
  25. plantID (_type_): plant to measure
  26. actionID (_type_): current ID of driving action
  27. client (mqtt.Client): current mqtt client for publishing
  28. """
  29. sensorData = sensors.readSensors()
  30. sensorData["PlantID"] = plantID
  31. sensorData["ActionID"] = actionID
  32. client.publish(Topics["ROBOT_DATA_SENSORDATA"], json.dumps(sensorData, indent=4))
  33. # TODO auslagern
  34. def drive_plant_thread(plantID, actionID, client: mqtt.Client):
  35. """
  36. Function to drive to plant according to number from MQTT message in thread
  37. Meassure and publish data via MQTT
  38. Drive home to starting point
  39. Args:
  40. plantID (_type_): plant to measure
  41. actionID (_type_): current ID of driving action
  42. client (mqtt.Client): current mqtt client for publishing
  43. """
  44. os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/plant_{plantID}.py')
  45. #CHECK if working properly
  46. print("Measuring Sensors")
  47. measure_send_data(plantID, actionID, client)
  48. print("Robot driving home")
  49. if plantID % 2 == 0:
  50. leftRight = -50 #rotating left
  51. else:
  52. leftRight = 50 #rotating right
  53. os.system(f'sshpass -p maker ssh robot@ev3dev.local python3 /home/robot/Programme/drive_back.py {leftRight}')
  54. print("Robot home")
  55. #TODO decide about robot occupied message
  56. #client.publish("ROBOT/DATA/OCCUPIED", "false")
  57. def on_connect(client: mqtt.Client, userdata, flags, rc):
  58. """
  59. This method gets called, when it connects to a mqtt broker.
  60. It is used to subscribe to the specific topics
  61. Args:
  62. client (mqtt.Client): current mqtt client
  63. userdata (_type_): _description_
  64. flags (_type_): _description_
  65. rc (_type_): _description_
  66. """
  67. if rc == 0:
  68. #Add callbacks
  69. client.message_callback_add("ROBOT/DATA", send_data_json) #Testing
  70. client.message_callback_add(Topics["ROBOT_ACTION_DRIVE"], drive_plant)
  71. client.message_callback_add(Topics["ROBOT_ACTION_GETPOSITION"], get_position)
  72. client.message_callback_add(Topics["ROBOT_ACTION_GETBATTERY"], get_BatteryStatus)
  73. #Subscribe to topics
  74. client.subscribe("ROBOT/DATA") #Testing
  75. client.subscribe(Topics["ROBOT_ACTION_DRIVE"])
  76. client.subscribe(Topics["ROBOT_ACTION_GETPOSITION"])
  77. client.subscribe(Topics["ROBOT_ACTION_GETBATTERY"])
  78. print("MQTT initialized")
  79. #endregion
  80. # TODO auslagern
  81. #region MQTT callbacks
  82. #Testing
  83. def send_data_json(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
  84. strIn = str(message.payload.decode("UTF-8"))
  85. dataDict = json.loads(strIn)
  86. print("Received data: ", json.dumps(dataDict))
  87. # CHECK if working properly
  88. def drive_plant(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
  89. """
  90. Function to drive to plant according to request
  91. Starting Drive in Thread
  92. Args:
  93. clients (mqtt.Client): current mqtt client
  94. userdata (_type_): _description_
  95. message (mqtt.MQTTMessage): received message
  96. """
  97. dictMessage = json.loads(str(message.payload.decode("UTF-8")))
  98. plantID = dictMessage["PlantID"]
  99. actionID = dictMessage["ActionID"]
  100. print(f"received drive to plant {plantID}")
  101. thread = threading.Thread(target= drive_plant_thread, args=(plantID, actionID, clients), daemon=True)
  102. thread.start()
  103. def get_position(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
  104. """
  105. Callback function for GPS position request
  106. Function to send actual GPS position via MQTT
  107. Args:
  108. clients (mqtt.Client): current mqtt client
  109. userdata (_type_): _description_
  110. message (mqtt.MQTTMessage): received message
  111. """
  112. # TODO Write Sensor Function
  113. position = {
  114. "Position": ""
  115. }
  116. clients.publish(Topics["ROBOT_DATA_POSITION"], json.dumps(position, indent=4))
  117. def get_BatteryStatus(clients: mqtt.Client, userdata, message: mqtt.MQTTMessage):
  118. """
  119. Callback function for battery status request
  120. Function to read battery status from ev3 and send via MQTT
  121. Args:
  122. clients (mqtt.Client): current mqtt client
  123. userdata (_type_): _description_
  124. message (mqtt.MQTTMessage): received message
  125. """
  126. battery = {
  127. "Battery": 0.0
  128. }
  129. #TODO read Battery
  130. clients.publish(Topics["ROBOT_DATA_BATTERY"], json.dumps(battery, indent=4))
  131. #endregion
  132. def main():
  133. """
  134. Initialises MQTT and Sensors
  135. Runs forever and controlls all robot functions
  136. """
  137. # CHECK if global
  138. global sensors
  139. sensors = RaspySensors()
  140. client = mqtt.Client(RASPI_CLIENT_ID)
  141. client.on_connect = on_connect
  142. client.connect(MQTT_BROKER_GLOBAL)
  143. # dataDict = {} #Testing
  144. # CHECK forever or start
  145. client.loop_start()
  146. print("Starting Loop")
  147. while True:
  148. # print("Looping")
  149. # time.sleep(1)
  150. pass
  151. if __name__ == "__main__":
  152. main()