Gestion du clignotement des LEDs
![Stacks Image 6091](files/stacks-image-05d11ae-72x70.png)
Version 2 du script Allume_led.py
Nous devons charger la bibliothèque gérant les threads
#!/usr/bin/env python# -*- coding:Utf-8 -*-#-----------------------------# allume_led.py# contrôle l'allumage ou non des LED# version 2.00 date 23/01/2014#-----------------------------# Chargement bibliothèqueimport ConfigParserimport timeimport commandsimport threadingimport RPi.GPIO as GPIO
Ensuite, ce sont les déclarations de variables et initialisation.
# initialisation constanteRGB_G_GREEN = 12RGB_G_BLUE = 11RGB_G_RED = 13RGB_D_BLUE = 15RGB_D_GREEN = 16RGB_D_RED = 18# Initialisation variableverif_nagios = 0led_gauche = 'blanc'led_gauche_etat = ''led_droite = 'blanc'led_droite_etat = ''led_gauche_temp = ''led_gauche_etat_temp = ''led_droite_temp = ''led_droite_etat_temp = ''tempo10 = 0serveurKO = Falsecfg = ConfigParser.ConfigParser()# Initialisation GPIOtry: # choix de la numérotation des I/O GPIO.setmode(GPIO.BOARD) #désactivation des alarmes GPIO.setwarnings(False) # initialisation des ports GPIO.setup(RGB_G_BLUE, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(RGB_G_GREEN, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(RGB_G_RED, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(RGB_D_BLUE, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(RGB_D_GREEN, GPIO.OUT, initial=GPIO.HIGH) GPIO.setup(RGB_D_RED, GPIO.OUT, initial=GPIO.HIGH)except RuntimeError: print("Error importing RPi.GPIO! This is probably because you need superuser privileges. You can achieve this by using 'sudo' to run your script")
Voici la fonction gérant le clignotement des LEDs.
# thread pour faire clignoter les LEDsclass clignote_LED(threading.Thread): def __init__(self, nom = ''): threading.Thread.__init__(self) self.nom = nom self._stopevent = threading.Event() def run(self): tempo = False while not self._stopevent.isSet(): if tempo : tempo = False if self.nom == 'gauche': init_led_gauche ('eteint') elif self.nom == 'droite': init_led_droite ('eteint') else: tempo = True if self.nom == 'gauche': init_led_gauche (led_gauche) elif self.nom == 'droite': init_led_droite (led_droite) self._stopevent.wait(1.0) if self.nom == 'gauche': init_led_gauche (led_gauche) if self.nom == 'droite': init_led_droite (led_droite) def stop(self): self._stopevent.set()
Ensuite les fonctions gérant l'affichage des LEDs
# Fonction gestion Led Gauchedef init_led_gauche (gauche): if gauche == 'vert': GPIO.output(RGB_G_BLUE, GPIO.HIGH) GPIO.output(RGB_G_RED, GPIO.HIGH) GPIO.output(RGB_G_GREEN, GPIO.LOW) elif gauche == 'rouge': GPIO.output(RGB_G_BLUE, GPIO.HIGH) GPIO.output(RGB_G_GREEN, GPIO.HIGH) GPIO.output(RGB_G_RED, GPIO.LOW) elif gauche == 'cyan': GPIO.output(RGB_G_BLUE, GPIO.LOW) GPIO.output(RGB_G_GREEN, GPIO.LOW) GPIO.output(RGB_G_RED, GPIO.HIGH) elif gauche == 'jaune': GPIO.output(RGB_G_BLUE, GPIO.HIGH) GPIO.output(RGB_G_GREEN, GPIO.LOW) GPIO.output(RGB_G_RED, GPIO.LOW) elif gauche == 'magenta': GPIO.output(RGB_G_BLUE, GPIO.LOW) GPIO.output(RGB_G_GREEN, GPIO.HIGH) GPIO.output(RGB_G_RED, GPIO.LOW) elif gauche == 'blanc': GPIO.output(RGB_G_BLUE, GPIO.LOW) GPIO.output(RGB_G_GREEN, GPIO.LOW) GPIO.output(RGB_G_RED, GPIO.LOW) elif gauche == 'bleu': GPIO.output(RGB_G_BLUE, GPIO.LOW) GPIO.output(RGB_G_GREEN, GPIO.HIGH) GPIO.output(RGB_G_RED, GPIO.HIGH) elif gauche == 'eteint': GPIO.output(RGB_G_BLUE, GPIO.HIGH) GPIO.output(RGB_G_GREEN, GPIO.HIGH) GPIO.output(RGB_G_RED, GPIO.HIGH) # Fonction gestion Led Droitedef init_led_droite (droite): if droite == 'rouge': GPIO.output(RGB_D_BLUE, GPIO.HIGH) GPIO.output(RGB_D_GREEN, GPIO.HIGH) GPIO.output(RGB_D_RED, GPIO.LOW) elif droite == 'vert': GPIO.output(RGB_D_BLUE, GPIO.HIGH) GPIO.output(RGB_D_GREEN, GPIO.LOW) GPIO.output(RGB_D_RED, GPIO.HIGH) elif droite == 'cyan': GPIO.output(RGB_D_BLUE, GPIO.LOW) GPIO.output(RGB_D_GREEN, GPIO.LOW) GPIO.output(RGB_D_RED, GPIO.HIGH) elif droite == 'magenta': GPIO.output(RGB_D_BLUE, GPIO.LOW) GPIO.output(RGB_D_GREEN, GPIO.HIGH) GPIO.output(RGB_D_RED, GPIO.LOW) elif droite == 'jaune': GPIO.output(RGB_D_BLUE, GPIO.HIGH) GPIO.output(RGB_D_GREEN, GPIO.LOW) GPIO.output(RGB_D_RED, GPIO.LOW) elif droite == 'blanc': GPIO.output(RGB_D_BLUE, GPIO.LOW) GPIO.output(RGB_D_GREEN, GPIO.LOW) GPIO.output(RGB_D_RED, GPIO.LOW) elif droite == 'bleu': GPIO.output(RGB_D_BLUE, GPIO.LOW) GPIO.output(RGB_D_GREEN, GPIO.HIGH) GPIO.output(RGB_D_RED, GPIO.HIGH) elif droite == 'eteint': GPIO.output(RGB_D_BLUE, GPIO.HIGH) GPIO.output(RGB_D_GREEN, GPIO.HIGH) GPIO.output(RGB_D_RED, GPIO.HIGH)
Afin de simplifier l'écriture du code, j'ai rajouté une fonction pour la lecture du fichier de configuration.
def Lecture_fichier(led_g_couleur,led_g_etat,led_d_couleur,led_d_etat): # lecture fichier configuration cfg.read('/usr/local/gestled/config_led.cfg') led_g_couleur = cfg.get('General', 'led_gauche_couleur') led_g_etat = cfg.get('General','led_gauche_etat') led_d_couleur = cfg.get('General', 'led_droite_couleur') led_d_etat = cfg.get('General', 'led_droite_etat') return led_g_couleur,led_g_etat,led_d_couleur,led_d_etat
Avant de démarrer la boucle infinie, nous commencerons à initialiser l'allumage des LED avec une couleur blanche.
# première lecture fichierled_gauche_temp,led_gauche_etat_temp,led_droite_temp,led_droite_etat_temp = Lecture_fichier('blanc','fixe','blanc','fixe')# affichage des ledsinit_led_gauche (led_gauche)init_led_droite (led_droite)
Nous terminerons par le programme principal. Toutes les 10 secondes, le programme lit le fichier de configuration et applique la nouvelle configuration, si besoin. Toutes les deux minutes, le programme vérifie le fonctionnement du moteur de supervision et alerte, si besoin, par l'affichage des LED avec la couleur magenta.
# Programme principalwhile True : if not serveurKO and tempo10 > 10: tempo10 = 0 # lecture fichier configuration led_gauche_temp,led_gauche_etat_temp,led_droite_temp,led_droite_etat_temp = Lecture_fichier(led_gauche,led_gauche_etat,led_droite,led_droite_etat) # Gestion LED Gauche if led_gauche_temp != led_gauche: led_gauche = led_gauche_temp init_led_gauche (led_gauche) if led_gauche_etat_temp != led_gauche_etat: led_gauche_etat = led_gauche_etat_temp if led_gauche_etat != 'fixe': g = clignote_LED('gauche') g.start() elif led_gauche_etat == 'fixe': # protection si l'objet n'est pas initialisé try: g.stop() except NameError: True # Gestion Led Droite if led_droite_temp != led_droite: led_droite = led_droite_temp init_led_droite (led_droite) if led_droite_etat_temp != led_droite_etat: led_droite_etat = led_droite_etat_temp if led_droite_etat != 'fixe': d = clignote_LED('droite') d.start() elif led_droite_etat == 'fixe': # protection si l'objet n'est pas initialisé try: d.stop() except NameError: True # tempo 1 secondes time.sleep(1) tempo10 += 1 verif_nagios += 1 # toutes les deux minutes vérification Nagios if verif_nagios > 120 : verif_nagios = 0 resultat_nagios = commands.getoutput('nagios3stats -m -d NAGIOSPID -D :') resultat_splite = resultat_nagios.split(":") if int(resultat_splite[0]) != 0 : if serveurKO : serveurKO = False # Le serveur Nagios fonctionne, on affiche les informations du fichier de configuration Lecture_fichier(led_gauche,led_gauche_etat,led_droite,led_droite_etat) init_led_droite (led_gauche) init_led_gauche (led_droite) led_gauche_etat = '' led_droite_etat = '' else : serveurKO = True # tuer les threads existant if led_gauche_etat != 'fixe': g.stop() if led_droite_etat != 'fixe': d.stop() # Le serveur Nagios est HS # l'initialisation des variables permet de positionner la bonne valeur # pour l'arrêt du thread led_gauche = 'magenta' led_droite = 'magenta' # on force les LED à magenta init_led_droite (led_gauche) init_led_gauche (led_droite)
Vous trouverez le script complet ici.
Modification du service gestled
Le fichier de script s'appelant allume_ledV2.py, il faut modifier le script /etc/init.d/gestled. Modifiez les lignes suivantes
DAEMON="/usr/local/gestled/allume_ledV2.py"DEAMON_NAME="allume_ledV2.py"
Configuration Nagios
Modification du fichier de commande
Nous devons modifier notre commande submit_alerte pour prendre en compte les états soft et hard des hôtes et des services. Nous rajouterons les macro
$HOSTSTATETYPE$ et $SERVICESTATETYPE$
$HOSTSTATETYPE$ et $SERVICESTATETYPE$
# 'submit_alerte' command definition
define command{
command_name submit_alerte
command_line /usr/lib/nagios/plugins/submit_alerte "$HOSTNAME$" "$SERVICEDESC$" "$HOSTSTATETYPE$" "$SERVICESTATETYPE$" "$TOTALHOSTSDOWN$" "$TOTALHOSTSUNREACHABLE$" "$TOTALSERVICESCRITICAL$" "$TOTALSERVICESWARNING$" "$TOTALSERVICESUNKNOWN$"
}
define command{
command_name submit_alerte
command_line /usr/lib/nagios/plugins/submit_alerte "$HOSTNAME$" "$SERVICEDESC$" "$HOSTSTATETYPE$" "$SERVICESTATETYPE$" "$TOTALHOSTSDOWN$" "$TOTALHOSTSUNREACHABLE$" "$TOTALSERVICESCRITICAL$" "$TOTALSERVICESWARNING$" "$TOTALSERVICESUNKNOWN$"
}
Modification du script submit_alerte
Pour la même raison, nous modifiereons le script submit_alerte.
#!/bin/bashHOSTNAME=$1SERVICEDESC=$2HOSTSTATE=$3SERVICESTATE=$4TOTALHOSTSDOWN=$5TOTALHOSTSUNREACHABLE=$6TOTALSERVICESCRITICAL=$7TOTALSERVICESWARNING=$8TOTALSERVICESUNKNOWN=$9YEAR=`date +%Y` # the current yearMONTH=`date +%m` # the current numeric monthDAY=`date +%d` # the current dayHOUR=`date +%H` # the current hourMINUTE=`date +%M` # the current minuteSECOND=`date +%S` # the current secondGESTLED_ROOT=/usr/local/gestled$GESTLED_ROOT/ecrit_config.py -D $TOTALHOSTSDOWN -U $TOTALHOSTSUNREACHABLE -C $TOTALSERVICESCRITICAL -W $TOTALSERVICESWARNING -u $TOTALSERVICESUNKNOWN -H $HOSTSTATE -S $SERVICESTATEif [ ! -f $GESTLED_ROOT/log.txt ]then echo "====== Incidents du $DAY/$MONTH/$YEAR ======" >> $GESTLED_ROOT/log.txt echo "^ Heure ^Host ^Service ^Host state ^Service State ^ Host Down ^ Host Unreachable ^ Service Critical ^ Service Warning ^ Service Unknown ^" >> $GESTLED_ROOT/log.txtfiecho "| $HOUR:$MINUTE:$SECOND | $HOSTNAME | $SERVICEDESC | $HOSTSTATE | $SERVICESTATE | $TOTALHOSTSDOWN | $TOTALHOSTSUNREACHABLE | $TOTALSERVICESCRITICAL | $TOTALSERVICESWARNING | $TOTALSERVICESUNKNOWN " >> $GESTLED_ROOT/log.txtexit 0
Pour la prise en compte de ces modifications, relancez Nagios.
service nagios3 restart
Modification du Script ecrit_config.py
Modifions le script ecrit_config.py pour la prise en compte de l'état des LEDs.
!/usr/bin/env python# -*- coding:Utf-8 -*-#-----------------------------# ecrit_config.py# ecriture fichier config# version 1.00 date 10/01/2014#-----------------------------# Chargement bibliothèqueimport ConfigParserimport optparseparseur = optparse.OptionParser()parseur.add_option('-D','--hostsdown',help='Total Hosts Down',dest='total_hosts_down')parseur.add_option('-U','--hostsunreachable',help='Total Hosts Unreachable',dest='total_hosts_unreachable')parseur.add_option('-C','--servicescritical',help='Total Services Critical',dest='total_services_critical')parseur.add_option('-W','--serviceswarning',help='Total Services Warning',dest='total_services_warning')parseur.add_option('-u','--servicesunknown',help='Total Services Unknown',dest='total_services_unknown')parseur.add_option('-H','--hoststate',help='Etat Soft-Hard',dest='etat_host')parseur.add_option('-S','--servicesstate',help='Etat Soft-hard',dest='etat_service')(options, args) =parseur.parse_args()cfg = ConfigParser.ConfigParser()# lecture du fichier de configurationcfg.read('/usr/local/gestled/config_led.cfg')S = 'General'# configuration des couleurs en fonction des états Nagiosif int(options.total_hosts_down) > 0: cfg.set(S, 'led_gauche_couleur', 'rouge')elif int(options.total_hosts_unreachable) > 0: cfg.set(S, 'led_gauche_couleur', 'blanc')else: cfg.set(S, 'led_gauche_couleur', 'vert')if int(options.total_services_critical) > 0: cfg.set(S, 'led_droite_couleur', 'rouge')elif int(options.total_services_warning) > 0: cfg.set(S, 'led_droite_couleur', 'jaune')elif int(options.total_services_unknown) > 0: cfg.set(S, 'led_droite_couleur', 'blanc')else: cfg.set(S, 'led_droite_couleur', 'vert')# configuration Etat Hard Softif options.etat_host == 'HARD': cfg.set(S, 'led_gauche_etat', 'fixe')elif options.etat_host == 'SOFT': cfg.set(S, 'led_gauche_etat', 'clignotant')# configuration Service Hard Softif options.etat_service == 'HARD': cfg.set(S, 'led_droite_etat', 'fixe')elif options.etat_service == 'SOFT': cfg.set(S, 'led_droite_etat', 'clignotant')# écriture du fichier de configurationcfg.write(open('/usr/local/gestled/config_led.cfg','w'))
Il nous restera à vérifier le fonctionnement de cette modification.
Vérification du fonctionnement
Prenons un exemple avec un service sur un Hôte. Au premier contrôle infructueux, nous aurons un état SOFT comme indiqué sur le log suivant.
![Stacks Image 6457](files/stacks-image-8ad7045.png)
Première Alerte, état soft, nous envoyons un état clignotant pour la LED de droite
![Stacks Image 6464](files/stacks-image-8a2dbcb-244x210.jpg)
![Stacks Image 6470](files/stacks-image-f794f59-244x208.jpg)
![Stacks Image 6467](files/stacks-image-5a6d935-244x208.jpg)
Clignotement de la LED droite
Quand la vérification aura atteint la valeur max_check_attempts, nous aurons un état HARD, notre service sera bien Critical donc l'affichage de la LED sera fixe. Une alerte de notification sera activée.
![Stacks Image 6475](files/stacks-image-b5b18ce.png)
Etat HARD et notification
![Stacks Image 6478](files/stacks-image-857ca2a-244x208.jpg)
Affichage de la LED au fixe
Le retour à la normale sera beaucoup plus rapide comme indiqué sur le log suivant. La LED reviendra au Vert fixe.
![Stacks Image 6483](files/stacks-image-60f38a9-800x46.png)
Retour à la normale
Prochain article, création d'une sonde de température