Como extrair determinados dados de um fluxo MQTT

1

Eu digito mosquitto_sub -d -t +/# do terminal do Ubuntu para acessar o fluxo do MQTT.

No entanto, gostaria de ver apenas um conjunto específico de dados do fluxo do MQTT. Eu adicionei | grep -v PING para que tudo ainda seja impresso, exceto para as linhas com PING, mas isso não funcionou.

Eu tentei | grep -A1 PUBLISH para que eu possa ver linhas do MQTT com PUBLISH neles, nada mudou: Acabei de receber todo o fluxo do MQTT e nada foi filtrado.

Como posso ver a coisa certa que quero ver de um fluxo do MQTT? Alternativamente; Como posso filtrar certas coisas do fluxo do MQTT ou como posso extrair dados do fluxo do MQTT?

Minha entrada do terminal do ubuntu é a seguinte $ mosquitto_sub -d -t +/# e eu tentei $ mosquitto_sub -d -t +/# | grep -v PING e $ mosquitto_sub -d -t +/# | grep -A1 PUBLISH , mas ele apenas transmite tudo, não faz nada. A saída é a seguinte:

ed@agharta:~$ mosquitto_sub -d -t +/#
Received CONNACK
Received SUBACK
Subscribed (mid: 1): 0
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/jsyd/TEST/001/d/status', ... (34 bytes))
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/jsyd/TEST/001/d/SVlts', ... (28 bytes))
Sending PINGREQ
Received PINGRESP

Por exemplo, como posso somente ver o PUBLISH da transmissão ao vivo e não dos PINGs?

    
por 3kstc 24.02.2015 / 03:48

1 resposta

2

Eu estava escrevendo a seguinte resposta à outra pergunta relacionada aqui quando foi excluída . Não sei se você conseguirá seguir esse link, mas (uma abreviação de) os dados de exemplo mencionados abaixo são:

Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
Received PUBLISH (d0, q0, r0, m0, 'm/gf/TMX6BP/075/d/SVlts', ... (28 bytes))
86,1224830,27610 27869 17565
Received PUBLISH (d0, q0, r0, m0, 'm/gf/TMX6BP/075/d/status', ... (39 bytes))
86,1243000,164573,-33.836465,151.051189
Sending PINGREQ
Received PINGRESP

Então, escrevi o seguinte para que funcione com sed da seguinte forma:

mosquitto ... 2>&1 | 
sed -u "/.*PUBLISH[^']*\([^,]*,\).*/!d 
       s///;N;s/[\%]/&&/g;s/'/&\\&&/g
       s/.*/printf '&'/;s/\n/'&date '+[%s,]/"|  
sh -s

Agora, eu não tenho o seu programa mosquitto , mas se eu copiar todo o seu exemplo na minha área de transferência, e faça:

xsel -bo | sed ... | sh ...

Imprime:

'm/gf/TMX6BP/075/d/SVlts',[1425002404,]86,1224830,27610 27869 17565
'm/gf/TMX6BP/075/d/status',[1425002404,]86,1243000,164573,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002404,]806,3040421,7549 7750 3904
'm/NWRL/TMX/098/d/status',[1425002404,]806,3069000,59666,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002404,]810,5440995,6143 7807 4076
'm/NWRL/TMX/098/d/status',[1425002404,]810,5489000,59897,-33.836465,151.051189

... qual é, eu acho, o que você quer. Ele funciona garantindo que todas as entradas sejam citadas com segurança para o shell e para as sequências de formato date e printf e, em seguida, a construção de comandos shell a partir de cada par de linhas.

Para cada par de linhas printf primeiro imprime o conteúdo da primeira linha sem um \n de ewline, então date imprime o [timestamp] em segundos desde a época, seguido do conteúdo da segunda linha e um \n ewline à direita. A saída de sed é algo assim:

printf ''\''m/gf/TMX6BP/075/d/SVlts'\'','
date '+[%s,]86,1224830,27610 27869 17565'

Nenhum dos comandos impressos em sh , é claro, são executados até sed imprimi-los nele. Portanto, se sed estivesse lendo a saída de mosquitto e uma linha aparecesse depois de uma anterior, a linha date refletiria isso.

Por exemplo:

(set -f; IFS='
';  for l in $(xsel -bo)
    do  printf %s\n "$l"
        sleep 1
    done) |
sed -u "/.*PUBLISH[^']*\([^,]*,\).*/!d 
       s///;N;s/[\%]/&&/g;s/'/&\\&&/g
       s/.*/printf '&'/;s/\n/'&date '+[%s,]/"|  
sh -s

... que aguarda um segundo antes de imprimir todas as linhas de saída em sed para poder emular mais fielmente uma transmissão em direto. Ele tira proveito do switch sed -u nbuffered do GNU para obter a saída de saída de sed o mais rápido possível, mas se isso não estiver disponível, deixe-me saber e mostrarei como bloquear um pipe corretamente com dd para evitar problemas de buffer.

De qualquer forma, as impressões acima:

'm/gf/TMX6BP/075/d/SVlts',[1425002863,]86,1224830,27610 27869 17565
'm/gf/TMX6BP/075/d/status',[1425002865,]86,1243000,164573,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002869,]806,3040421,7549 7750 3904
'm/NWRL/TMX/098/d/status',[1425002871,]806,3069000,59666,-33.836465,151.051189
'm/NWRL/TMX/098/d/SVlts',[1425002881,]810,5440995,6143 7807 4076
'm/NWRL/TMX/098/d/status',[1425002885,]810,5489000,59897,-33.836465,151.051189
    
por 27.02.2015 / 04:23