diff --git a/ESP8266/src/main.cpp b/ESP8266/src/main.cpp index 1bd2792..2017aee 100644 --- a/ESP8266/src/main.cpp +++ b/ESP8266/src/main.cpp @@ -2,11 +2,11 @@ #include // Remplacez par les informations de votre réseau WiFi -const char* ssid = "Le chateau de Chantenay"; -const char* password = "crevette4ever"; +const char* ssid = "Refugees Welcome"; +const char* password = "calais62"; // Adresse du serveur HTTP sur le PC -const char* host = "192.168.1.62"; // Remplacez par l'adresse IP de votre PC +const char* host = "192.168.234.214"; // Remplacez par l'adresse IP de votre PC const int port = 5000; const int buttonPin = D7; // Définir le pin du bouton @@ -14,12 +14,27 @@ bool lastButtonState = HIGH; // État précédent du bouton unsigned long lastDebounceTime = 0; // Dernier temps de changement d'état unsigned long debounceDelay = 50; // Délai de débounce (en millisecondes) +const int ledPin = D5; +unsigned long lastBlinkTime = 0; // Dernier temps de clignotement +const unsigned long blinkInterval = 500; // Intervalle de clignotement (en millisecondes) +// Énumération pour les états de la LED +enum LEDState { + OFF, + ON, + BLINKING +}; +LEDState ledState = OFF; // État initial de la LED + +ESP8266WebServer server(5000); // Créer un serveur HTTP sur le port 80 + void setup() { Serial.begin(115200); delay(10); + pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); + digitalWrite(ledPin, LOW); WiFi.begin(ssid, password); Serial.print("Connexion à "); Serial.print(ssid); @@ -28,12 +43,59 @@ void setup() { Serial.print("."); } Serial.println(" connectée"); + + server.on("/blink", []() { + // Cette fonction sera appelée lorsque le serveur reçoit une requête sur /update + Serial.println("Requête reçue sur /play"); + // Par exemple, vous pouvez allumer la LED si la requête le demande + ledState = BLINKING; // Allumer la LED + server.send(200, "text/plain", "LED blink"); // Envoyer une réponse + }); + + // Définir le gestionnaire pour la requête entrante + server.on("/on", []() { + // Cette fonction sera appelée lorsque le serveur reçoit une requête sur /update + Serial.println("Requête reçue sur /win"); + // Par exemple, vous pouvez allumer la LED si la requête le demande + ledState = ON; // Allumer la LED + server.send(200, "text/plain", "LED high"); // Envoyer une réponse + }); + + server.on("/off", []() { + // Cette fonction sera appelée lorsque le serveur reçoit une requête sur /update + Serial.println("Requête reçue sur /wait"); + // Par exemple, vous pouvez allumer la LED si la requête le demande + ledState = OFF; // Allumer la LED + server.send(200, "text/plain", "LED low"); // Envoyer une réponse + }); + + + + server.begin(); // Démarrer le serveur } void loop() { - int buttonState = digitalRead(buttonPin); // Lire l'état du bouton + // Gérer les requêtes entrantes + server.handleClient(); - // Vérifier le débounce + // LED management + unsigned long currentTime = millis(); + + // Logique de clignotement en fonction de l'état + if (ledState == BLINKING) { + if (currentTime - lastBlinkTime >= blinkInterval) { + lastBlinkTime = currentTime; + digitalWrite(ledPin, !digitalRead(ledPin)); // Inverser l'état de la LED + } + } else if (ledState == ON) { + digitalWrite(ledPin, HIGH); // LED allumée + } else { + digitalWrite(ledPin, LOW); // LED éteinte + } + + int buttonState = digitalRead(buttonPin); // Lire l'état du bouton + + // Débounce if (buttonState != lastButtonState) { lastDebounceTime = millis(); // Réinitialiser le temps de débounce } @@ -45,7 +107,7 @@ void loop() { Serial.println("Bouton pressé! Envoi de la requête..."); WiFiClient client; if (client.connect(host, port)) { - client.print(String("GET /execute?box_id=1 HTTP/1.1\r\n") + + client.print(String("GET /execute HTTP/1.1\r\n") + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); diff --git a/Python/bell.mp3 b/Python/bell.mp3 new file mode 100644 index 0000000..1d3ae0a Binary files /dev/null and b/Python/bell.mp3 differ diff --git a/Python/buttons.json b/Python/buttons.json index c89de26..e679429 100644 --- a/Python/buttons.json +++ b/Python/buttons.json @@ -1 +1 @@ -{"1": "192.168.1.34", "2": "192.168.1.42"} \ No newline at end of file +{"1": "192.168.234.240"} \ No newline at end of file diff --git a/Python/coin.mp3 b/Python/coin.mp3 new file mode 100644 index 0000000..60c87f3 Binary files /dev/null and b/Python/coin.mp3 differ diff --git a/Python/register.py b/Python/register.py index 1b930c3..48086fe 100644 --- a/Python/register.py +++ b/Python/register.py @@ -10,7 +10,7 @@ app = Flask(__name__) buttons = {} # Dictionnaire pour stocker les boutons et leurs IP lock = threading.Lock() -EXPECTED_BUTTONS = 2 # Nombre de boutons attendus +EXPECTED_BUTTONS = 0 # Nombre de boutons attendus # Fichier pour enregistrer la correspondance BUTTONS_FILE = 'buttons.json' @@ -53,4 +53,5 @@ def execute_script(): if __name__ == '__main__': print("Serveur d'enregistrement démarré") + EXPECTED_BUTTONS = int(input("Nombre de buzzers ? ")) serve(app, host='0.0.0.0', port=5000) # Utiliser Waitress pour démarrer le serveur diff --git a/Python/server.py b/Python/server.py index a83b7de..299372b 100644 --- a/Python/server.py +++ b/Python/server.py @@ -7,14 +7,17 @@ import keyboard import json import os from waitress import serve +from pygame import mixer import time +import requests # Ajouté pour envoyer des requêtes HTTP app = Flask(__name__) DEBUG = False +INGAME = True # Variables globales -fastest = None +port = 5000 # Définir le port utilisé par vos boutons lock = threading.Lock() order = [] # Liste pour suivre l'ordre des boutons button_ips = {} # Dictionnaire pour enregistrer les adresses IP des boutons @@ -25,109 +28,204 @@ if os.path.exists(json_file): with open(json_file, 'r') as f: button_ips = json.load(f) +def init_mixer(): + if not mixer.get_init(): + mixer.init() + if DEBUG: + print("Mixer initialized.") + +def play_sound(file): + mixer.music.load(file) + mixer.music.play() + +def notify_button(ip, endpoint): + """ Fonction pour envoyer une requête à un bouton à son adresse IP. """ + url = f"http://{ip}:{port}{endpoint}" # Utiliser la variable `port` définie en haut + try: + response = requests.get(url) + if DEBUG: + print(f"Requête envoyée à {ip}{endpoint}: {response.status_code}") + except Exception as e: + print(f"Erreur lors de l'envoi de la requête à {ip}: {e}") + @app.route('/execute') def execute_script(): - global fastest - client_ip = request.remote_addr # Obtenir l'adresse IP du client - # Vérifier si l'adresse IP est enregistrée - button_id = None - for button, ip in button_ips.items(): - if ip == client_ip: - button_id = button - break + if INGAME: + client_ip = request.remote_addr # Obtenir l'adresse IP du client - if button_id is None: # Si l'IP n'est pas trouvée - error_message = {"message": "Erreur : cette adresse IP n'est pas enregistrée."} - print(f"{error_message['message']} - IP: {client_ip}") - return jsonify(error_message), 400 # Retourne un code d'erreur 400 + # Vérifier si l'adresse IP est enregistrée + button_id = None + for button, ip in button_ips.items(): + if ip == client_ip: + button_id = button + break - send_vlc_command('pl_pause', True) # Mettre VLC en pause + # if button_id is None: # Si l'IP n'est pas trouvée + # error_message = {"message": "Erreur : cette adresse IP n'est pas enregistrée."} + # print(f"{error_message['message']} - IP: {client_ip}") + # return jsonify(error_message), 400 # Retourne un code d'erreur 400 - # Utiliser un verrou pour gérer les accès concurrents - with lock: - if button_id not in order: - order.append(button_id) # Ajouter le boîtier à la liste d'ordre - print(f"Boîtiers en ordre: {order}") - if fastest is None: - fastest = button_id # Le premier à arriver devient le gagnant - response_message = {"message": "fastest"} - # print(f"Fastest is {button_id}") + # Utiliser un verrou pour gérer les accès concurrents + with lock: + if button_id not in order: + send_vlc_command('pl_pause', True) # Mettre VLC en pause + play_sound('coin.mp3') # Son de canard au premier buzz + order.append(button_id) # Ajouter le boîtier à la liste d'ordre + print(f"Boîtiers en ordre: {order}") + + # Notification au bouton premier dans l'ordre + if order[0] == button_id: + notify_button(button_ips[button_id], '/on') # Envoyer /on + + # Notifier tous les autres boutons enregistrés avec /off + for other_button_id, ip in button_ips.items(): + if other_button_id != button_id: + notify_button(ip, '/off') # Envoyer /off + + response_message = {"message": "added"} # Réponse pour l'ajout à l'ordre else: - response_message = {"message": "second"} - # print(f"{button_id} is second") - else: - response_message = {"message": "duplicate"} # Requête répétée, rejetée + response_message = {"message": "duplicate"} # Requête répétée, rejetée - return jsonify(response_message), 200 + return jsonify(response_message), 200 + + else: + return jsonify({"message": "not allowed"}), 200 def good_answer(): + global INGAME while True: - # Attendre que la touche 'r' soit pressée pour vider l'ordre + # Attendre que la touche 'o' soit pressée pour vider l'ordre keyboard.wait('o') with lock: - fastest = None # Réinitialiser le gagnant if order: + INGAME = False print(f"--- Boîtier {order[0]} gagne ! ---") - order.clear() # Enlever le premier boîtier de l'ordre - #seek_to_time('') - send_vlc_command('pl_play') + play_sound('victory.mp3') + # Envoyer /off à tous les boutons + for button, ip in button_ips.items(): + notify_button(ip, '/off') # Envoi de /off aux boutons + order.clear() # Vider l'ordre + time.sleep(1) + send_vlc_command('pl_play') # Reprendre la musique def incomplet_answer(): - global fastest while True: - # Attendre que la touche 'r' soit pressée pour vider l'ordre + # Attendre que la touche 'x' soit pressée pour enlever le premier boîtier keyboard.wait('x') with lock: - fastest = None # Réinitialiser le gagnant if order: - print(f"Boîtier {order[0]} : Réponse incomplète") + # Vérifier si le premier boîtier est retiré + first_button = order[0] + print(f"Boîtier {first_button} : Réponse incomplète") order.pop(0) # Enlever le premier boîtier de l'ordre print(f"Boîtiers en ordre: {order}") - if not order: - send_vlc_command('pl_play') -def no_answer(): - global fastest - while True: - # Attendre que la touche 'r' soit pressée pour vider l'ordre - keyboard.wait('p') - - with lock: - fastest = None # Réinitialiser le gagnant - if order: - print(f"Boîtier {order[0]} : Pas de réponse") - order.pop(0) # Enlever le premier boîtier de l'ordre - print(f"Boîtiers en ordre: {order}") + # Si le bouton retiré était le premier, lui envoyer /off + notify_button(button_ips[first_button], '/off') + + # Si le second boîtier devient le premier, envoyer /on + if order: + second_button = order[0] + notify_button(button_ips[second_button], '/on') + if not order: - send_vlc_command('pl_play') + # Envoyer /blink à tous les boutons + send_vlc_command('pl_play') # Reprendre la musique + for button, ip in button_ips.items(): + notify_button(ip, '/blink') def next_song(): - global fastest + global INGAME while True: - # Attendre que la touche 'r' soit pressée pour vider l'ordre - keyboard.wait('n') - print("Are you sure to next ?") + # Attendre que la touche 'n' soit pressée pour demander le prochain son keyboard.wait('n') + send_vlc_command('pl_pause') + for button, ip in button_ips.items(): + notify_button(ip, '/off') + time.sleep(1) + play_sound('bell.mp3') + print("Music - Next in 2 seconds") + time.sleep(2) + send_vlc_command('pl_next') # Passer à la chanson suivante + INGAME = True with lock: - fastest = None # Réinitialiser le gagnant - if order: - order.pop(0) # Enlever le premier boîtier de l'ordre - print('Next song') - send_vlc_command('pl_next') + # Si order est vide, envoyer /blink à tous les boutons + if not order: + for button, ip in button_ips.items(): + notify_button(ip, '/blink') # Envoyer /blink à tous les boutons + send_vlc_command('pl_play') # Reprendre la musique + +def play(): + while True: + # Attendre que la touche 'space' soit pressée pour mettre VLC en pause + keyboard.wait('m') + print("Music - Play") + send_vlc_command('pl_play') def pause(): while True: - # Attendre que la touche 'r' soit pressée pour vider l'ordre - keyboard.wait('space') + # Attendre que la touche 'space' soit pressée pour mettre VLC en pause + keyboard.wait('p') + print("Music - Pause") send_vlc_command('pl_pause', True) +def light_on(): + while True: + keyboard.wait('r') + print("Buzzer light - On") + for button, ip in button_ips.items(): + notify_button(ip, '/on') + +def light_blink(): + while True: + keyboard.wait('t') + print("Buzzer light - Blink") + for button, ip in button_ips.items(): + notify_button(ip, '/blink') + +def light_off(): + while True: + keyboard.wait('y') + print("Buzzer light - Off") + for button, ip in button_ips.items(): + notify_button(ip, '/off') + +def buzzer_on(): + global INGAME + while True: + keyboard.wait('f') + INGAME = True + print("Buzzer - Enable") + for button, ip in button_ips.items(): + notify_button(ip, '/blink') + +def buzzer_off(): + global INGAME + while True: + keyboard.wait('h') + INGAME = False + print("Buzzer - Disable") + for button, ip in button_ips.items(): + notify_button(ip, '/off') + if __name__ == '__main__': print("Serveur démarré") + init_mixer() threading.Thread(target=good_answer, daemon=True).start() threading.Thread(target=incomplet_answer, daemon=True).start() - threading.Thread(target=no_answer, daemon=True).start() threading.Thread(target=next_song, daemon=True).start() + threading.Thread(target=play, daemon=True).start() threading.Thread(target=pause, daemon=True).start() + threading.Thread(target=light_on, daemon=True).start() + threading.Thread(target=light_off, daemon=True).start() + threading.Thread(target=light_blink, daemon=True).start() + threading.Thread(target=buzzer_on, daemon=True).start() + threading.Thread(target=buzzer_off, daemon=True).start() + + INGAME = True + print("Buzzer - Enable") + for button, ip in button_ips.items(): + notify_button(ip, '/blink') - serve(app, host='0.0.0.0', port=5000) + serve(app, host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/Python/victory.mp3 b/Python/victory.mp3 new file mode 100644 index 0000000..ef3e6f6 Binary files /dev/null and b/Python/victory.mp3 differ diff --git a/Python/vlc_control.py b/Python/vlc_control.py index 1b35d17..7c56025 100644 --- a/Python/vlc_control.py +++ b/Python/vlc_control.py @@ -1,4 +1,5 @@ import requests +import time # Configurer l'adresse et le port de l'interface Web de VLC VLC_WEB_URL = 'http://localhost:8080' @@ -48,4 +49,37 @@ def seek_to_time(minutes, seconds): # Convertir le temps en secondes total_seconds = minutes * 60 + seconds send_vlc_command(f'seek&val={total_seconds}') - \ No newline at end of file + +def decrease_volume(): + """ + Decrease the volume of VLC to 0 with fixed step and duration. + """ + if not is_vlc_running(): + print(f"VLC n'est pas accessible à {VLC_WEB_URL}. Assurez-vous que VLC est ouvert et que l'interface Web est activée.") + return + + try: + # Récupérer le volume actuel + status = get_vlc_status() + if status is None: + return + current_volume = int(status.get('volume', 256)) + + # Paramètres fixes + step_duration = 0.5 # Durée en secondes entre chaque diminution de volume + volume_step = 5 # Diminution du volume par étape + + while current_volume > 0: + current_volume -= volume_step + if current_volume < 0: + current_volume = 0 + send_vlc_command(f'volume&val={int(current_volume)}') + time.sleep(step_duration) + + # S'assurer que le volume est à 0 + send_vlc_command('volume&val=0') + if DEBUG: + print("Volume baissé à 0.") + except requests.RequestException as e: + if DEBUG: + print(f"Erreur lors de la diminution du volume : {e}") \ No newline at end of file