13 Commits

Author SHA1 Message Date
6c4c7f1bc4 Ajustement de l'interface de console MQTT, couleur appliqués au Topic et Msg pour bien trancher toute la ligne (plus facile à lire) 2024-11-10 11:47:32 +01:00
08c8f85921 Déplacement du bouton publier pour qu'il soit en desous du color picker + Changement du scrolldown sur la page du debbuger, désormais lors du scrolldown, la console MQTT reste docked, donc la console ne remonte plus. Ouais je sais c'est génal 2024-11-09 13:42:20 +01:00
25ee22bfbf Déplacement du bouton publier pour qu'il soit en desous du color picker + Changement du scrolldown sur la page du debbuger, désormais lors du scrolldown, la console MQTT reste docked, donc la console ne remonte plus. Ouais je sais c'est génal 2024-11-09 13:30:39 +01:00
445a1b883f Ajout des boutons a cotés du color picker pour publier les couleurs d'équipe 2024-11-09 11:31:30 +01:00
62bd29d752 Ajout du colorpicker sur la page de débug 2024-11-05 18:26:59 +01:00
dd72e02370 Activation de la console MQTT dans le debugger 2024-11-05 17:36:20 +01:00
561b8b9820 test light manager 2024-11-01 21:16:31 +00:00
ff1b546f0c passe en rainbow quand on débloque (au pif) 2024-11-01 21:15:40 +00:00
1cf9266dcb buzzer(doc): ajoute mémo pour compilation en ligne de commande 2024-11-01 21:13:38 +00:00
2a5fb6c613 buzzer: Envoi un message complet sur le bon topic 2024-11-01 21:13:05 +00:00
9147b40d47 2eme iteration 2024-11-01 17:52:57 +00:00
fe7001effc première iteration du buzzer-manager 2024-11-01 17:52:57 +00:00
9a47dc6633 Ajour du code du buzzeré 2024-10-07 21:40:28 +02:00
8 changed files with 417 additions and 22 deletions

31
buzzer/README.md Normal file
View File

@ -0,0 +1,31 @@
# buzzer
Code arduino du buzzer
## memo arduino-cli
Pour Compilation en ligne de commande.
### Configuration
Après installation d'arduino
```sh
arduino-cli config init
arduino-cli config add board_manager.additional_urls http://arduino.esp8266.com/stable/package_esp8266com_index.json
arduino-cli core update-index
arduino-cli core install esp8266:esp8266
arduino-cli lib install PubSubClient
```
### Compilation
```sh
arduino-cli compile --fqbn esp8266:esp8266:nodemcuv2 buzzer.ino
```
### Envoi vers l'ESP
```sh
arduino-cli upload -p /dev/ttyUSB0 --fqbn esp8266:esp8266:nodemcuv2 buzzer.ino
```

68
buzzer/buzzer.ino Normal file
View File

@ -0,0 +1,68 @@
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// Configurations WiFi et MQTT
const char* ssid = "Redmi Note 13 Pro 5G";
const char* password = "1234567890";
const char* mqtt_server = "192.168.127.208";
const char* mqtt_topic = "brainblast/buzzer/pressed/1";
const char* mqtt_message = "{\"buzzer_id\": 1, \"color\": \"#FF7518\"}";
// Déclaration des broches
#define BUTTON_PIN D8
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connexion au WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connecté");
Serial.print("Adresse IP: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
Serial.print("Connexion au broker MQTT...");
if (client.connect("ESP8266Client")) {
Serial.println("connecté");
} else {
Serial.print("échec, rc=");
Serial.print(client.state());
Serial.println("; nouvelle tentative dans 5 secondes");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP);
setup_wifi();
client.setServer(mqtt_server, 1883);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
// Vérifier si le bouton est pressé
if (digitalRead(BUTTON_PIN) == HIGH) {
Serial.println("Bouton pressé, envoi du message...");
client.publish(mqtt_topic, mqtt_message);
delay(200); // Anti-rebond pour éviter les publications multiples
}
}

View File

@ -194,6 +194,12 @@ client.on('message', (topic, message) => {
message: "Buzzer unlock command received.",
timestamp: new Date().toISOString()
}));
// Notify the light manager to change to the team's color
client.publish('brainblast/light/change', JSON.stringify({
color: "#FFFFFF",
effect: 'rainbow'
}));
// Reset buzzer manager state
buzzerActive = false;

