Création du BuzzerWatcher et mise à jour des fichiers associés
This commit is contained in:
parent
c3b975665e
commit
7e2e417191
@ -1,8 +1,92 @@
|
|||||||
<template> <div class="label-pos"> <v-label class="labelTitle-style pb-4">Scores</v-label> </div>
|
<template>
|
||||||
<!-- Équipes Rouges et Bleues côte à côte --> <v-row no-gutters class="scorebox-pos"> <!-- Équipe Rouge --> <v-col cols="6"> <!-- Colonnes de taille 6 pour chaque équipe --> <v-row no-gutters> <v-col class="scorediv-style-red"> <div> <v-label class="labelRoundScore-style pt-3">Manche</v-label> <div> <v-label class="labelRoundScore-style">{{ RedRoundScore }}</v-label> </div> </div> <v-divider color="background"/> <div> <v-label class="labelTotalScore-style pt-3">Total</v-label> <div> <v-label class="labelTotalScore-style pb-3">{{ RedTotalScore }}</v-label> </div> </div> </v-col> </v-row> </v-col>
|
<div class="label-pos">
|
||||||
<!-- Équipe Bleue --> <v-col cols="6"> <v-row no-gutters> <v-col class="scorediv-style-blue"> <div> <v-label class="labelRoundScore-style pt-3">Manche</v-label> <div> <v-label class="labelRoundScore-style">{{ BlueRoundScore }}</v-label> </div> </div> <v-divider color="background"/> <div> <v-label class="labelTotalScore-style pt-3">Total</v-label> <div> <v-label class="labelTotalScore-style pb-3">{{ BlueTotalScore }}</v-label> </div> </div> </v-col> </v-row> </v-col> </v-row>
|
<v-label class="labelTitle-style pb-4">Scores</v-label>
|
||||||
<!-- Équipes Oranges et Vertes côte à côte --> <v-row no-gutters class="scorebox-pos"> <!-- Équipe Orange --> <v-col cols="6"> <v-row no-gutters> <v-col class="scorediv-style-orange"> <div> <v-label class="labelRoundScore-style pt-3">Manche</v-label> <div> <v-label class="labelRoundScore-style">{{ OrangeRoundScore }}</v-label> </div> </div> <v-divider color="background"/> <div> <v-label class="labelTotalScore-style pt-3">Total</v-label> <div> <v-label class="labelTotalScore-style pb-3">{{ OrangeTotalScore }}</v-label> </div> </div> </v-col> </v-row> </v-col>
|
</div>
|
||||||
<!-- Équipe Verte --> <v-col cols="6"> <v-row no-gutters> <v-col class="scorediv-style-green"> <div> <v-label class="labelRoundScore-style pt-3">Manche</v-label> <div> <v-label class="labelRoundScore-style">{{ GreenRoundScore }}</v-label> </div> </div> <v-divider color="background"/> <div> <v-label class="labelTotalScore-style pt-3">Total</v-label> <div> <v-label class="labelTotalScore-style pb-3">{{ GreenTotalScore }}</v-label> </div> </div> </v-col> </v-row> </v-col> </v-row>
|
<!-- Équipes Rouges et Bleues côte à côte -->
|
||||||
|
<v-row no-gutters class="scorebox-pos"> <!-- Équipe Rouge -->
|
||||||
|
<v-col cols="6"> <!-- Colonnes de taille 6 pour chaque équipe -->
|
||||||
|
<v-row no-gutters>
|
||||||
|
<v-col class="scorediv-style-red">
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style">{{ RedRoundScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<v-divider color="background"/>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pt-3">Total</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pb-3">{{ RedTotalScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
<!-- Équipe Bleue -->
|
||||||
|
<v-col cols="6">
|
||||||
|
<v-row no-gutters>
|
||||||
|
<v-col class="scorediv-style-blue">
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style">{{ BlueRoundScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<v-divider color="background"/>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pt-3">Total</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pb-3">{{ BlueTotalScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<!-- Équipes Oranges et Vertes côte à côte -->
|
||||||
|
<v-row no-gutters class="scorebox-pos">
|
||||||
|
<!-- Équipe Orange -->
|
||||||
|
<v-col cols="6">
|
||||||
|
<v-row no-gutters>
|
||||||
|
<v-col class="scorediv-style-orange">
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style">{{ OrangeRoundScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<v-divider color="background"/>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pt-3">Total</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pb-3">{{ OrangeTotalScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
<!-- Équipe Verte -->
|
||||||
|
<v-col cols="6">
|
||||||
|
<v-row no-gutters>
|
||||||
|
<v-col class="scorediv-style-green">
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style pt-3">Manche</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelRoundScore-style">{{ GreenRoundScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<v-divider color="background"/>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pt-3">Total</v-label>
|
||||||
|
<div>
|
||||||
|
<v-label class="labelTotalScore-style pb-3">{{ GreenTotalScore }}</v-label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -22,24 +106,51 @@ const GreenRoundScore = ref(variables.GreenRoundScore);
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.label-pos { padding-top: 15px; text-align: center;
|
.label-pos {
|
||||||
|
padding-top: 15px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.labelTitle-style { font-size: 20px !important; font-weight: 500; color: #d42828 !important; opacity: 90% !important;
|
.labelTitle-style {
|
||||||
|
font-size: 20px !important;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #d42828 !important;
|
||||||
|
opacity: 90% !important;
|
||||||
}
|
}
|
||||||
.labelRoundScore-style { opacity: 100% !important; font-size: 25px !important; font-weight: 500;
|
.labelRoundScore-style {
|
||||||
|
opacity: 100% !important;
|
||||||
|
font-size: 25px !important;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.labelTotalScore-style { opacity: 100% !important; font-size: 15px !important; font-weight: 500;
|
.labelTotalScore-style {
|
||||||
|
opacity: 100% !important;
|
||||||
|
font-size: 15px !important;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.button-pos { padding-top: 10px; padding-bottom: 15px;
|
.button-pos {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 15px;
|
||||||
}
|
}
|
||||||
.scorebox-pos { text-align: center;
|
.scorebox-pos {
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.scorediv-style-red { background-color: #d42828 !important; padding: 15px; border-top-left-radius: 10%;
|
.scorediv-style-red {
|
||||||
|
background-color: #d42828 !important;
|
||||||
|
padding: 15px;
|
||||||
|
border-top-left-radius: 10%;
|
||||||
}
|
}
|
||||||
.scorediv-style-orange { background-color: #d48f28 !important; padding: 15px; border-bottom-left-radius: 10%;
|
.scorediv-style-orange {
|
||||||
|
background-color: #d48f28 !important;
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom-left-radius: 10%;
|
||||||
}
|
}
|
||||||
.scorediv-style-blue { background-color: #2867d4 !important; padding: 15px; border-top-right-radius: 10%;
|
.scorediv-style-blue {
|
||||||
|
background-color: #2867d4 !important;
|
||||||
|
padding: 15px;
|
||||||
|
border-top-right-radius: 10%;
|
||||||
}
|
}
|
||||||
.scorediv-style-green { background-color: #28d42e !important; padding: 15px; border-bottom-right-radius: 10%;
|
.scorediv-style-green {
|
||||||
|
background-color: #28d42e !important;
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom-right-radius: 10%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,41 +1,126 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-navigation-drawer width="250"> <!-- Augmenter la largeur pour deux équipes côte à côte -->
|
<v-navigation-drawer width="250">
|
||||||
<div class="label-pos">
|
<div class="label-pos">
|
||||||
<v-label class="labelTitle-style">Buzzer connectés</v-label>
|
<v-label class="labelTitle-style">Buzzer connectés</v-label>
|
||||||
</div>
|
</div>
|
||||||
<v-row no-gutters justify="space-around" class="button-pos">
|
<v-row no-gutters justify="space-around" class="button-pos">
|
||||||
<v-icon color="BuzzerRed">mdi-radiobox-marked</v-icon>
|
<v-icon v-bind:color="redBuzzerState == 1 ? 'RedBuzzer' : 'DisconnectedBuzzer'">mdi-radiobox-marked</v-icon>
|
||||||
<v-icon color="BuzzerBlue">mdi-radiobox-marked</v-icon>
|
<v-icon v-bind:color="blueBuzzerState == 1 ? 'BlueBuzzer' : 'DisconnectedBuzzer'">mdi-radiobox-marked</v-icon>
|
||||||
<v-icon color="BuzzerOrange">mdi-radiobox-marked</v-icon>
|
<v-icon v-bind:color="yellowBuzzerState == 1 ? 'YellowBuzzer' : 'DisconnectedBuzzer'">mdi-radiobox-marked</v-icon>
|
||||||
<v-icon color="BuzzerGreen">mdi-radiobox-marked</v-icon>
|
<v-icon v-bind:color="greenBuzzerState == 1 ? 'GreenBuzzer' : 'DisconnectedBuzzer'">mdi-radiobox-marked</v-icon>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-divider :thickness="2" class="border-opacity-100" color="primary"/>
|
<v-divider :thickness="2" class="border-opacity-100" color="primary"/>
|
||||||
<CardScore/>
|
<CardScore/>
|
||||||
<CardTimer/>
|
<CardTimer/>
|
||||||
</v-navigation-drawer>
|
</v-navigation-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import CardTimer from '@/components/CardTimer.vue'
|
import CardTimer from '@/components/CardTimer.vue'
|
||||||
import CardScore from '@/components/CardScore.vue'
|
import CardScore from '@/components/CardScore.vue'
|
||||||
import { ref } from 'vue'; // Import des fonctions de Vue 3
|
import { subscribeToTopic } from '@/services/mqttService'
|
||||||
import variables from '@/variables.js';
|
import { onMounted, ref, onUnmounted } from 'vue';
|
||||||
|
|
||||||
|
// États réactifs pour chaque buzzer
|
||||||
|
let redBuzzerState = ref(0);
|
||||||
|
let blueBuzzerState = ref(0);
|
||||||
|
let greenBuzzerState = ref(0);
|
||||||
|
let yellowBuzzerState = ref(0);
|
||||||
|
|
||||||
|
// État pour surveiller la connexion générale
|
||||||
|
let connectionStatus = ref("connected"); // "connected" ou "disconnected"
|
||||||
|
|
||||||
|
// Variable pour gérer le timeout global
|
||||||
|
let globalTimeoutHandle = null;
|
||||||
|
|
||||||
|
// Fonction pour réinitialiser le timeout global
|
||||||
|
function resetGlobalTimeout() {
|
||||||
|
// Effacer le timeout précédent, s'il existe
|
||||||
|
if (globalTimeoutHandle) {
|
||||||
|
clearTimeout(globalTimeoutHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redémarrer un timeout de 5 minutes (300000 ms)
|
||||||
|
globalTimeoutHandle = setTimeout(() => {
|
||||||
|
handleGlobalTimeout(); // Appel si aucun message MQTT reçu depuis 5 minutes
|
||||||
|
}, 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction à exécuter si le timeout global est atteint
|
||||||
|
function handleGlobalTimeout() {
|
||||||
|
console.log("Aucun message MQTT reçu depuis plus de 5 minutes !");
|
||||||
|
connectionStatus.value = "disconnected"; // Indiquer que la connexion est perdue
|
||||||
|
redBuzzerState.value = 0;
|
||||||
|
blueBuzzerState.value = 0;
|
||||||
|
yellowBuzzerState.value = 0;
|
||||||
|
greenBuzzerState.value = 0;
|
||||||
|
|
||||||
|
// Tu peux ajouter ici d'autres actions, comme afficher une alerte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction pour traiter chaque message reçu et réinitialiser le timeout
|
||||||
|
function handleMessage(topic, message) {
|
||||||
|
let parsedMessage;
|
||||||
|
try {
|
||||||
|
parsedMessage = JSON.parse(message);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Erreur d'analyse JSON:", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extraire les informations
|
||||||
|
const { buzzer, status } = parsedMessage;
|
||||||
|
|
||||||
|
// Mettre à jour l'état des buzzers en fonction des messages
|
||||||
|
switch (buzzer) {
|
||||||
|
case 'redBuzzerIP':
|
||||||
|
redBuzzerState.value = status === "online" ? 1 : 0;
|
||||||
|
break;
|
||||||
|
case 'blueBuzzerIP':
|
||||||
|
blueBuzzerState.value = status === "online" ? 1 : 0;
|
||||||
|
break;
|
||||||
|
case 'yellowBuzzerIP':
|
||||||
|
yellowBuzzerState.value = status === "online" ? 1 : 0;
|
||||||
|
break;
|
||||||
|
case 'greenBuzzerIP':
|
||||||
|
greenBuzzerState.value = status === "online" ? 1 : 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Réinitialiser le timeout global car un message a été reçu
|
||||||
|
connectionStatus.value = "connected"; // Rétablir le statut de connexion
|
||||||
|
resetGlobalTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
// S'abonner au topic lorsque le composant est monté
|
||||||
|
onMounted(() => {
|
||||||
|
subscribeToTopic('buzzer/watcher', (topic, message) => {
|
||||||
|
handleMessage(topic, message);
|
||||||
|
resetGlobalTimeout(); // Réinitialiser le timeout global au démarrage
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Nettoyer le timeout global lorsque le composant est démonté
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (globalTimeoutHandle) {
|
||||||
|
clearTimeout(globalTimeoutHandle);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.label-pos {
|
.label-pos {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.labelTitle-style {
|
.labelTitle-style {
|
||||||
font-size: 20px !important;
|
font-size: 20px !important;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #e91e1e !important;
|
color: #e91e1e !important;
|
||||||
opacity: 90% !important;
|
opacity: 90% !important;
|
||||||
}
|
}
|
||||||
.button-pos {
|
.button-pos {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -7,10 +7,10 @@ export default {
|
|||||||
mqttBrokerUrl: 'ws://192.168.1.78:9001',
|
mqttBrokerUrl: 'ws://192.168.1.78:9001',
|
||||||
|
|
||||||
// Buzzer
|
// Buzzer
|
||||||
redBuzzerIP: '',
|
redBuzzerIP: '192.168.73.40',
|
||||||
blueBuzzerIP: '',
|
blueBuzzerIP: '192.168.73.41',
|
||||||
orangeBuzzerIP: '',
|
orangeBuzzerIP: '192.168.73.42',
|
||||||
greenBuzzerIP: ''
|
greenBuzzerIP: '192.168.73.43'
|
||||||
|
|
||||||
// Light
|
// Light
|
||||||
};
|
};
|
||||||
|
@ -22,10 +22,12 @@ const CustomThemeDark = {
|
|||||||
warning: '#FFC107',
|
warning: '#FFC107',
|
||||||
info: '#607D8B',
|
info: '#607D8B',
|
||||||
success: '#e91e1e',
|
success: '#e91e1e',
|
||||||
BuzzerBlue: '#2867d4',
|
BlueBuzzer: '#2867d4',
|
||||||
BuzzerOrange: '#d48f28',
|
OrangeBuzzer: '#d48f28',
|
||||||
BuzzerRed: '#d42828',
|
YellowBuzzer: '#C0DE00',
|
||||||
BuzzerGreen: '#28d42e',
|
RedBuzzer: '#d42828',
|
||||||
|
GreenBuzzer: '#28d42e',
|
||||||
|
DisconnectedBuzzer: '#595959',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const CustomThemeLight = {
|
const CustomThemeLight = {
|
||||||
@ -39,10 +41,12 @@ const CustomThemeLight = {
|
|||||||
warning: '#FFC107',
|
warning: '#FFC107',
|
||||||
info: '#607D8B',
|
info: '#607D8B',
|
||||||
success: '#4CAF50',
|
success: '#4CAF50',
|
||||||
BuzzerBlue: '#2867d4',
|
BlueBuzzer: '#2867d4',
|
||||||
BuzzerOrange: '#d48f28',
|
OrangeBuzzer: '#d48f28',
|
||||||
BuzzerRed: '#d42828',
|
YellowBuzzer: '#C0DE00',
|
||||||
BuzzerGreen: '#28d42e',
|
RedBuzzer: '#d42828',
|
||||||
|
GreenBuzzer: '#28d42e',
|
||||||
|
DisconnectedBuzzer: '#595959',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
// index.js
|
|
||||||
import Vue from 'vue';
|
|
||||||
import Vuex from 'vuex';
|
|
||||||
import ping from 'ping';
|
|
||||||
|
|
||||||
Vue.use(Vuex);
|
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
|
||||||
state: {
|
|
||||||
buzzerRedState: '',
|
|
||||||
buzzerBlueState: '',
|
|
||||||
buzzerOrangeState: '',
|
|
||||||
buzzerGreenState: ''
|
|
||||||
},
|
|
||||||
mutations: {
|
|
||||||
setBuzzerRedState(state, newState) {
|
|
||||||
state.buzzerRedState = newState;
|
|
||||||
},
|
|
||||||
setBuzzerBlueState(state, newState) {
|
|
||||||
state.buzzerBlueState = newState;
|
|
||||||
},
|
|
||||||
setBuzzerOrangeState(state, newState) {
|
|
||||||
state.buzzerOrangeState = newState;
|
|
||||||
},
|
|
||||||
setBuzzerGreenState(state, newState) {
|
|
||||||
state.buzzerGreenState = newState;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
updateBuzzerStates({ commit }, { index, newState }) {
|
|
||||||
switch (index) {
|
|
||||||
case 0:
|
|
||||||
commit('setBuzzerRedState', newState);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
commit('setBuzzerBlueState', newState);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
commit('setBuzzerOrangeState', newState);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
commit('setBuzzerGreenState', newState);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.error('Index de buzzer invalide:', index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const hosts = ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4'];
|
|
||||||
|
|
||||||
async function pingHosts() {
|
|
||||||
hosts.forEach(async (host, index) => { try {
|
|
||||||
const res = await ping.promise.probe(host);
|
|
||||||
store.dispatch('updateBuzzerStates', {index, newState: res.alive ? 'ON' : 'OFF' }); }
|
|
||||||
catch (error) {
|
|
||||||
console.error(`Erreur lors du ping de ${host}:`, error.message); }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pingHosts();
|
|
||||||
|
|
||||||
module.exports = store;
|
|
Loading…
Reference in New Issue
Block a user