Salut ;
L'ensemble du projet Domos est placé sous licence GNU GPL version 3. Entre autres choses cela autorise les utilisateurs à prendre connaissance des sources des procédures, à les modifier et à partager le fruits de leur efforts.
C'est bien joli tout ça mais après ? Et bien je vous propose d'étudier ensemble le contenu de la plus courante des règles, la règle de base.
Les procédures AWK peuvent figurer autant de lignes de commentaires que nécessaire, cela commence au caractère # et se termine à la fin de ligne.
Le langage AWK est accès sur l'interprétation de commande et le filtrage de contenu de texte. Les gros programmes peuvent être très complexes, et cela ne pose aucun soucis car l'organisation est de mise.
Le listing des commande se découpe en trois blocs principaux :
- l'entête, annoncé par la balise BEGIN ;
- le corps de la procédure commençant après l'entête ;
- la fin, marquant la fin du corps.
L'entête BEGIN s'étend entre accolades { et }, il sert à déclarer et à computer toutes les fonctions et étapes avant de lancer le corps du programme.
En parcourant cette règle domos, vous remarquerez que tout le travail est effectué dans l'entête. Je n'ai pas utilisé de corps de programme.
La raison est simple, les procédures récupèrent le fichier de statut, compare le contenu à des tests listés dans la règle. Il n'y a pas d'utilité à comparer le statut à du texte issu d'un hypothétique autre fichier dont le contenu nous serai en parti inconnu.
L'accolade de fin de l'entête se trouve donc à la fin de la procédure.
L'entête commence donc à la ligne 8 par une série de déclarations qui renseignent des éléments (les constantes) qui serviront ultérieurement.
if (URLserveur == "") URLserveur = "192.168.1.21" # l adresse brut du serveur web comme 192.168.1.20
URLstatus = ("http://" URLserveur "/status.xml") # le fichier d'état de la carte
for (k = 0 ; k < 8 ; k++)
{
if (action ~ ("relai" k+1 "_allume")) { commande = ("http://" URLserveur "/preset.htm?led" k "=1") }
if (action ~ ("relai" k+1 "_eteint")) { commande = ("http://" URLserveur "/preset.htm?led" k "=0") }
}
navigateur = ("/usr/bin/elinks " commande)
print "Règle de base version 5\n"

