Files

747 lines
32 KiB
C

//**********************************************************************************************************************************************************************************
// Fichier CAPTEURS.C
//
// Contient toutes les fonctions liées aux capteurs, associé à la table TB_Capteurs de la BDD (créé en janvier 2017)
//**********************************************************************************************************************************************************************************
//#define __DEBUG_CAPTEURS // Décommenter cette ligne pour que les infos de debug soient affichées
//#define __DEBUG_CAPTEURS_CALCULES // Décommenter cette ligne pour que les infos de debug soient affichées
//#define __DEBUG_CAPTEURS_ALERTES_ALARMES // Décommenter cette ligne pour que les infos de debug soient affichées
// Include :
#include "main.h"
// Prototypes :
void gestion_capteurs(void);
int8_t init_capteurs(void);
bool test_condition_capteur_booleen(uint16_t no_capteur, uint16_t no_condition);
bool valeur_neutre_operation_booleene(uint8_t operation);
int16_t capteur_cle_primaire(uint16_t cle_primaire);
int16_t variable_capteur_cle_primaire(uint16_t cle_primaire);
// Variables globales :
struct Struct_capteurs capteurs;
//**********************************************************************************************************************************************************************************
// Fonction INIT_CAPTEURS
//
//**********************************************************************************************************************************************************************************
int8_t init_capteurs(void)
{
capteurs.sequenceur.etat = ETAT_SEQUENCEUR_CAPTEURS_INIT;
capteurs.sequenceur.compteur = CAPTEURS_TEMPO_INIT;
// Affichage du message de débug :
affichage_debug(__FILE__, __LINE__, "Initialisation des capteurs\t\t: OK", TYPE_MESSAGE_DEBUG_OK);
return(0);
}
//**********************************************************************************************************************************************************************************
// Fonction GESTION_CAPTEURS
//
//**********************************************************************************************************************************************************************************
void gestion_capteurs(void)
{
uint16_t i, j;
float val;
int16_t no;
bool flag_erreur;
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
if (!systeme.flag_cm3p_ready) return; // Evite que le traitement soit fait au milieu d'une reconfiguration...
switch(capteurs.sequenceur.etat)
{
//--------------------------------------------------------------------------------------------------------------
case ETAT_SEQUENCEUR_CAPTEURS_INIT :
//--------------------------------------------------------------------------------------------------------------
{
if ((systeme.flag_cm3p_ready) && // Permet de s'assurer que le cycle d'init système est terminé. En particulier, on est sûr que 'init_bdd()' puis 'annuaire_k_bus()' ont été traités.
(capteurs.sequenceur.compteur == 0))
{
affichage_debug(__FILE__, __LINE__, "------------------CAPTEURS INIT", TYPE_MESSAGE_DEBUG_WARNING);
for (i=0; i<capteurs.nb; i++)
{
if (capteurs.capteurs[i].flag_validite == FALSE) continue;
// Mise à jour de valeurs de démarrage des entrées prédéfinies à partir des valeurs de capteurs stockés dans la BDD.
// Correction de l'offset et du gain :
if (capteurs.capteurs[i].gain != 0) // Le cas d'un gain=0 ne doit pas arriver car cela est vérifié au chargement, dans bdd_init.c. Mais on ne sait jamais...
{
val = (capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante - capteurs.capteurs[i].offset) / capteurs.capteurs[i].gain;
}
else val = capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante - capteurs.capteurs[i].offset;
no = capteurs.capteurs[i].no_entrees[0]; // Facilite le traitement et la lecture ensuite. ATTENTION : Uniquement pour les types n'ayant qu'UNE entrée par capteur !!!!
switch(capteurs.capteurs[i].type_entrees)
{
//==================================
case TYPE_ENTREES_AUXILIAIRES :
{
uint32_t val_u32 = (uint32_t) val;
for (j = 0; j < capteurs.capteurs[i].nb_entrees; j ++)
{
entrees.aux.entrees[capteurs.capteurs[i].no_entrees[j]].valeur = (uint8_t) (val_u32 & 0x00000001);
val_u32 >>= 1;
}
break;
}
//==================================
case TYPE_ENTREES_LEVEL_SENSOR :
{
entrees.level_sensor.entrees[no].valeur = val; // NB : si le capteur est valide, l'entrée correspondante l'est aussi (traité dans 'enregistrement_annuaire_k_bus()')
break;
}
//==================================
case TYPE_ENTREES_VOLTAGE :
{
entrees.volt.entrees[no].valeur = val; // NB : si le capteur est valide, l'entrée correspondante l'est aussi (traité dans 'enregistrement_annuaire_k_bus()')
break;
}
//==================================
case TYPE_ENTREES_OW :
{
// L'init se fait dans 'c_bus_down_reponse_annuaire_ow()' car on n'est pas sûr d'avoir l'annuaire OW disponible à ce stade.
break;
}
//==================================
case TYPE_ENTREES_PREDEFINIES :
{
entrees.predefinies.entrees[no].valeur = val; // NB : si le capteur est valide, l'entrée correspondante l'est aussi (traité dans 'enregistrement_annuaire_k_bus()')
break;
}
/* //==================================
case TYPE_ENTREES_IBS :
{
break;
}
*/
//==================================
case TYPE_ENTREES_NMEA :
{
entrees.nmea.entrees[no].valeur = val; // NB : si le capteur est valide, l'entrée correspondante l'est aussi (traité dans 'enregistrement_annuaire_k_bus()')
break;
}
//==================================
/* case TYPE_ENTREES_CAN :
{
break;
}
*/
//==================================
case TYPE_ENTREES_CALCULEE_BOOLEEN :
{
for (j = 0; j < capteurs.capteurs[i].nb_entrees; j ++)
{
if (capteurs.capteurs[i].conditions.conditions[j].type_condition == CAPTEUR_CONDITION_GROUPE_NORMAL)
{
// Mise à jour du n° de source à partir de l'ID_Source :
// Mise à jour du n° de variable à partir de l'ID_Variable :
int16_t no_source;
int16_t no_variable;
switch(capteurs.capteurs[i].conditions.conditions[j].type_source)
{
case SOURCE_MESURE_CIRCUIT:
{
no_source = circuit_cle_primaire(capteurs.capteurs[i].conditions.conditions[j].id_source);
no_variable = variable_circuit_cle_primaire(capteurs.capteurs[i].conditions.conditions[j].id_variable);
break;
}
case SOURCE_MESURE_CAPTEUR:
{
no_source = capteur_cle_primaire(capteurs.capteurs[i].conditions.conditions[j].id_source);
no_variable = 0; // Un capteur n'a qu'un n° de variable...
break;
}
case SOURCE_MESURE_RESERVOIR:
{
no_source = reservoir_cle_primaire(capteurs.capteurs[i].conditions.conditions[j].id_source);
no_variable = variable_reservoir_cle_primaire(capteurs.capteurs[i].conditions.conditions[j].id_variable);
break;
}
case SOURCE_MESURE_BATTERIE:
{
no_source = batterie_cle_primaire(capteurs.capteurs[i].conditions.conditions[j].id_source);
no_variable = variable_batterie_cle_primaire(capteurs.capteurs[i].conditions.conditions[j].id_variable);
break;
}
default:
{
no_source = -1;
break;
}
}
if (no_source < 0) // Si on n'a pas trouvé d'équipement valide correspondant à l'ID reçu, on est obligé de dévalider complètement de capteur car l'équation peut ne plus rien vouloir dire...
{
sprintf(tmp, "L'ID_Source de la condition #%i du capteur #%i (clé primaire = %i) est invalide [%i]. Le capteur est dévalidé complètement car l'équation pourrait devenir instable", j, i, capteurs.capteurs[i].cle_primaire, capteurs.capteurs[i].conditions.conditions[j].id_source);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
capteurs.capteurs[i].flag_validite = FALSE;
break;
}
else capteurs.capteurs[i].conditions.conditions[j].no_source = no_source;
if (no_variable < 0) // Si on n'a pas trouvé de variable valide correspondant à l'ID reçu, on est obligé de dévalider complètement de capteur car l'équation peut ne plus rien vouloir dire...
{
sprintf(tmp, "L'ID_Variable de la condition #%i du capteur #%i (clé primaire = %i) est invalide [%i]. Le capteur est dévalidé complètement car l'équation pourrait devenir instable", j, i, capteurs.capteurs[i].cle_primaire, capteurs.capteurs[i].conditions.conditions[j].id_variable);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
capteurs.capteurs[i].flag_validite = FALSE;
break;
}
else capteurs.capteurs[i].conditions.conditions[j].no_variable = no_variable;
}
}
break;
}
/* //==================================
case TYPE_ENTREES_CALCULEE_NUMERIQUE :
{
break;
}
*/
//==================================
default:
{
sprintf(tmp, "Le 'Type_entrées' du capteur #%i est invalide [%i]. Le capteur est dévalidé", i, capteurs.capteurs[i].type_entrees);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
capteurs.capteurs[i].flag_validite = FALSE;
break;
}
}
}
capteurs.sequenceur.etat = ETAT_SEQUENCEUR_CAPTEURS_REPOS;
}
break;
}
//--------------------------------------------------------------------------------------------------------------
case ETAT_SEQUENCEUR_CAPTEURS_REPOS :
//--------------------------------------------------------------------------------------------------------------
{
if (capteurs.sequenceur.compteur == 0)
{
capteurs.sequenceur.compteur = CAPTEURS_PERIODE_INTEGRATION_VALEUR;
for (i = 0; i < capteurs.nb; i ++)
{
if (capteurs.capteurs[i].flag_validite == FALSE) continue;
flag_erreur = FALSE;
val = 0;
//-------------------------------------
// Recherche de la valeur du capteur :
//-------------------------------------
// ATTENTION : ne doit pas fonctionner si le nb d'entrées est > 1 !!!!
no = capteurs.capteurs[i].no_entrees[0]; // Facilite le traitement et la lecture ensuite.
switch(capteurs.capteurs[i].type_entrees)
{
//==================================
case TYPE_ENTREES_AUXILIAIRES :
{
uint32_t val_u32 = 0;
for (j = 0; j < capteurs.capteurs[i].nb_entrees; j ++)
{
val_u32 |= ((uint32_t)(entrees.aux.entrees[capteurs.capteurs[i].no_entrees[j]].valeur) ) << j;
}
val = (float) val_u32;
capteurs.capteurs[i].valeur_brute = val; // SDIR #135
break;
}
//==================================
case TYPE_ENTREES_LEVEL_SENSOR :
{
switch(entrees.level_sensor.entrees[no].mode)
{
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_DEFAUT_ISOLEMENT_MASSE :
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_DEFAUT_ISOLEMENT_PLUS :
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_DEFAUT_ISOLEMENT_FULL :
{
val = entrees.level_sensor.entrees[no].valeur;
if (fabs(val) < 0.8) val = 0; // Seuil (en valeur absolue), en-dessous duquel on considère la valeur comme non significative donc nulle. Evite les questions...!
// if (val < -99.9) val = -99.9; // Il est inutile d'afficher des valeurs supérieures qui risquent d'affoler pour rien puisque c'est une projection qui est faite et pas un courant réel.
//printf("Valeur lue sur détection de courant de défaut = %.3f\n", val);
break;
}
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_NON_DEFINI :
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_0_10V :
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_500R :
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_4_20MA :
case ENTREE_LEVEL_SENSOR_MODE_FONCTIONNEMENT_AUTO_TEST :
default :
{
val = entrees.level_sensor.entrees[no].valeur;
break;
}
}
capteurs.capteurs[i].valeur_brute = val; // SDIR #135
break;
}
//==================================
case TYPE_ENTREES_VOLTAGE :
{
val = entrees.volt.entrees[no].valeur;
capteurs.capteurs[i].valeur_brute = val; // SDIR #135
break;
}
//==================================
case TYPE_ENTREES_OW :
{
// NB : on sait que l'entrée est valide car le test a été fait dans 'enregistrement_annuaire_ow()'... Inutile de retester à chaque boucle.
// Vérification qu'on a déjà reçu des valeurs OW depuis le Companon :
if (!entrees.ow.flag_premieres_valeurs_recues)
{
flag_erreur = TRUE;
break;
}
// SDIR # 176 :
val = entrees.ow.entrees[no].valeur;
capteurs.capteurs[i].valeur_brute = val; // SDIR #135
// SDIR #178 [début] :
if (entrees.ow.entrees[no].etat != OW_ETAT_DEVICE_OK) // Si le capteur OW est NOK :
{
flag_erreur = TRUE; // Il est inutile de traiter de nouvelles valeurs de capteurs si le capteur est défaillant.
if (capteurs.capteurs[i].etat != CAPTEUR_ETAT_ALARME) // Détection d'un changement d'état.
{
capteurs.capteurs[i].etat = CAPTEUR_ETAT_ALARME; // Mise à jour du nouvel état du capteur
capteurs.capteurs[i].flag_dde_maj_bdd = TRUE;
if (entrees.ow.entrees[no].etat == OW_ETAT_BUS_NOK) // Différentiation entre erreur globale du bus OW :
{
enregistrement_historique(TYPE_SOURCE_HISTORIQUE_CAPTEURS, CAPTEUR_OW_BUS_NOK, capteurs.capteurs[i].cle_primaire, 0, entrees.ow.entrees[no].rom_code);
}
else // ... et erreur du capteur seulement :
{
enregistrement_historique(TYPE_SOURCE_HISTORIQUE_CAPTEURS, CAPTEUR_OW_DEVICE_NOK, capteurs.capteurs[i].cle_primaire, 0, entrees.ow.entrees[no].rom_code);
}
}
}
else // Si le capteur OW est Ok :
{
if (capteurs.capteurs[i].etat != CAPTEUR_ETAT_NORMAL) // Détection d'un changement d'état
{
capteurs.capteurs[i].etat = CAPTEUR_ETAT_NORMAL; // Mise à jour du nouvel état du capteur (il sera peut-être modifié ensuite si une alerte ou une alarme est détectée)
capteurs.capteurs[i].flag_dde_maj_bdd = TRUE;
enregistrement_historique(TYPE_SOURCE_HISTORIQUE_CAPTEURS, CAPTEUR_OW_DEVICE_OK, capteurs.capteurs[i].cle_primaire, 0, entrees.ow.entrees[no].rom_code);
}
}
// SDIR #178 [fin]
break;
}
//==================================
case TYPE_ENTREES_PREDEFINIES :
{
val = entrees.predefinies.entrees[no].valeur;
capteurs.capteurs[i].valeur_brute = val; // SDIR #135
break;
}
/* //==================================
case TYPE_ENTREES_IBS :
{
break;
}
*/
//==================================
case TYPE_ENTREES_NMEA :
{
val = entrees.nmea.entrees[no].valeur;
capteurs.capteurs[i].valeur_brute = val; // SDIR #135
break;
}
//==================================
/* case TYPE_ENTREES_CAN :
{
break;
}
*/
//==================================
case TYPE_ENTREES_CALCULEE_BOOLEEN :
{
struct Struct_calcul_capteur_booleen calcul_booleen;
calcul_booleen.niveau = -1;
#ifdef __DEBUG_CAPTEURS_CALCULES
sprintf(tmp, "Capteur calculé #%i : ---------------------------------", i);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
for (j = 0; j < capteurs.capteurs[i].nb_entrees; j ++)
{
//----------------------------------------------------------------------------------------
// Condition de début de groupe '[' :
if (capteurs.capteurs[i].conditions.conditions[j].type_condition > CAPTEUR_CONDITION_GROUPE_NORMAL)
{
calcul_booleen.niveau ++;
calcul_booleen.parentheses[calcul_booleen.niveau].operation = capteurs.capteurs[i].conditions.conditions[j].type_condition;
calcul_booleen.parentheses[calcul_booleen.niveau].resultat = valeur_neutre_operation_booleene(calcul_booleen.parentheses[calcul_booleen.niveau].operation);
#ifdef __DEBUG_CAPTEURS_CALCULES
char ch[100] = "";
uint8_t k;
for (k=0; k<calcul_booleen.niveau; k++) strcat(ch, "\t");
sprintf(tmp, "#%i : %s[",
j, ch );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
continue;
}
//----------------------------------------------------------------------------------------
// Condition normale :
if (capteurs.capteurs[i].conditions.conditions[j].type_condition == CAPTEUR_CONDITION_GROUPE_NORMAL)
{
bool val_bool;
if (capteurs.capteurs[i].conditions.conditions[j].flag_validite) val_bool = test_condition_capteur_booleen(i, j);
else val_bool = valeur_neutre_operation_booleene(calcul_booleen.parentheses[calcul_booleen.niveau].operation);
if (calcul_booleen.parentheses[calcul_booleen.niveau].operation == CAPTEUR_CONDITION_GROUPE_OU)
{
calcul_booleen.parentheses[calcul_booleen.niveau].resultat |= val_bool;
}
else
{
calcul_booleen.parentheses[calcul_booleen.niveau].resultat &= val_bool;
}
#ifdef __DEBUG_CAPTEURS_CALCULES
char ch[100] = "";
uint8_t k;
for (k=0; k<(calcul_booleen.niveau+1); k++) strcat(ch, "\t");
sprintf(tmp, "#%i : %s%s (%s) %s",
j, ch,
(calcul_booleen.parentheses[calcul_booleen.niveau].operation == CAPTEUR_CONDITION_GROUPE_OU) ? "OU" : "ET",
(val_bool) ? "TRUE" : "FALSE",
(capteurs.capteurs[i].conditions.conditions[j].flag_validite) ? "" : "[condition dévalidée]" );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
continue;
}
//----------------------------------------------------------------------------------------
// Condition de fin de groupe ']' :
if (capteurs.capteurs[i].conditions.conditions[j].type_condition < CAPTEUR_CONDITION_GROUPE_NORMAL)
{
if (calcul_booleen.niveau > 0)
{
calcul_booleen.niveau --;
if (calcul_booleen.parentheses[calcul_booleen.niveau].operation == CAPTEUR_CONDITION_GROUPE_OU)
{
calcul_booleen.parentheses[calcul_booleen.niveau].resultat |= calcul_booleen.parentheses[calcul_booleen.niveau + 1].resultat;
}
else
{
calcul_booleen.parentheses[calcul_booleen.niveau].resultat &= calcul_booleen.parentheses[calcul_booleen.niveau + 1].resultat;
}
#ifdef __DEBUG_CAPTEURS_CALCULES
char ch[100] = "";
uint8_t k;
for (k=0; k<(calcul_booleen.niveau+1); k++) strcat(ch, "\t");
sprintf(tmp, "#%i : %s] %s (%s)",
j, ch,
(calcul_booleen.parentheses[calcul_booleen.niveau].operation == CAPTEUR_CONDITION_GROUPE_OU) ? "OU" : "ET",
(calcul_booleen.parentheses[calcul_booleen.niveau + 1].resultat) ? "TRUE" : "FALSE");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
else
{
val = (float) calcul_booleen.parentheses[calcul_booleen.niveau].resultat;
capteurs.capteurs[i].valeur_brute = val; // SDIR #135
#ifdef __DEBUG_CAPTEURS_CALCULES
sprintf(tmp, "#%i : ] Résultat = %s", j, (val == 0) ? "FALSE" : "TRUE");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
break;
}
continue;
}
}
break;
}
/* //==================================
case TYPE_ENTREES_CALCULEE_NUMERIQUE :
{
break;
}
*/
//==================================
default: flag_erreur = TRUE; // A priori, pas possible car testé au moment de l'init...
}
//------------------------------------
// Traitement de la valeur récupérée :
//------------------------------------
if (flag_erreur == FALSE)
{
// Correction :
val = (val * capteurs.capteurs[i].gain) + capteurs.capteurs[i].offset ;
// Calcul de la nouvelle moyenne de valeur courante à partir de l'ancienne et de la valeur lue :
capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante = (((capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante * (capteurs.capteurs[i].valeur_coeff_filtrage - 1))) + val) / capteurs.capteurs[i].valeur_coeff_filtrage;
// Mise à jour du cumul :
capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].cumul += capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante;
capteurs.capteurs[i].cumuls_nb_val ++; // MàJ du nombre d'échantillons dans le cumul
// Traitement si la valeur a suffisemment évolué :
// if (fabs(capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_bdd - capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante) >= capteurs.variables[capteurs.capteurs[i].no_variable].marge)
if (fabs(capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_bdd - capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante) > 0)
{
#ifdef __DEBUG_CAPTEURS
sprintf(tmp, "Capteur #%i (cle primaire = %i) : changement détecté avec valeur_courante=%.3f et valeur_bdd=%.3f - Marge=%.3f ", i, capteurs.capteurs[i].cle_primaire, capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante, capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_bdd, capteurs.variables[capteurs.capteurs[i].no_variable].marge);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
#endif
capteurs.capteurs[i].flag_dde_maj_bdd = TRUE; // Flag pour mise à jour dans la BDD
// Enregistrement de la mesure si le capteur est configuré en mode MODE_ENREGISTREMENT_MESURES_CHANGEMENT_ETAT :
if (capteurs.capteurs[i].mode_enregistrement_mesures == MODE_ENREGISTREMENT_MESURES_CHANGEMENT_ETAT)
{
char date_vide[MAX_LONGUEUR_DATE_COURANTE] = ""; // Evite un warning depuis GCC14
enregistrement_mesure(SOURCE_MESURE_CAPTEUR, i, capteurs.capteurs[i].no_variable, date_vide, BDD_ENREGISTREMENT_MESURE_PONCTUEL);
}
} // Fin de traitement si la valeur a évolué.
#ifdef __DEBUG_CAPTEURS
sprintf(tmp, "Capteur #%i : Valeur=%.3f ", i, capteurs.capteurs[i].variables[CAPTEUR_VARIABLE_VALEUR].valeur_courante);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
// Mise à jour des valeurs BDD des variables :
if (capteurs.capteurs[i].flag_dde_maj_bdd)
{
for (j = 0; j < MAX_NOMBRE_VARIABLES_PAR_CAPTEUR; j ++) capteurs.capteurs[i].variables[j].valeur_bdd = capteurs.capteurs[i].variables[j].valeur_courante;
}
} // Fin du traitement sans erreur.
}
}
break;
}
//--------------------------------------------------------------------------------------------------------------
default :
//--------------------------------------------------------------------------------------------------------------
{
sprintf(tmp, "L'état du séquenceur Capteurs est inconnu [%i]. Il est repositionné au REPOS", capteurs.sequenceur.etat);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
capteurs.sequenceur.etat = ETAT_SEQUENCEUR_CAPTEURS_REPOS;
break;
}
}
}
//**********************************************************************************************************************************************************************************
// Fonction : Teste si la condition d'un capteur calculé booléen est vraie ou fausse
// Reçoit : Le numéro du capteur et le numéro de la condition du capteur
// Retourne : Vrai ou Faux
//**********************************************************************************************************************************************************************************
bool test_condition_capteur_booleen(uint16_t no_capteur, uint16_t no_condition)
{
float valeur;
// Si la condition n'est pas une condition normale, on retourne directement FALSE :
if (capteurs.capteurs[no_capteur].conditions.conditions[no_condition].type_condition != CAPTEUR_CONDITION_GROUPE_NORMAL) return(false);
//==================================================
// Recherche de la valeur en cours de la source :
switch(capteurs.capteurs[no_capteur].conditions.conditions[no_condition].type_source)
{
case SOURCE_MESURE_CIRCUIT:
{
valeur = circuits.circuits[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_source].variables[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_variable].valeur_courante;
break;
}
case SOURCE_MESURE_CAPTEUR:
{
valeur = capteurs.capteurs[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_source].variables[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_variable].valeur_courante;
break;
}
case SOURCE_MESURE_RESERVOIR:
{
valeur = reservoirs.reservoirs[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_source].variables[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_variable].valeur_courante;
break;
}
case SOURCE_MESURE_BATTERIE:
{
valeur = batteries.batteries[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_source].variables[capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_variable].valeur_courante;
break;
}
default: return(false); // Ne devrait pas arriver puisque testé à l'init...
}
#ifdef __DEBUG_CAPTEURS_CALCULES
/*char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
sprintf(tmp, "Test de la condition #%i du capteur #%i : Type_source=%i, N° source=%i, N° de variable=%i, Valeur= %.2f, Condition de test=%i",
no_condition, no_capteur,
capteurs.capteurs[no_capteur].conditions.conditions[no_condition].type_source,
capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_source,
capteurs.capteurs[no_capteur].conditions.conditions[no_condition].no_variable,
valeur,
capteurs.capteurs[no_capteur].conditions.conditions[no_condition].test);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
*/
#endif
//==================================================
// Test selon le type de test de l'évènement :
switch(capteurs.capteurs[no_capteur].conditions.conditions[no_condition].test)
{
//-------------------------------------
case EVENTS_TYPE_TEST_STRICT_INFERIEUR:
{
return (valeur < capteurs.capteurs[no_capteur].conditions.conditions[no_condition].seuil);
break;
}
//-------------------------------------
case EVENTS_TYPE_TEST_INFERIEUR_OU_EGAL:
{
return (valeur <= capteurs.capteurs[no_capteur].conditions.conditions[no_condition].seuil);
break;
}
//-------------------------------------
case EVENTS_TYPE_TEST_EGAL:
{
return (fabs(valeur - capteurs.capteurs[no_capteur].conditions.conditions[no_condition].seuil) < FLT_MIN);
break;
}
//-------------------------------------
case EVENTS_TYPE_TEST_SUPERIEUR_OU_EGAL:
{
return (valeur >= capteurs.capteurs[no_capteur].conditions.conditions[no_condition].seuil);
break;
}
//-------------------------------------
case EVENTS_TYPE_TEST_STRICT_SUPERIEUR:
{
return (valeur > capteurs.capteurs[no_capteur].conditions.conditions[no_condition].seuil);
break;
}
//-------------------------------------
default:
case EVENTS_TYPE_TEST_NON_DEFINI :
{
return (false);
break;
}
}
}
//**********************************************************************************************************************************************************************************
// Fonction : Renvoit une valeur booléenne neutre par rapport à une opération (0 si OU , 1 si ET)
// Reçoit : l'opération concernée
// Retourne : Vrai ou Faux
//**********************************************************************************************************************************************************************************
bool valeur_neutre_operation_booleene(uint8_t operation)
{
if (operation == CAPTEUR_CONDITION_GROUPE_ET) return(true);
else return(false);
}
//**********************************************************************************************************************************************************************************
// Fonction CAPTEUR_CLE_PRIMAIRE
// Reçoit en paramètre :
// - La Cle_primaire du capteur à rechercher
// Retourne :
// - le numéro de capteur correspondant (ou -1 si aucun capteur valide ne correspond). La numérotation allant de 0 à MAX_NOMBRE_CAPTEURS-1.
//**********************************************************************************************************************************************************************************
int16_t capteur_cle_primaire(uint16_t cle_primaire)
{
uint16_t i;
for (i=0; i<capteurs.nb; i++)
{
if ((capteurs.capteurs[i].cle_primaire == cle_primaire) && (capteurs.capteurs[i].flag_validite)) return(i);
}
return (-1); // Si on est arrivé au bout de la boucle, on renvoi le code de 'non trouvé'.
}
//**********************************************************************************************************************************************************************************
// Fonction VARIABLE_CAPTEUR_CLE_PRIMAIRE
// Reçoit en paramètre :
// - La Cle_primaire de la variable à rechercher
// Retourne :
// - le numéro de variable correspondant (ou -1 si aucune variable valide ne correspond). La numérotation allant de 0 à MAX_NOMBRE_VARIABLES_CAPTEURS-1.
//**********************************************************************************************************************************************************************************
int16_t variable_capteur_cle_primaire(uint16_t cle_primaire)
{
uint16_t i;
for (i=0; i<MAX_NOMBRE_VARIABLES_CAPTEURS; i++)
{
if (capteurs.variables[i].cle_primaire == cle_primaire) return(i);
}
return (-1); // Si on est arrivé au bout de la boucle, on renvoi le code de 'non trouvé'.
}