138
services/light-manager.js Normal file
View File

@ -0,0 +1,138 @@
// Import du module MQTT
const mqtt = require('mqtt');
// Configuration du broker MQTT et de WLED
const brokerUrl = 'mqtt://localhost'; // Change ce lien si nécessaire
const clientId = 'light_manager_wled';
const wledTopicBase = 'wled/all'; // Le topic de base pour ton ruban WLED
const options = {
clientId,
clean: true
};
// État des lumières
let currentColor = '#FFFFFF'; // Couleur par défaut (blanc)
let currentEffect = 'none'; // Pas d'effet par défaut
// Connexion au broker MQTT
const client = mqtt.connect(brokerUrl, options);
client.on('connect', () => {
console.log(`[INFO] Connected to MQTT broker ${brokerUrl} as ${clientId}`);
// Souscription aux topics de gestion de lumière
client.subscribe('brainblast/light/#', (err) => {
if (err) console.error('[ERROR] Subscription to light topics failed');
else console.log('[INFO] Successfully subscribed to light topics');
});
});
// Fonction pour envoyer un message au ruban WLED
function sendToWLED(topicSuffix, message) {
const wledTopic = `${wledTopicBase}/${topicSuffix}`;
client.publish(wledTopic, message, { qos: 1 }, (err) => {
if (err) console.error(`[ERROR] Failed to send message to WLED topic: ${wledTopic}`);
else console.log(`[INFO] Sent to WLED (${wledTopic}): ${message}`);
});
}
// Fonction pour appliquer un changement de lumière
function applyLightChange(color, effect, intensity) {
currentColor = color || currentColor;
currentEffect = effect || currentEffect;
console.log(`[INFO] Applying light change: Color=${currentColor}, Effect=${currentEffect}, Intensity=${intensity}`);
// Envoyer la couleur au ruban WLED
sendToWLED('col', currentColor);
// Appliquer l'effet si défini
if (currentEffect !== 'none') {
const effectId = getWLEDEffectId(currentEffect);
sendToWLED('api', "FX=" + effectId.toString());
}
// Régler l'intensité si spécifiée
if (intensity) {
sendToWLED('api', intensity.toString());
}
// Envoi de l'état mis à jour
sendLightStatus();
}
// Fonction pour obtenir l'ID d'effet WLED correspondant à un effet donné
function getWLEDEffectId(effect) {
const effectsMap = {
'none': 0,
'blink': 1, // Effet de fondu
'fade': 12, // Clignotement
'rainbow': 9 // Effet arc-en-ciel
};
return effectsMap[effect] || 0; // Par défaut, aucun effet
}
// Fonction pour envoyer l'état actuel des lumières sur le topic de réponse
function sendLightStatus() {
const statusMessage = JSON.stringify({
status: "updated",
color: currentColor,
effect: currentEffect,
message: `Current light state: Color=${currentColor}, Effect=${currentEffect}`,
timestamp: new Date().toISOString()
});
// Envoi de l'état à tous les clients intéressés
client.publish('brainblast/light/status/response', statusMessage);
console.log('[INFO] Light status sent to brainblast/light/status/response');
}
// Gestion des messages entrants
client.on('message', (topic, message) => {
let payload;
try {
// Analyse du message reçu
payload = JSON.parse(message.toString());
} catch (e) {
console.error(`[ERROR] Invalid JSON message received on topic ${topic}: ${message.toString()}`);
return;
}
// Changement de lumière
if (topic === 'brainblast/light/change') {
const { color, effect, intensity } = payload;
// Valider la couleur et l'effet
if (!/^#[0-9A-F]{6}$/i.test(color)) {
console.error('[ERROR] Invalid color format');
return;
}
// Appliquer le changement de lumière
applyLightChange(color, effect, intensity);
} else if (topic === 'brainblast/light/reset') {
// Réinitialisation des lumières à la couleur et l'effet par défaut
console.log('[INFO] Resetting lights to default state');
applyLightChange('#FFFFFF', 'reset', 255);
} else if (topic === 'brainblast/light/status/request') {
// Répondre à la requête de statut
console.log('[INFO] Light status request received');
sendLightStatus();
} else if (topic === 'brainblast/light/status/response') {
// Répondre à la requête de statut
console.log('[INFO] Light status response received');
} else {
console.error(`[ERROR] Unrecognized topic: ${topic}`);
}
});
// Gestion des erreurs de connexion
client.on('error', (err) => {
console.error(`[ERROR] Error connecting to broker: ${err}`);
});
console.log('[INFO] Light Manager with WLED support and status handling started...');