Première ligne, je teste si la constante URLserveur est connue, sinon elle prend la valeur par défaut indiquée (adresse IP privée classique). Cette option permet donc d'indiquer lors de l'appel de la procédure quelle sera la carte relai questionnée ; utile si plusieurs existent sur le réseau.
Seconde ligne, j'emploie l'adresse URLserveur pour désigner l'emplacement du fichier status.xml qui est lisible sur la carte relai IP.
A fin de test vous pouvez désigner un fichier statique tel que celui présent dans le dépôt ; donc même si vous ne possédez pas de carte sous la main.
Lignes 3 à 7, une petite boucle de test parcoure la variable k de 0 à 7, et évalue le contenu de la constante "action" qui est censée être transmise à la procédure lors de son invocation. Si la valeur de k est trouvée dans la constante action, alors la constante "commande" est créditée d'une ligne de texte qui servira à actionner la page preset sur le relai concerné.
Cette gymnastique est nécessaire afin d'employer le numéro 1 pour le premier relai connecté à la carte (qui elle le connait en tant que 0).
A la suite de quoi nous pouvons désigner le programme qui nous est particulièrement utile pour lancer vite et bien la page preset.htm, elinks. Si un autre logiciel navigateur doit être employé, il suffit de l'indiquer ici.
Enfin j'ai placé un petit texte qui s'affiche avec le numéro de version de la règle (ici la 5) et ajoute une nouvelle ligne vide à la suite (le \n).
Les lignes suivantes vont être liées à une fonction magique avec gawk, l'usage de la connectivité réseau et internet pour lire et écrire des fichiers.
if (ProxyPort == 0) ProxyPort = 80
HttpService = "/inet/tcp/0/" URLserveur "/" ProxyPort
ORS = RS = "\r\n\r\n"
print "GET " URLstatus " HTTP/1.0" |& HttpService
while ((HttpService |& getline) > 0)
{

Je ne vais pas expliquer dans le détail comment se passe un échange de fichiers sur le réseau avec le protocole HTTP. Mais voici ce que font ses quelques lignes :
- une déclaration de constante ProxyPort si non connue ;
- une déclaration de constante annonçant l'emploi de inet, en mode tcp vers le serveur de la carte relai, au port déclaré ;
- un changement de constante concernant la façon dont les fichiers sont marqués "terminé" ;
- l'envoi d'une requête GET en mode HTTP 1.0, le plus simple, du fichier status.xml, vers le service inet de manière interactive (|& permet à la procédure de lancer inet et de recevoir de lui la réponse dans la foulée jusqu'à la balise de fin) ;
- on lance une boucle ne se terminant pas tant que la réponse du service inet ne sera pas nulle.
Cette dernière boucle va contenir les divers tests qui constituent le gros du travail pour la procédure. Les demandes à inet se faisant dans l'entête, et les tests se faisant "en direct" sur sa réponse, cela explique pourquoi je n'utilise pas le corps de programme dans cette procédure.
Reste à détailler comment tester ce qui nous arrive du net, et le comparer à ce l'on demande à la procédure (les variables test et etat)
# Boucle de vérification des valeurs des relais, si la cible est trouvée alors action
for (i = 0; i < 8; i++) {
entree = "<led" i ">" etat
cible = "relai" (i+1)
if ($0 ~ entree && test == cible) print ("lancement de " action) | navigateur
}
# Boucle de vérification des valeurs des entrées, si la cible est trouvée alors action
for (j = 0; j < 4; j++) {
entree = "<btn" j ">" etat
cible = "bouton" (j+1)
if ($0 ~ entree && test == cible) print ("lancement de " action) | navigateur
}

Il y a deux boucles similaires, correspondant à l'état des relais (indiqués par des valeurs 1 ou 0), et à l'état des entrées (boutons indiqués par up ou dn).
Les boucles testent pour toutes les valeurs de i et j si le texte trouvé dans le fichiers statut colle avec le texte du test
plus si le "test" indiqué par l'utilisateur colle avec la cible du test de la boucle.
Ici aussi nous avons une gymnastique qui permet de tester le statut avec des mots compréhensibles par l'utilisateur.
Si on souhaite changer les mots "bouton1" par "entree1" lors de l'invocation, c'est ici qu'il faut faire le changement.
Si le test est positif (les deux cibles concordantes trouvées) alors on affiche un texte (lancement de l'action) et on lance le navigateur. Le texte n'est pas censé s'afficher, mais en phase de test, on peut commenter la fin de la ligne (à partir du | ) et profiter de l'affichage de cette ligne à l'écran de la console.
Notez bien l'organisation générale jusqu'ici, avec des indentations successives qui permettent de distinguer les niveaux emboités et les accolades ceinturant un contenu.
Nous en avons bientôt terminé avec cette looooooongue tirade.
# printf "%s", $0
}
close(HttpService)
close(navigateur) #referme l appel proprement, mais inutile avec le timer elinks réglé sur really_quit
system ("sleep 2") # patiente largement avec 15 si le réseau est lent
print "ok"
} 
Avant de fermer la boucle employant la réponse de inet, j'ai placé un commentaire abscons. Cette ligne une fois décommentée permet d'avoir un affichage à l'écran de l'intégralité de la réponse. Là aussi utile en phase d'essais.
A la suite de quoi nous refermons proprement les appels aux autres programmes. Pas nécessairement utile, mais il est toujours préférable de faire ainsi.
Un dernier petit passage avec une attente de 2 secondes, puis l'affichage du glorieux et sempiternel "OK" avant de finir l'entête et la procédure par la même occasion.
Voilà pour cette procédure. Les autres sont du même acabit, avec des variantes portant sur les variables et les constantes à utiliser. et quelques tests adaptés à l'usage que l'on souhaite faire du contenu du fichier status.xml.
[ Message modifié par La_Brosse le 14-10-2011 à 18:10 ]