J'ai remplacé l'imprimante d'un système d'alarme qui enregistrait moult
logs par un PC sous Debian qui fournit par ailleurs d'autres services sur
un réseau.
Le système d'alarme envoie ses données sur le port série du PC ; le
paramétrage suivant:
stty raw 2400 oddp istrip < /dev/ttyS0
(fruit de la lecture de man stty et de nombreux essais
infructueux..) me permet de récupérer les données correctement par
cat /dev/ttyS0
Je souhaite enregistrer ces données dans des fichiers mensuels (des
logs disais-je)et en modifier la présentation.
les données "brutes" ont cet aspect:
05 fev 14:33 SY
^M01 Action 002 code R2
^M05 fev 14:33 SY
^M07 Action 002 code R2
^M
(les "^M" sont parfois ignorés, parfois traduits par une ligne blanche
selon l'utilitaire utilisé, je les ai ajoutés à la main ici pour plus de
"clarté" hum...)
(hum, là je me suis fait aider)
le résultat attendu de la ligne de commande est:
05 fev 14:33 SY 01 Action 002 code R2
05 fev 14:33 SY 07 Action 002 code R2
dans un fichier 2007_02
Ce résultat est bien obtenu si l'entrée est un fichier "fermé"
( cat /dev/ttyS0 > fichier ;^C; puis cat fichier | awk .....) mais pas si
je lis "en direct" le port série. Il semble que les traitements prévus ne
sont jamais exécutés parce que le fichier en entrée du pipe n'est jamais
"fermé".
La question est donc comment paramétrer le port série pour que le buffer
soit vidé à chaque ligne et que les lignes puissent être traitées une à
une dans le pipe.
Merci de votre patience pour cette longue lecture et surtout de vos
lumières.
NB: je n'ai pas la main sur le système qui est à 20km de mon domicile. Le
câble de liaison PC-Système d'alarme comporte 3 brins, donc pas de
protocole d'échange juste de l'écoute sur le port série.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Fabien LE LEZ
On Mon, 25 Jun 2007 21:02:56 +0000 (UTC), Christophe Maquaire :
Ce résultat est bien obtenu si l'entrée est un fichier "fermé" ( cat /dev/ttyS0 > fichier ;^C; puis cat fichier | awk .....) mais pas si je lis "en direct" le port série.
Tu devrais mettre un sujet plus explicite dans tes posts. Ton problème est un problème de flux, pas de port série.
De deux choses l'une :
- soit ton flux contient un caractère qui en indique la fin, et tu l'utilises (via une syntaxe que je n'ai malheureusement pas en tête) pour arrêter la copie ;
- soit tu traites le flux ligne par ligne : lire une ligne, la traiter, puis enregistrer le résultat à la fin du fichier.
Crée un fichier decode_alarme qui contient ce qui suit :
#!/bin/bash
while [ 1 ] do read ligne echo ligne|awk '{gsub(/ 15/, "", $0); printf("%s%s", $0, /:/?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m) done
Rend-le exécutable, puis tape
decode_alarme < /dev/ttyS0
Je n'ai pas testé, et j'ai des doutes sur son fonctionnement, mais logiquement, il devrait convertir et enregistrer chaque ligne dès qu'il la reçoit.
(Et si quelqu'un veut proposer un script un peu moins bancal, qu'il n'hésite pas !)
On Mon, 25 Jun 2007 21:02:56 +0000 (UTC), Christophe Maquaire :
Ce résultat est bien obtenu si l'entrée est un fichier "fermé"
( cat /dev/ttyS0 > fichier ;^C; puis cat fichier | awk .....) mais pas si
je lis "en direct" le port série.
Tu devrais mettre un sujet plus explicite dans tes posts.
Ton problème est un problème de flux, pas de port série.
De deux choses l'une :
- soit ton flux contient un caractère qui en indique la fin, et tu
l'utilises (via une syntaxe que je n'ai malheureusement pas en tête)
pour arrêter la copie ;
- soit tu traites le flux ligne par ligne : lire une ligne, la
traiter, puis enregistrer le résultat à la fin du fichier.
Crée un fichier decode_alarme qui contient ce qui suit :
#!/bin/bash
while [ 1 ]
do
read ligne
echo ligne|awk '{gsub(/ 15/, "", $0); printf("%s%s", $0,
/:/?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m)
done
Rend-le exécutable, puis tape
decode_alarme < /dev/ttyS0
Je n'ai pas testé, et j'ai des doutes sur son fonctionnement, mais
logiquement, il devrait convertir et enregistrer chaque ligne dès
qu'il la reçoit.
(Et si quelqu'un veut proposer un script un peu moins bancal, qu'il
n'hésite pas !)
On Mon, 25 Jun 2007 21:02:56 +0000 (UTC), Christophe Maquaire :
Ce résultat est bien obtenu si l'entrée est un fichier "fermé" ( cat /dev/ttyS0 > fichier ;^C; puis cat fichier | awk .....) mais pas si je lis "en direct" le port série.
Tu devrais mettre un sujet plus explicite dans tes posts. Ton problème est un problème de flux, pas de port série.
De deux choses l'une :
- soit ton flux contient un caractère qui en indique la fin, et tu l'utilises (via une syntaxe que je n'ai malheureusement pas en tête) pour arrêter la copie ;
- soit tu traites le flux ligne par ligne : lire une ligne, la traiter, puis enregistrer le résultat à la fin du fichier.
Crée un fichier decode_alarme qui contient ce qui suit :
#!/bin/bash
while [ 1 ] do read ligne echo ligne|awk '{gsub(/ 15/, "", $0); printf("%s%s", $0, /:/?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m) done
Rend-le exécutable, puis tape
decode_alarme < /dev/ttyS0
Je n'ai pas testé, et j'ai des doutes sur son fonctionnement, mais logiquement, il devrait convertir et enregistrer chaque ligne dès qu'il la reçoit.
(Et si quelqu'un veut proposer un script un peu moins bancal, qu'il n'hésite pas !)
Christophe Maquaire
Le Mon, 25 Jun 2007 23:25:23 +0200, Fabien LE LEZ a écrit:
Tout d'abord merci de ton aide. Si mes réponses te semblent mal formulées, n'oublie pas que je n'ai pas un bagage technologique très important,je ne suis pas un professionnel de l'informatique, et comble du bonheur, mon anglais est loin d'être parfait; j'ai lu diverses pages man que je n'ai pas toujours bien comprises, des howto et des documentations glanés sur internet qui m'ont semblé parfois aussi bien obscurs, pour tenter de venir à bout de différents problèmes, dont celui-ci.
Tu devrais mettre un sujet plus explicite dans tes posts. Ton problème est un problème de flux, pas de port série.
Soit, mais j'exposerais plus loin la formulation originale.
De deux choses l'une :
- soit ton flux contient un caractère qui en indique la fin, et tu l'utilises (via une syntaxe que je n'ai malheureusement pas en tête) pour arrêter la copie
Justement, j'aimerais bien pouvoir interrompre et reprendre la lecture du flux à chaque ligne (le caractère ^M est un bon candidat) mais j'en revient à mon souci initial: comment traiter le flux qui n'est pas arrêté pour y lire un caractère particulier ?
- soit tu traites le flux ligne par ligne : lire une ligne, la traiter,
puis enregistrer le résultat à la fin du fichier.
Crée un fichier decode_alarme qui contient ce qui suit :
#!/bin/bash
while [ 1 ] do read ligne echo ligne|awk '{gsub(/ 15/, "", $0); printf("%s%s", $0, /:/?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m) done
J'avais tenté dans le même esprit un
#! /bin/sh while true ; do read LIGNE < /dev/ttyS0 echo $LIGNE | awk '{gsub(/ 15/, "", $0); printf("%s%s", $0, /:/ ?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m)
sans succès, mais en y réfléchissant, il bien possible que la technique consistant à lire le flux depuis une boucle et non à lire le flux à l'intérieur de la boucle puisse être la solution. Comme je l'ai dit au départ, les tests se font de manière épisodique pour cause d'éloignement géographique. (et que va contenir ligne ? un seul caractère, une ligne, ou le flux complet ?)
Pour en revenir au sujet initial, je l'avais choisit parce que j'avais souvenir d'avoir lu dans une doc quelconque qu'il y avait existé des terminaux antédiluviens qui fonctionnaient ligne par ligne et j'imaginais qu'il était possible via stty de paramétrer le port série pour qu'il se comporte d'une façon équivalente, ce qui je crois aurait été une solution. (par ailleurs je n'ai toujours pas bien fait la différence entre CR LF et autres fin de ligne pour les différents terminaux, dont l'imprimante et mon port série)
Merci
Le Mon, 25 Jun 2007 23:25:23 +0200, Fabien LE LEZ a écrit:
Tout d'abord merci de ton aide. Si mes réponses te semblent mal formulées,
n'oublie pas que je n'ai pas un bagage technologique très important,je ne
suis pas un professionnel de l'informatique, et comble du bonheur, mon
anglais est loin d'être parfait; j'ai lu diverses pages man que je n'ai pas
toujours bien comprises, des howto et des documentations glanés sur
internet qui m'ont semblé parfois aussi bien obscurs, pour tenter de venir
à bout de différents problèmes, dont celui-ci.
Tu devrais mettre un sujet plus explicite dans tes posts. Ton problème
est un problème de flux, pas de port série.
Soit, mais j'exposerais plus loin la formulation originale.
De deux choses l'une :
- soit ton flux contient un caractère qui en indique la fin, et tu
l'utilises (via une syntaxe que je n'ai malheureusement pas en tête)
pour arrêter la copie
Justement, j'aimerais bien pouvoir interrompre et reprendre la lecture du
flux à chaque ligne (le caractère ^M est un bon candidat) mais j'en
revient à mon souci initial: comment traiter le flux qui n'est pas arrêté
pour y lire un caractère particulier ?
- soit tu traites le flux ligne
par ligne : lire une ligne, la traiter,
puis enregistrer le résultat à la fin du fichier.
Crée un fichier decode_alarme qui contient ce qui suit :
#!/bin/bash
while [ 1 ]
do
read ligne
echo ligne|awk '{gsub(/ 15/, "", $0); printf("%s%s", $0,
/:/?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m) done
J'avais tenté dans le même esprit un
#! /bin/sh
while true ; do
read LIGNE < /dev/ttyS0
echo $LIGNE | awk '{gsub(/ 15/, "", $0); printf("%s%s", $0, /:/
?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m)
sans succès, mais en y réfléchissant, il bien possible que la technique
consistant à lire le flux depuis une boucle et non à lire le flux à
l'intérieur de la boucle puisse être la solution. Comme je l'ai dit au
départ, les tests se font de manière épisodique pour cause d'éloignement
géographique. (et que va contenir ligne ? un seul caractère, une ligne, ou
le flux complet ?)
Pour en revenir au sujet initial, je l'avais choisit parce que j'avais
souvenir d'avoir lu dans une doc quelconque qu'il y avait existé des
terminaux antédiluviens qui fonctionnaient ligne par ligne et j'imaginais
qu'il était possible via stty de paramétrer le port série pour qu'il
se comporte d'une façon équivalente, ce qui je crois aurait été une
solution.
(par ailleurs je n'ai toujours pas bien fait la différence entre
CR LF et autres fin de ligne pour les différents terminaux, dont
l'imprimante et mon port série)
Le Mon, 25 Jun 2007 23:25:23 +0200, Fabien LE LEZ a écrit:
Tout d'abord merci de ton aide. Si mes réponses te semblent mal formulées, n'oublie pas que je n'ai pas un bagage technologique très important,je ne suis pas un professionnel de l'informatique, et comble du bonheur, mon anglais est loin d'être parfait; j'ai lu diverses pages man que je n'ai pas toujours bien comprises, des howto et des documentations glanés sur internet qui m'ont semblé parfois aussi bien obscurs, pour tenter de venir à bout de différents problèmes, dont celui-ci.
Tu devrais mettre un sujet plus explicite dans tes posts. Ton problème est un problème de flux, pas de port série.
Soit, mais j'exposerais plus loin la formulation originale.
De deux choses l'une :
- soit ton flux contient un caractère qui en indique la fin, et tu l'utilises (via une syntaxe que je n'ai malheureusement pas en tête) pour arrêter la copie
Justement, j'aimerais bien pouvoir interrompre et reprendre la lecture du flux à chaque ligne (le caractère ^M est un bon candidat) mais j'en revient à mon souci initial: comment traiter le flux qui n'est pas arrêté pour y lire un caractère particulier ?
- soit tu traites le flux ligne par ligne : lire une ligne, la traiter,
puis enregistrer le résultat à la fin du fichier.
Crée un fichier decode_alarme qui contient ce qui suit :
#!/bin/bash
while [ 1 ] do read ligne echo ligne|awk '{gsub(/ 15/, "", $0); printf("%s%s", $0, /:/?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m) done
J'avais tenté dans le même esprit un
#! /bin/sh while true ; do read LIGNE < /dev/ttyS0 echo $LIGNE | awk '{gsub(/ 15/, "", $0); printf("%s%s", $0, /:/ ?FS:RS)}'>> /home/francois/alarme/$(date +%Y_%m)
sans succès, mais en y réfléchissant, il bien possible que la technique consistant à lire le flux depuis une boucle et non à lire le flux à l'intérieur de la boucle puisse être la solution. Comme je l'ai dit au départ, les tests se font de manière épisodique pour cause d'éloignement géographique. (et que va contenir ligne ? un seul caractère, une ligne, ou le flux complet ?)
Pour en revenir au sujet initial, je l'avais choisit parce que j'avais souvenir d'avoir lu dans une doc quelconque qu'il y avait existé des terminaux antédiluviens qui fonctionnaient ligne par ligne et j'imaginais qu'il était possible via stty de paramétrer le port série pour qu'il se comporte d'une façon équivalente, ce qui je crois aurait été une solution. (par ailleurs je n'ai toujours pas bien fait la différence entre CR LF et autres fin de ligne pour les différents terminaux, dont l'imprimante et mon port série)
Merci
Fabien LE LEZ
On Tue, 26 Jun 2007 20:57:40 +0000 (UTC), Christophe Maquaire :
Comme je l'ai dit au départ, les tests se font de manière épisodique pour cause d'éloignement géographique.
Remplace
le_script < /dev/ttyS0
par
simule | le_script
où "simule" contiendrait quelque chose comme :
while [1] do echo 01 Action 002 code R2 sleep 1s done
On Tue, 26 Jun 2007 20:57:40 +0000 (UTC), Christophe Maquaire :
Comme je l'ai dit au
départ, les tests se font de manière épisodique pour cause d'éloignement
géographique.
Remplace
le_script < /dev/ttyS0
par
simule | le_script
où "simule" contiendrait quelque chose comme :
while [1]
do
echo 01 Action 002 code R2
sleep 1s
done
On Tue, 26 Jun 2007 20:57:40 +0000 (UTC), Christophe Maquaire :
Comme je l'ai dit au départ, les tests se font de manière épisodique pour cause d'éloignement géographique.
Remplace
le_script < /dev/ttyS0
par
simule | le_script
où "simule" contiendrait quelque chose comme :
while [1] do echo 01 Action 002 code R2 sleep 1s done
Christophe Maquaire
Le Wed, 27 Jun 2007 00:42:34 +0200, Fabien LE LEZ a écrit:
Bonjour,
J'ai appliqué ton idée de simulation de données du port série, le résultat semble positif avec le script modifié selon ton autre idée ( le script n'appelle pas directement /dev/ttyS0 dans la boucle ). Je testerai en réel dès que possible.
Il reste que mon script initial qui ne fonctionnait pas produit une sortie conforme à mes attentes avec la simulation...
Merci
Le Wed, 27 Jun 2007 00:42:34 +0200, Fabien LE LEZ a écrit:
Bonjour,
J'ai appliqué ton idée de simulation de données du port série, le résultat
semble positif avec le script modifié selon ton autre idée ( le script
n'appelle pas directement /dev/ttyS0 dans la boucle ).
Je testerai en réel dès que possible.
Il reste que mon script initial qui ne fonctionnait pas produit une sortie
conforme à mes attentes avec la simulation...
Le Wed, 27 Jun 2007 00:42:34 +0200, Fabien LE LEZ a écrit:
Bonjour,
J'ai appliqué ton idée de simulation de données du port série, le résultat semble positif avec le script modifié selon ton autre idée ( le script n'appelle pas directement /dev/ttyS0 dans la boucle ). Je testerai en réel dès que possible.
Il reste que mon script initial qui ne fonctionnait pas produit une sortie conforme à mes attentes avec la simulation...