View File

@ -0,0 +1,95 @@
<template>
<v-container class="v-container-style">
<v-card tile outlined width="500">
<v-card-title class="card__title primary centered-title">
<v-icon left class="pr-5 pl-2" size="30">mdi-send</v-icon>
Publier une couleur
</v-card-title>
<div class="input-style">
<v-select label="Topic" v-model="selectedTopic" :items="topics" prepend-icon="mdi-target"></v-select>
</div>
<v-row>
<v-col cols="6" class="color-picker-style">
<div>
<v-color-picker mode="hex" v-model="selectedColor" border="md" width="250"></v-color-picker>
<v-btn class="v-btn-style-validate" height="35" @click="publisCustomColor">Publier</v-btn>
</div>
</v-col>
<v-col cols="5.5" class="button-container">
<v-btn color="#D42828" class="team-button" @click="publisButtonColor('#D42828')">Team Rouge</v-btn>
<v-btn color="#FF7518" class="team-button" @click="publisButtonColor('#FF7518')">Team Orange</v-btn>
<v-btn color="#00FF1F" class="team-button" @click="publisButtonColor('#00FF1F')">Team Verte</v-btn>
<v-btn color="#007AFF" class="team-button" @click="publisButtonColor('#007AFF')">Team Bleue</v-btn>
<v-btn color="#FFFC00" class="team-button" @click="publisButtonColor('#FFFC00')">Team Jaune</v-btn>
</v-col>
</v-row>
</v-card>
</v-container>
</template>
<script>
import { publishMessage } from '@/services/mqttService'
export default {
data() {
return {
message: '', // Initialiser la variable message
selectedTopic: 'Selectionnez un topic',
selectedColor: "#FF0000",
topics: [
'/wled/all',
'/wled/1',
'/wled/2',
'/wled/3',
'/wled/4',
'/wled/5'
]
}
},
methods: {
publisCustomColor() {
publishMessage(this.selectedTopic, this.selectedColor)
},
publisButtonColor(param) {
publishMessage(this.selectedTopic, param)
},
}
}
</script>
<style>
.v-container-style {
align-items: center;
justify-content: center;
}
.input-style{
margin: 20px;
}
.v-btn-style-validate{
border-top-right-radius: 0%;
border-top-left-radius: 0%;
}
.centered-title {
text-align: center;
}
.color-picker-style {
margin-left: 5%;
margin-bottom: 5%;
display: flex;
}
.button-container {
text-align: center;
margin-top: 12px;
margin-bottom: 27px;
margin-left: 15px;
margin-right: 13px;
}
.team-button {
width: 140px;
display: block;
margin: 12% auto 0; /* 5% de marge en bas pour espacer les boutons */
background-color: #d42828;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<v-container class="v-container-style">
<v-container class="v-container-style-console">
<v-card tile outlined width="500">
<v-card-title class="card__title primary centered-title">
<v-icon left class="pr-5 pl-2" size="40">mdi-console-line</v-icon>
@ -7,8 +7,9 @@
</v-card-title>
<v-container class="text-center">
<div v-for="(log, index) in messageLogs" :key="index">
<v-label class="v-label-timestamp">{{ log.timestamp }} </v-label> -
<v-label>{{ log.message }}</v-label>
<v-label class="v-label-timestamp">{{ log.timestamp }} -&nbsp;</v-label>
<v-label class="v-label-topic-message-title">Topic :&nbsp;</v-label><v-label class="v-label-topic-message">{{ log.topic }}&nbsp;</v-label>
<v-label class="v-label-topic-message-title">Msg :&nbsp;</v-label><v-label class="v-label-topic-message">{{ log.message }}</v-label>
</div>
</v-container>
</v-card>
@ -32,10 +33,11 @@
});
// Ajouter le message avec l'horodatage à la liste des messages
this.messageLogs.push({ timestamp, message: `Topic: ${topic}, Message: ${message}` });
this.messageLogs.push({ timestamp, topic: `${topic}`, message: `${message}` });
//this.messageLogs.push({ timestamp, message: `${message}` });
// Limiter la liste à 10 messages
if (this.messageLogs.length > 10) {
if (this.messageLogs.length > 26) {
this.messageLogs.shift(); // Supprimer le premier élément (le plus ancien)
} }) // S'abonner à tous les topics MQTT
}
@ -43,16 +45,28 @@
</script>
<style>
.v-container-style {
display: flex;
justify-content: center;
.v-container-style-console {
display: flex;
justify-content: center;
position: sticky;
top: 50px; /* Distance depuis le haut de la fenêtre avant de "coller" */
}
.centered-title {
text-align: center;
text-align: center;
}
.v-label-timestamp{
opacity: 100%;
font-weight: 700;
color: #d42828;
opacity: 100%;
font-style: oblique;
font-weight: 400;
color: #838383;
}
.v-label-topic-message-title{
opacity: 100%;
font-weight: 700;
color: #d42828;
}
.v-label-topic-message{
font-weight: 300;
}
</style>

View File

@ -8,7 +8,9 @@
<div class="input-style">
<v-select label="Topic" v-model="selectedTopic" :items="topics" prepend-icon="mdi-target"></v-select>
<v-text-field label="Message" v-model="message" prepend-icon="mdi-text-box"></v-text-field>
</div> <v-btn class="v-btn-style" height="50" @click="publishMessage">Publier</v-btn>
</div>
<v-btn class="v-btn-style-standalone" height="40" @click="publishBuzzerUnblock">Déblocage<br>Buzzer</v-btn>
<v-btn class="v-btn-style-validate" height="50" @click="publisCustomMessage">Publier</v-btn>
</v-card>
</v-container>
@ -19,13 +21,22 @@ import { publishMessage } from '@/services/mqttService'
export default {
data() { return { message: '', // Initialiser la variable message
selectedTopic: 'topic1',
topics: [ '/display/control', '/sound/playsound', 'topic3', 'topic4', 'topic5', 'topic6', 'topic7', 'topic8', 'topic9', 'topic10' ] // Liste des topics
selectedTopic: 'Selectionnez un topic',
topics: [
'/wled/all',
'/display/control',
'/sound/playsound'
] // Liste des topics
}
},
methods: {
publishMessage() {
publishMessage(this.selectedTopic, this.message) }
publisCustomMessage() {
publishMessage(this.selectedTopic, this.message)
},
publishBuzzerUnblock() {
publishMessage('brainblast/buzzer/unlock', "0")
}
}
}
</script>
@ -38,7 +49,12 @@ export default {
.input-style{
margin: 20px;
}
.v-btn-style{
.v-btn-style-standalone{
background-color: #d42828; /* Changez la couleur en fonction de votre thème */
margin-bottom: 5%;
margin-left: 5%;
}
.v-btn-style-validate{
align-items: center;
justify-content: center;
width: 100%;

View File

@ -1,15 +1,42 @@
<template>
<div> <!-- Zone pour publier sur MQTT --> <PublishMQTTComponent />
<!-- Zone pour afficher la console MQTT --> <MQTTConsoleComponent />
<v-row>
</v-row>
<div> <!-- Zone pour publier sur MQTT -->
<!-- Zone pour afficher la console MQTT -->
</div>
<v-container>
<v-row>
<!-- Colonne gauche avec les deux composants empilés -->
<v-col cols="6">
<!-- Composant 1 -->
<v-row>
<v-col>
<PublishMQTTComponent />
<MQTTColorPublisher />
</v-col>
</v-row>
</v-col>
<!-- Colonne droite avec le composant unique -->
<v-col cols="6">
<MQTTConsoleComponent />
</v-col>
</v-row>
</v-container>
</template>
<script>
import PublishMQTTComponent from '@/components/MQTTDebugPublish.vue' // Importer le composant pour publier sur MQTT
import MQTTConsoleComponent from '@/components/MQTTDebugConsole.vue' // Importer le composant pour la console MQTT
import MQTTConsoleComponent from '@/components/MQTTDebugConsole.vue' // Importer le composant pour publier sur MQTT
import MQTTColorPublisher from '@/components/MQTTColorPublisher.vue' // Importer le composant pour publier sur MQTT
export default {
components: { PublishMQTTComponent, // Composant pour publier sur MQTT MQTTConsoleComponent // Composant pour la console MQTT
components: {
PublishMQTTComponent, // Composant pour publier sur MQTT MQTTConsoleComponent // Composant pour la console MQTT
MQTTConsoleComponent, // Composant pour la console MQTT
MQTTColorPublisher, // Composant pour publier une couleur custom dans un topic
}
}
</script>