From 842a20cc961a6950f9b10c9000a49cea9d04f29d Mon Sep 17 00:00:00 2001 From: flaisch <simon.flaisch@student.reutlingen-university.de> Date: Tue, 30 Apr 2024 15:37:25 +0200 Subject: [PATCH] Changed the game to work with our architecture. For that I implemented mqtt clients and a Server.js --- Server.js | 31 ++++++++++++++++++ app.js | 7 +++- index.html | 2 +- main.py | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 Server.js diff --git a/Server.js b/Server.js new file mode 100644 index 0000000..7d6fd60 --- /dev/null +++ b/Server.js @@ -0,0 +1,31 @@ +const mqtt = require("mqtt"); +const ws = require ("ws"); + +let socketserver = new ws.WebSocketServer({ + port: 443 +}); + + let client = mqtt.connect("mqtt://localhost:1883",{ + username: "standardUser", + password: "GreatHHZ4Ever!" + }); +client.on("connect", function() { + let topicID = "Topic1"; + client.subscribe(topicID); +}); +socketserver.on('connection', ws => { + console.log("new client connected"); + +}); +socketserver.on('close', () => console.log('Client has disconnected!')); + + + + + +client.on("message", function(topic, message){ + data = JSON.parse(message.toString()) + var column = {column: Math.min(data.total_fingers,6)} + socketserver.clients.forEach(client => { + client.send(JSON.stringify(column)); +})}); diff --git a/app.js b/app.js index b8a28f5..7b97c0a 100644 --- a/app.js +++ b/app.js @@ -1,3 +1,4 @@ + document.addEventListener('DOMContentLoaded', () => { const flaechen = document.querySelectorAll('.grid div'); const ergebnis = document.querySelector('#result'); @@ -5,6 +6,7 @@ document.addEventListener('DOMContentLoaded', () => { let currentPlayer = 1; + const gewinnFlaechen = [ [0, 1, 2, 3], [41, 40, 39, 38], @@ -77,7 +79,8 @@ document.addEventListener('DOMContentLoaded', () => { [13, 20, 27, 34], ] // Verbinden mit dem WebSocket. - const ws = new WebSocket('ws://localhost:89/ws'); + + const ws = new WebSocket('ws://localhost:443/ws'); ws.onmessage = function(event) { const data = JSON.parse(event.data); @@ -155,3 +158,5 @@ function placeChipInColumn(column) { } }) + + diff --git a/index.html b/index.html index 05368d4..07a5a0d 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ <meta charset="utf-8"> <title>Connect Four</title> <link rel="stylesheet" href="style.css"> - <script src="app.js" charset="utf-8" defer></script> + <script type="module" src="app.js" charset="utf-8" defer></script> </head> <body> <h1>Der derzeitige Spieler ist: Spieler <span id="current-player">1</span></h1> diff --git a/main.py b/main.py index 025bdf2..78579c7 100644 --- a/main.py +++ b/main.py @@ -1,17 +1,65 @@ +import json + import uvicorn from fastapi import FastAPI, WebSocket from fastapi.responses import HTMLResponse, Response import cv2 from cvzone.HandTrackingModule import HandDetector from imutils.video import VideoStream +import paho.mqtt.client as mqtt import asyncio +import time + + +unacked_publish = set() +main_time = 0 +response = None + +def on_connect( client, userdata, flags, reason_code, properties): + print(f"Connected with result code {reason_code}\n") + client.subscribe("Topic1") + + +# Funktion, die bei einem Publish in ein Topic ausgeführt wird. +def on_publish( client, userdata, mid, reason_code, properties): + try: + userdata.remove(mid) # Removed die gesendete Nachricht vom Speicher, um eine doppelte Sendung zu verhindern + except KeyError: + "Something went wrong. Please check if you have removed the mid from the userdata" + +# Funktion zur Verbindung mit MQTT +def connectwithmqtt( adress: str, targetport: int): + mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, userdata=None) # Intitalisierung des Clients + mqttc.on_connect = on_connect + mqttc.on_publish = on_publish + mqttc.user_data_set(unacked_publish) # Den lokalen Speicher als User data setzen + mqttc.username_pw_set(username="standardUser", + password="GreatHHZ4Ever!") # Username und Passwort - vorgegeben vom MQTT Server + mqttc.connect(host=adress, port=targetport) + while not mqttc.is_connected(): + mqttc.loop() + print("Waiting for connection...") + return mqttc + + +# Funktion zum senden einer Nachricht +def sendMessage(mqttc, topic, message): + mqttc.loop_start() # Started einen gethreaded connection loop zum senden der Nachrichten. + msg = mqttc.publish(topic, message, qos=1) + unacked_publish.add(msg.mid) # Mid sind die Daten der aktuellen Nachricht + while len(unacked_publish): + time.sleep(0.1) # Wartet bis alle gequeten Nachrichten gepublished werden + msg.wait_for_publish() + + +mqttClient = connectwithmqtt(adress="localhost", targetport=1883) app = FastAPI() # Video-Capture initialisieren try: - video_capture = VideoStream("http://localhost:88/video_feed").start() + video_capture = VideoStream("http://localhost:80/video_feed").start() except Exception as e: print(f"We couldn't reach the camera") exit() @@ -19,7 +67,42 @@ except Exception as e: # Hand-Detektor initialisieren detector = HandDetector(maxHands=2) +while True: + frame = video_capture.read() + if frame is None: + print("Sorry, couldn't receive videostream") + exit() + + # Handgesten-Erkennung + hands, img = detector.findHands(frame) + current_time = time.time() # Aktueller Zeitpunkt + if current_time - main_time > 5: # Timer + main_time = current_time + if hands: + # Zähle die Anzahl der gestreckten Finger + total_fingers = 0 + for hand in hands: + fingers = detector.fingersUp(hand) + total_fingers += sum(fingers) + response = { + "fingers": fingers, + "total_fingers": total_fingers + } + if response is not None: + sendMessage(mqttc=mqttClient, topic="Topic1", message=json.dumps(response)) + + + # Bild fürs Debugging anzeigen + cv2.imshow("Video", img) + if cv2.waitKey(1) & 0xFF == ord('q'): + print("Goodbye!") + mqttClient.disconnect() + mqttClient.loop_stop() + break +video_capture.stop() +cv2.destroyAllWindows() +''' @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() @@ -83,3 +166,13 @@ async def get_image(): if __name__ == "__main__": uvicorn.run(app, host="localhost", port=89) + + + # Begrenze die Fingeranzahl auf 7, da wir 7 Spalten haben (0-6) + selected_column = min(total_fingers, 6) + print("Selected column:", selected_column) + try: + await websocket.send_json({"column": selected_column}) + except Exception as e: + print(f"Error sending message: {str(e)}") +''' \ No newline at end of file -- GitLab