Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Param

4 réponses
Avatar
Christophe Maquaire
Bonjour,

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...)

j'essaie:

cat /dev/ttyS0 | awk '{gsub(/\015/, "", $0); printf("%s%s", $0, /:/?FS:RS
)}'>> /home/francois/alarme/$(date +%Y_%m) &

(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.

4 réponses

Avatar
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 !)

Avatar
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

Avatar
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

Avatar
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