diff --git a/api/mosquitto/data/mosquitto.db b/api/mosquitto/data/mosquitto.db index de61d7fd..b5662a01 100644 Binary files a/api/mosquitto/data/mosquitto.db and b/api/mosquitto/data/mosquitto.db differ diff --git a/rpi/controllers/GameController.py b/rpi/controllers/GameController.py new file mode 100644 index 00000000..872a295c --- /dev/null +++ b/rpi/controllers/GameController.py @@ -0,0 +1,53 @@ +from flask import jsonify, request + +from services.game_service import GameService + +class GameController: + + _game_service : GameService + _has_started : bool + _auth_token : str + + def __init__(self, app): + self._game_service = GameService() + self._register_routes(app) + self.auth_token = "0eed89e8-7625-4f8d-bf2a-0872aede0efb" + self._has_started = False + + def _register_routes(self, app): + app.add_url_rule("/command/party/start", view_func=self.start_party, methods=['POST']) + app.add_url_rule("/command/party/play", view_func=self.make_move, methods=['POST']) + + def start_party(self): + try: + data = request.get_json() + if data is None: + raise Exception("Data must be provided") + + white_name = data["white_name"] + black_name = data["black_name"] + time_control = int(data["time_control"]) + increment = int(data["increment"]) + + self._game_service.start(white_name, black_name, time_control, increment) + + return jsonify({"status": "ok", "message": "Game started"}), 200 + except Exception as ex: + print(ex) + return jsonify({"status": "error", "message": f"An error occurred : {ex}"}), 500 + + def make_move(self): + try: + if not self._has_started: + jsonify({"status": "error", "message": "Game hasn't started yet"}), 400 + + auth_token = request.headers.get("Authorization") + if auth_token != self.auth_token: + return jsonify({"status": "error", "message": "Invalid authorization token"}), 401 + + self._game_service.make_move() + + return jsonify({"status": "ok"}), 200 + except Exception as ex: + print(ex) + return jsonify({"status": "error", "message": f"An error occurred : {ex}"}), 500 \ No newline at end of file diff --git a/rpi/main.py b/rpi/main.py index 5510f3f2..52383813 100644 --- a/rpi/main.py +++ b/rpi/main.py @@ -6,6 +6,7 @@ import requests from dotenv import load_dotenv from flask import Flask, jsonify, request +from controllers.GameController import GameController from hardware.light.lora_light_sensor_reader import LoraLightSensorReader from hardware.rfid.reader import RfidReader from services.clock_service import ClockService @@ -29,61 +30,41 @@ api_username = os.environ.get("API_USERNAME") api_password = os.environ.get("API_PASSWORD") app = Flask(__name__) - -rfid_reader = RfidReader("/dev/serial0", 9600) -light_sensor_reader = LoraLightSensorReader("/dev/ttyUSB1", 9600) - -local_broker = MQTTService( - local_broker_address, - local_broker_port, - client_id="system", - username=local_username, - password=local_password, -) - -api_broker = MQTTService( - api_broker_address, - api_broker_port, - client_id=client_id, - username=api_username, - password=api_password, -) - -forward_service = ForwarderService(local_broker, api_broker) -game_service = GameService() - -@app.route("/command/party/start", methods=['POST']) -def start_party(): - try: - data = request.get_json() - print(f"Received data : {data}") - print("Party started!") - return jsonify({"status": "ok", "message": "Party started"}), 200 - except Exception as ex: - print(ex) - return jsonify({"status": "error", "message": f"An error occurred : {ex}"}), 500 - -@app.route("/command/party/play", methods=['POST']) -def make_move(): - try: - game_service.make_move() - - return jsonify({"status": "ok", "message": "Party started"}), 200 - except Exception as ex: - print(ex) - return jsonify({"status": "error", "message": f"An error occurred : {ex}"}), 500 +forwarder_service = None if __name__ == "__main__": try : - forward_service.register_forwarder(client_id, "/system/sensor/rfid", f"/customer/telemetry/rfid") - forward_service.register_forwarder(client_id, "/system/sensor/light", f"/customer/telemetry/light") - forward_service.register_forwarder(client_id, "/system/sensor/gps", f"/customer/telemetry/gps") + rfid_reader = RfidReader("/dev/serial0", 9600) + light_sensor_reader = LoraLightSensorReader("/dev/ttyUSB1", 9600) + + local_broker = MQTTService( + local_broker_address, + local_broker_port, + client_id="system", + username=local_username, + password=local_password, + ) + + api_broker = MQTTService( + api_broker_address, + api_broker_port, + client_id=client_id, + username=api_username, + password=api_password, + ) + + forwarder_service = ForwarderService(local_broker, api_broker) + game_controller = GameController(app) + + forwarder_service.register_forwarder(client_id, "/system/sensor/rfid", f"/customer/telemetry/rfid") + forwarder_service.register_forwarder(client_id, "/system/sensor/light", f"/customer/telemetry/light") + forwarder_service.register_forwarder(client_id, "/system/sensor/gps", f"/customer/telemetry/gps") rfid_reader.subscribe(lambda uid: local_broker.publish("/system/sensor/rfid", str(uid), 1)) light_sensor_reader.subscribe(lambda light_value: local_broker.publish("/system/sensor/light", str(light_value), 0)) - forward_service.start_all() + forwarder_service.start_all() rfid_reader.start() light_sensor_reader.start() @@ -93,12 +74,12 @@ if __name__ == "__main__": except KeyboardInterrupt: print("Keyboard interrupt. Stopping app...") - game_service.stop() - forward_service.stop_all() + #game_service.stop() + forwarder_service.stop_all() exit() except Exception as e: print(e) - game_service.stop() - forward_service.stop_all() + #game_service.stop() + forwarder_service.stop_all() exit() \ No newline at end of file diff --git a/rpi/services/game_service.py b/rpi/services/game_service.py index b37e4288..56ed17a8 100644 --- a/rpi/services/game_service.py +++ b/rpi/services/game_service.py @@ -1,6 +1,7 @@ -import cv2 -import numpy as np +import threading + import requests +import _thread from services.clock_service import ClockService from services.detection_service import DetectionService @@ -15,7 +16,7 @@ class GameService: self.detection_service = DetectionService() self.clock_service = ClockService() - def start(self, time_control : int, increment : int ) -> None: + def start(self, white_name, back_name, time_control : int, increment : int ) -> None: self.clock_service.start(time_control, increment) self.clock_service.set_on_terminated(self.stop) @@ -27,10 +28,21 @@ class GameService: try : frame, fen = self.detection_service.analyze_single_frame() print(fen) + url = "http://192.168.15.125:1880/party/image" + threading.Thread( + target=self.__send_detection_result, + args=(url, frame, fen), + daemon=True + ).start() + except Exception as e: + print(e) + + def __send_detection_result(self, url, img, fen): + try: headers = {'Content-Type': 'image/jpeg'} - body = {'frame': frame, 'fen': fen} + body = {'frame': img, 'fen': fen} response = requests.post( - "https://192.168.15.125:1880/party/image", + url, data=body, headers=headers, verify=False)