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.8KB

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