Import initial du projet shipheart_appli
This commit is contained in:
@@ -0,0 +1,568 @@
|
||||
//**********************************************************************************************************************************************************************************
|
||||
// Fichier EVENTS.C
|
||||
//
|
||||
// Contient toutes les fonctions liées à la gestion des évènements
|
||||
//**********************************************************************************************************************************************************************************/
|
||||
|
||||
//#define __DEBUG_EVENTS //Décommenter cette ligne pour avoir les messages de debug des évènements
|
||||
|
||||
// Includes :
|
||||
#include "main.h"
|
||||
|
||||
// Prototypes :
|
||||
int8_t init_events(void);
|
||||
void gestion_events(void);
|
||||
void gestion_event(uint16_t no_event, uint8_t jour, uint8_t heure, uint8_t minute);
|
||||
bool test_event(uint16_t no_event);
|
||||
int8_t declenchement_event(uint16_t no_event);
|
||||
|
||||
// Variables globales :
|
||||
struct Struct_events events;
|
||||
|
||||
|
||||
/**********************************************************************************************************************************************************************************
|
||||
Fonction INIT_EVENTS
|
||||
|
||||
Fonction d'initialisation des évènements
|
||||
**********************************************************************************************************************************************************************************/
|
||||
int8_t init_events(void)
|
||||
{
|
||||
|
||||
events.sequenceur.etat = ETAT_SEQUENCEUR_EVENTS_INIT;
|
||||
events.sequenceur.compteur = EVENTS_TEMPO_INIT;
|
||||
events.sequenceur.compteur_time_out = 0;
|
||||
|
||||
events.derniere_minute_traitee = 60; // Valeur volontairement hors limite pour forcer le premier traitement.
|
||||
|
||||
// Affichage du message de débug :
|
||||
affichage_debug(__FILE__, __LINE__, "Initialisation des évènements\t: OK", TYPE_MESSAGE_DEBUG_OK);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
//==================================================================================================================================================================
|
||||
// Fonction : Appelée en tâche de fond, cette fonction gère les févènements dans leur ensemble
|
||||
// Reçoit : Rien
|
||||
// Renvoit : Rien
|
||||
//==================================================================================================================================================================
|
||||
void gestion_events(void)
|
||||
{
|
||||
uint16_t i;
|
||||
time_t now;
|
||||
struct tm tm_now;
|
||||
uint8_t jour;
|
||||
uint8_t heure;
|
||||
uint8_t minute;
|
||||
bool test_temp;
|
||||
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
|
||||
|
||||
|
||||
|
||||
switch(events.sequenceur.etat)
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENTS_INIT :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
if (events.sequenceur.compteur == 0)
|
||||
{
|
||||
events.sequenceur.etat = ETAT_SEQUENCEUR_EVENTS_REPOS;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENTS_REPOS :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
if (events.sequenceur.compteur == 0)
|
||||
{
|
||||
events.sequenceur.compteur = EVENTS_PERIODE_CHECK; // A priori, toutes les 100ms
|
||||
|
||||
//=====================================================================
|
||||
// Préparation des conditions horaires :
|
||||
jour = 0; // Permet de savoir, in fine, si les conditions horaire sont applicables (>0) ou pas (0).
|
||||
heure = 0;
|
||||
minute = 0;
|
||||
|
||||
if (++ events.compteur_diviseur_conditions_horaires >= EVENTS_DIVISEUR_CONDITIONS_HORAIRES)
|
||||
{
|
||||
events.compteur_diviseur_conditions_horaires = 0; // A priori, toutes les 1s
|
||||
|
||||
now = time (NULL); // Génère le timestamp de l'heure courante (UTC)
|
||||
now += (systeme.fuseau_horaire + systeme.heure_ete) * 60 * 60; // Passage en heure locale
|
||||
tm_now = *localtime (&now); // Convertit le timestamp en une structure lisible
|
||||
|
||||
if (events.derniere_minute_traitee != tm_now.tm_min) // A priori, toutes les minutes, à 00s
|
||||
{
|
||||
jour = tm_now.tm_wday;
|
||||
if (jour == 0) jour = 7; // de lundi (1) à dimanche (7)
|
||||
heure = tm_now.tm_hour; // de 0 à 23
|
||||
minute = tm_now.tm_min; // de 0 à 59
|
||||
|
||||
events.derniere_minute_traitee = minute; // Pour utilisation lors des boucles suivantes
|
||||
|
||||
#ifdef __DEBUG_EVENTS
|
||||
sprintf(tmp, "Traitement horaire des Events avec Jour=%i, Heure=%i et Minutes=%i", jour, heure, minute);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
// Appel du gestionnaire de chaque event valide :
|
||||
for (i = 0; i < events.nb; i ++)
|
||||
{
|
||||
if (!events.events[i].flag_validite) continue; // Si l'event n'est pas valide, on ne le traite pas
|
||||
|
||||
// Calcul du résultat du test dès lors que l'event en contient un :
|
||||
// Cela permet d'abord de mettre à jour son état dans la BDD et être utilisé par Qt.
|
||||
// Cela permet aussi de ne plus le calculer dans la suite du traitement.
|
||||
if (events.events[i].condition_test.flag_validite)
|
||||
{
|
||||
test_temp = test_event(i);
|
||||
if (events.events[i].condition_test.etat_test != test_temp)
|
||||
{
|
||||
events.events[i].condition_test.etat_test = test_temp;
|
||||
events.events[i].flag_dde_maj_bdd = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Traitement de l'event :
|
||||
gestion_event(i, jour, heure, minute); // Rappel : si les conditions horaires ne sont PAS applicables, 'jour == 0'
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
default :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
sprintf(tmp, "L'état du séquenceur EVENTS est inconnu [%i]. Il est repositionné au REPOS", events.sequenceur.etat);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
||||
events.sequenceur.etat = ETAT_SEQUENCEUR_EVENTS_REPOS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==================================================================================================================================================================
|
||||
// Fonction : Traite le séquenceur de test d'un évènement
|
||||
// Reçoit : le n° de l'évènement
|
||||
// Renvoit : Rien
|
||||
//==================================================================================================================================================================
|
||||
void gestion_event(uint16_t no_event, uint8_t jour, uint8_t heure, uint8_t minute)
|
||||
{
|
||||
uint16_t i;
|
||||
bool flag_repetition;
|
||||
uint8_t compteur_repetitions; // Sécurite...
|
||||
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
|
||||
|
||||
compteur_repetitions = 0;
|
||||
|
||||
do {
|
||||
flag_repetition = false; // Par défaut. Une éventuelle répétition doit être demandée explicitement.
|
||||
|
||||
switch(events.events[no_event].sequenceur.etat)
|
||||
{
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENT_INIT :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
if (events.events[no_event].sequenceur.compteur == 0)
|
||||
{
|
||||
// SDIR #68 (début) :
|
||||
if (events.events[no_event].conditions_horaires.nb == 0) // S'il n'y a acune condition horaire :
|
||||
{
|
||||
// NB : la valeur de 'etat_test' a été mise à jour juste avant l'appel de 'gestion_event()' ci-dessus...
|
||||
if (events.events[no_event].condition_test.etat_test) events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_ATTENTE_DESACTIVATION; // Si la condition est déjà vraie au démarrage, on passe en phase d'attenet du retour à False avant de traiter le premier front d'apparition.
|
||||
else events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_REPOS; // Si la condition est False, on peut dès à présent attendre le premier front.
|
||||
}
|
||||
else events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_REPOS; // S'il y a une ou plusieurs conditions horaires, on passe au repos dans tous les cas, en attente de la condition horaire pour faire le premier test.
|
||||
// SDIR #68 (fin)
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENT_REPOS :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
//====================================================
|
||||
// Conditions horaire :
|
||||
if (events.events[no_event].conditions_horaires.nb > 0) // Cet event a une condition horaire (au moins une)
|
||||
{
|
||||
if (jour > 0) // Dans ce cas, on sait que les conditions horaires doivent être testées
|
||||
{
|
||||
// Parcours de toutes les conditions horaires de l'évent :
|
||||
for (i = 0; i < events.events[no_event].conditions_horaires.nb; i ++)
|
||||
{
|
||||
if (!events.events[no_event].conditions_horaires.conditions[i].flag_validite) continue;
|
||||
|
||||
// Test du jour :
|
||||
if ((events.events[no_event].conditions_horaires.conditions[i].jour != JOUR_SEMAINE_TOUS_LES_JOURS) &&
|
||||
(events.events[no_event].conditions_horaires.conditions[i].jour != jour)) continue;
|
||||
|
||||
// Test de l'heure et de la minute :
|
||||
if (events.events[no_event].conditions_horaires.conditions[i].heure < 24) // La condition correspond à une heure normale :
|
||||
{
|
||||
if (events.events[no_event].conditions_horaires.conditions[i].heure != heure) continue;
|
||||
if (events.events[no_event].conditions_horaires.conditions[i].minute != minute) continue;
|
||||
}
|
||||
else // La condition correspond à une heure spéciale :
|
||||
{
|
||||
if (systeme.heures_speciales[events.events[no_event].conditions_horaires.conditions[i].heure - 24].heures != heure) continue; // Comparaison entre 'heure' de l'heure spéciale et 'heure' actuelle
|
||||
if (systeme.heures_speciales[events.events[no_event].conditions_horaires.conditions[i].heure - 24].minutes != minute) continue; // Comparaison entre 'minute' de l'heure spéciale et 'minute' actuelle
|
||||
}
|
||||
#ifdef __DEBUG_EVENTS
|
||||
sprintf(tmp, "Event #%i / condition #%i : Condition horaire validée", no_event, i);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);
|
||||
#endif
|
||||
// Le déclenchement horaire est validé :
|
||||
if (events.events[no_event].condition_test.flag_validite) // Si l'event comprend un test :
|
||||
{
|
||||
// Test de la condition :
|
||||
if (events.events[no_event].condition_test.etat_test)
|
||||
{
|
||||
#ifdef __DEBUG_EVENTS
|
||||
sprintf(tmp, "Event #%i / condition #%i : Résultat du test = TRUE. Lancement de la Tempo (%i sec.)", no_event, i, events.events[no_event].sequenceur.compteur = events.events[no_event].tempo);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);
|
||||
#endif
|
||||
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_LANCEMENT_TEMPO;
|
||||
flag_repetition = true; // Permet le traitement du déclenchement sans attendre.
|
||||
}
|
||||
#ifdef __DEBUG_EVENTS
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "Event #%i / condition #%i : Résultat du test = FALSE ", no_event, i);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else // Si l'event ne comprend pas de test :
|
||||
{
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_DECLENCHEMENT;
|
||||
flag_repetition = true; // Permet le traitement du déclenchement sans attendre.
|
||||
#ifdef __DEBUG_EVENTS
|
||||
sprintf(tmp, "Event #%i / condition #%i : L'évènement ne comprend pas de test. Il est donc considéré comme déclenché (quelle que soit la valeur de Tempo [qui est de %i sec.])", no_event, i, events.events[no_event].sequenceur.compteur = events.events[no_event].tempo);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
break; // Si une condition horaire est valide sur cet event, on ne traite pas la suite (quel que soit le résultat du test horaire lui-même)
|
||||
}
|
||||
|
||||
|
||||
//====================================================
|
||||
// Test sans condition horaire :
|
||||
if (events.events[no_event].condition_test.flag_validite)
|
||||
{
|
||||
if (events.events[no_event].compteur_diviseur_gestion > 0) events.events[no_event].compteur_diviseur_gestion --;
|
||||
if (events.events[no_event].compteur_diviseur_gestion == 0)
|
||||
{
|
||||
events.events[no_event].compteur_diviseur_gestion = events.events[no_event].diviseur_gestion; // Rechargement du diviseur (sans effet si 'diviseur' = 0 ou 1)
|
||||
|
||||
// Test de la condition :
|
||||
if (events.events[no_event].condition_test.etat_test)
|
||||
{
|
||||
#ifdef __DEBUG_EVENTS
|
||||
sprintf(tmp, "Event #%i : Résultat du test = TRUE. Lancement de la Tempo (%i sec.)", no_event, events.events[no_event].sequenceur.compteur = events.events[no_event].tempo);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);
|
||||
#endif
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_LANCEMENT_TEMPO;
|
||||
flag_repetition = true; // Permet le traitement du déclenchement sans attendre.
|
||||
}
|
||||
#ifdef __DEBUG_EVENTS
|
||||
else
|
||||
{
|
||||
sprintf(tmp, "Event #%i : Résultat du test = FALSE ", no_event);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENT_LANCEMENT_TEMPO :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
// Armement de la tempo si une tempo est demandée :
|
||||
if (events.events[no_event].tempo > 0)
|
||||
{
|
||||
events.events[no_event].sequenceur.compteur = events.events[no_event].tempo * 10; // Passage de secondes en x100ms du compteur
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_ATTENTE_FIN_TEMPO;
|
||||
}
|
||||
// ou déclenchement direct si aucune tempo n'est demandée :
|
||||
else
|
||||
{
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_DECLENCHEMENT;
|
||||
flag_repetition = true; // Permet le traitement du déclenchement sans attendre.
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENT_ATTENTE_FIN_TEMPO :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
if (events.events[no_event].sequenceur.compteur == 0)
|
||||
{
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_DECLENCHEMENT;
|
||||
flag_repetition = true; // Permet de traiter le déclenchement dans la foulé, sana attendre le prochain appel au gestyionnaire d'évènements
|
||||
}
|
||||
else
|
||||
{
|
||||
// Test d'une éventuelle désactivation de l'Event avant la fin de la tempo :
|
||||
if (!events.events[no_event].condition_test.etat_test)
|
||||
{
|
||||
sprintf(tmp, "L'état de l'évènement #%i est revenu à FAUX avant l'expiration de sa temporisation [%i secondes]. Il est repositionné au REPOS sans déclenchement.", no_event, events.events[no_event].tempo);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
|
||||
|
||||
events.events[no_event].sequenceur.compteur = 0; // RAZ du compteur qui n'est plus utile
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_REPOS; // Retour au repos
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENT_DECLENCHEMENT :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
sprintf(tmp, "Déclenchement de l'évènement # %i [clé_primaire = %i]", no_event, events.events[no_event].cle_primaire);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);
|
||||
|
||||
declenchement_event(no_event);
|
||||
|
||||
if (events.events[no_event].conditions_horaires.nb > 0) events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_REPOS; // S'il y a condition horaire, on revient directement au repos, en attente de la prochaine condition horaire.
|
||||
else events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_ATTENTE_DESACTIVATION; // S'il n'y a PAS de condition horaire, on est obligé d'attendre la disparition de la condition avant de revenir au repos.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
case ETAT_SEQUENCEUR_EVENT_ATTENTE_DESACTIVATION :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
// Vérifie que la condition de l'évènement a disparue :
|
||||
if (!events.events[no_event].condition_test.etat_test)
|
||||
{
|
||||
#ifdef __DEBUG_EVENTS
|
||||
sprintf(tmp, "Event #%i : La condition de test est repassée à False. Le séquenceur repasse au repos.", no_event);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);
|
||||
#endif
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_REPOS; // Retour au repos
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
default :
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
sprintf(tmp, "L'état du séquenceur EVENT est inconnu [%i]. Il est repositionné au REPOS", events.events[no_event].sequenceur.etat);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
||||
events.events[no_event].sequenceur.etat = ETAT_SEQUENCEUR_EVENT_REPOS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while ((flag_repetition) && (compteur_repetitions ++ < MAX_REPETITIONS_SEQUENCEUR_EVENT));
|
||||
|
||||
|
||||
// Message d'erreur si le nombre de répétitions est trop élevé :
|
||||
if (compteur_repetitions >= MAX_REPETITIONS_SEQUENCEUR_EVENT)
|
||||
{
|
||||
sprintf(tmp, "Le séquenceur EVENT a rencontré un nombre de répétitions trop élevé [%i] pour l'évènement #%i et à l'état du séquenceur %i. Les répétitions sur cet event sont arrêtées de façon forcée.", MAX_REPETITIONS_SEQUENCEUR_EVENT, no_event, events.events[no_event].sequenceur.etat);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************************************************************************
|
||||
// Fonction : Teste si la condition de l'évènement est vraie ou fausse
|
||||
// Reçoit : Le numéro de l'évènement
|
||||
// Retourne : Vrai ou Faux
|
||||
//**********************************************************************************************************************************************************************************
|
||||
bool test_event(uint16_t no_event)
|
||||
{
|
||||
float valeur;
|
||||
|
||||
|
||||
// Si l'event ne contient aucune condition de test, on retourne directement FALSE :
|
||||
if (!events.events[no_event].condition_test.flag_validite) return (false);
|
||||
|
||||
//==================================================
|
||||
// Recherche de la valeur en cours de la source :
|
||||
switch(events.events[no_event].condition_test.type_source)
|
||||
{
|
||||
case SOURCE_MESURE_CIRCUIT:
|
||||
{
|
||||
valeur = circuits.circuits[events.events[no_event].condition_test.no_source].variables[events.events[no_event].condition_test.no_variable].valeur_courante;
|
||||
break;
|
||||
}
|
||||
case SOURCE_MESURE_CAPTEUR:
|
||||
{
|
||||
valeur = capteurs.capteurs[events.events[no_event].condition_test.no_source].variables[events.events[no_event].condition_test.no_variable].valeur_courante;
|
||||
break;
|
||||
}
|
||||
case SOURCE_MESURE_RESERVOIR:
|
||||
{
|
||||
valeur = reservoirs.reservoirs[events.events[no_event].condition_test.no_source].variables[events.events[no_event].condition_test.no_variable].valeur_courante;
|
||||
break;
|
||||
}
|
||||
case SOURCE_MESURE_BATTERIE:
|
||||
{
|
||||
valeur = batteries.batteries[events.events[no_event].condition_test.no_source].variables[events.events[no_event].condition_test.no_variable].valeur_courante;
|
||||
break;
|
||||
}
|
||||
default: return(false); // Ne devrait pas arriver puisqu'on a renvoyé FALSE pour les Event ne contenant que des conditions horaires...
|
||||
}
|
||||
#ifdef __DEBUG_EVENTS
|
||||
/* char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
|
||||
sprintf(tmp, "Test de l'évent #%i : Type_source=%i, N° source=%i, N° de variable=%i, Valeur= %.2f, Condition de test=%i",
|
||||
no_event,
|
||||
events.events[no_event].condition_test.type_source,
|
||||
events.events[no_event].condition_test.no_source,
|
||||
events.events[no_event].condition_test.no_variable,
|
||||
valeur,
|
||||
events.events[no_event].condition_test.test);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
|
||||
*/
|
||||
#endif
|
||||
|
||||
//==================================================
|
||||
// Test selon le type de test de l'évènement :
|
||||
switch(events.events[no_event].condition_test.test)
|
||||
{
|
||||
//-------------------------------------
|
||||
case EVENTS_TYPE_TEST_STRICT_INFERIEUR:
|
||||
{
|
||||
return (valeur < events.events[no_event].condition_test.seuil);
|
||||
break;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
case EVENTS_TYPE_TEST_INFERIEUR_OU_EGAL:
|
||||
{
|
||||
return (valeur <= events.events[no_event].condition_test.seuil);
|
||||
break;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
case EVENTS_TYPE_TEST_EGAL:
|
||||
{
|
||||
return (fabs(valeur - events.events[no_event].condition_test.seuil) < FLT_MIN);
|
||||
break;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
case EVENTS_TYPE_TEST_SUPERIEUR_OU_EGAL:
|
||||
{
|
||||
return (valeur >= events.events[no_event].condition_test.seuil);
|
||||
break;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
case EVENTS_TYPE_TEST_STRICT_SUPERIEUR:
|
||||
{
|
||||
return (valeur > events.events[no_event].condition_test.seuil);
|
||||
break;
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
default:
|
||||
case EVENTS_TYPE_TEST_NON_DEFINI :
|
||||
{
|
||||
return (false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************************************************************************************************
|
||||
// Fonction : Traite le déclenchement d'un event
|
||||
// Reçoit : Le numéro de l'évènement
|
||||
// Retourne : 0 si Ok, -1 si erreur
|
||||
//**********************************************************************************************************************************************************************************
|
||||
int8_t declenchement_event(uint16_t no_event)
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t no_circuit;
|
||||
uint8_t consigne;
|
||||
char chaine[20];
|
||||
|
||||
// Parcours de toutes les 'action_circuits' configurées sur cet event :
|
||||
for (i = 0; i < events.events[no_event].action_circuits.nb; i ++)
|
||||
{
|
||||
if (!events.events[no_event].action_circuits.action[i].flag_validite) continue; // On ne traite que les actions valides
|
||||
|
||||
no_circuit = events.events[no_event].action_circuits.action[i].no_circuit; // Facilite la lecture...
|
||||
|
||||
if (circuits.circuits[no_circuit].validation_cdes_events == CIRCUIT_VALIDATION_COMMANDES_EVENTS_OFF) continue; // Si le circuit concerné a son flag 'Validite_cdes_events' à FALSE, on ne fait aucune action dessus.
|
||||
|
||||
// Calcul de la nouvelle consigne :
|
||||
if (events.events[no_event].action_circuits.action[i].action == EVENTS_TYPE_ACTION_CIRCUIT_TOGGLE)
|
||||
{
|
||||
if (circuits.circuits[no_circuit].variables[CIRCUIT_VARIABLE_CONSIGNE].valeur_courante != 0) consigne = 0;
|
||||
else consigne = MAX_CONSIGNE_CIRCUIT;
|
||||
}
|
||||
else consigne = events.events[no_event].action_circuits.action[i].action;
|
||||
|
||||
// Application de la nouvelle consigne :
|
||||
changement_consigne_circuit(no_circuit, consigne, CIRCUITS_ORIGINE_CONSIGNE_EVENT, events.events[no_event].cle_primaire);
|
||||
|
||||
#ifdef __DEBUG_EVENTS
|
||||
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
|
||||
sprintf(tmp, "Event #%i : Consigne = %i appliquée sur circuit n° %i (clé_primaire=%i)", no_event, consigne, no_circuit, circuits.circuits[no_circuit].cle_primaire);
|
||||
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
|
||||
#endif
|
||||
|
||||
// Enregistrement historique du changement de consigne du circuit :
|
||||
enregistrement_historique(TYPE_SOURCE_HISTORIQUE_CIRCUITS, CIRCUIT_ACTION_EVENT, circuits.circuits[no_circuit].cle_primaire, events.events[no_event].cle_primaire, NULL);
|
||||
}
|
||||
|
||||
// Enregistrement historique :
|
||||
enregistrement_historique(TYPE_SOURCE_HISTORIQUE_EVENTS, EVENT_DECLENCHEMENT, events.events[no_event].cle_primaire, 0, NULL);
|
||||
|
||||
// Alarme message :
|
||||
if (events.events[no_event].alarme_message > 0)
|
||||
{
|
||||
sprintf(chaine, "%i", events.events[no_event].cle_primaire); // Paramètres = 'id_event'
|
||||
enregistrement_message_users(MESSAGE_USERS_CODE_DECLENCHEMENT_EVENT, chaine, MESSAGE_USERS_ETAT_ALERTE);
|
||||
}
|
||||
|
||||
// Alarme son :
|
||||
if (events.events[no_event].alarme_son > 0)
|
||||
{
|
||||
emission_bip("button-35.mp3", 5, 15, 20);
|
||||
}
|
||||
|
||||
// Alarme LED :
|
||||
if (events.events[no_event].alarme_led > 0)
|
||||
{
|
||||
c_bus_down_commande_cde_carte(0, C_BUS_COMMANDE_CDE_CARTE_ETAT_SYSTEME, C_BUS_COMMANDE_CDE_CARTE_ETAT_SYSTEME_ALARME);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user