Conclusão de informações na tela do comprador

A tela do cliente apareceu. Tornou-se interessante tentar usá-lo como um painel de informações para exibir informações sobre o dia atual, horário até o final do dia / semana útil, informações sobre o tempo e taxas de câmbio.


Ao mesmo tempo, não queria usar aplicativos com muitos recursos e meu PC. Ele parou em um monte de mini-PC Raspberry + Linux + Customer Display.


@ Visor do cliente com informações | centro | 700x0


@Raspberry Pi 2 | centro | 300 x 0


Comentários obrigatórios


Não considero instalar e configurar o Linux OS em um dispositivo Raspberry neste artigo.

Para editar texto no Linux, usei os editores nano e mcedit.
Para acessar um mini-PC baseado no Linux a partir do Windows, ele usava clientes para acesso remoto via protocolo SSH - KiTTY / PuTTY.
Para transferir arquivos entre Windows e Linux, usei o WinSCP.

Bash - shell (concha).
Bash é uma abreviação de "Bourne-Again Shell" (shell "revivido"). Palavras-chave, sintaxe e outros recursos básicos da linguagem foram emprestados de outro sh shell (abreviação de shell).
O Bash também é uma poderosa linguagem de programação.

Estou envolvido na manutenção de produtos de software baseados em 1C e, para mim, foi uma oportunidade de me familiarizar com a programação no ambiente Linux.
Na melhor das hipóteses, explicarei os comandos que estão sendo executados. O objetivo é atingir um grande público.

O que você usou?


  • Computador de placa única Raspberry Pi 2 Modelo B v1.1 com Raspbian GNU / Linux 9.4 (estiramento) instalado.
  • Exibição do cliente POSUA LPOS-VFD USB.
  • O shell bash

1ª etapa. Conectar e configurar a exibição do cliente


Depois de conectar a tela do cliente (DP) à porta USB, descobriremos os parâmetros do dispositivo conectado. No terminal, execute o comando:


usb-devices 

Obtenha uma lista de dispositivos USB conectados ao Raspberry:


 T: Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=480 MxCh= 1 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1d6b ProdID=0002 Rev=04.14 S: Manufacturer=Linux 4.14.69-v7+ dwc_otg_hcd S: Product=DWC OTG Controller S: SerialNumber=3f980000.usb C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 5 D: Ver= 2.00 Cls=09(hub ) Sub=00 Prot=02 MxPS=64 #Cfgs= 1 P: Vendor=0424 ProdID=9514 Rev=02.00 C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=2mA I: If#= 0 Alt= 1 #EPs= 1 Cls=09(hub ) Sub=00 Prot=02 Driver=hub T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=00 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0424 ProdID=ec00 Rev=02.00 C: #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=2mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=ff Driver=smsc95xx T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0000 ProdID=0131 Rev=01.00 S: Manufacturer=www.posua.com S: Product=POSua LPOS-II-VFD USB CDC C: #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr=16mA I: If#= 0 Alt= 0 #EPs= 3 Cls=02(commc) Sub=02 Prot=01 Driver=usbserial_generic I: If#= 1 Alt= 0 #EPs= 2 Cls=03(HID ) Sub=00 Prot=00 Driver=usbhid 

A partir das informações recebidas pelo comando, encontramos a linha Product = POSua LPOS-II-VFD USB CDC . Esta é a exibição do nosso cliente. Nesta seção, precisamos da linha Fornecedor = 0000 ProdID = 0131 Rev = 01.00. Ou seja, fornecedor = 0000 prodID = 0131 . Então o dispositivo se identifica.


Para a operação correta com o DP, é necessário carregar o módulo de operação USB no núcleo do sistema. Execute o comando com privilégios elevados:


 sudo modprobe usbserial vendor=0x0000 product=0x0131 

modprobe é um programa para adicionar módulos ao kernel do Linux. usbserial é um módulo do kernel que emula uma porta COM em dispositivos USB. 0x - significa formato hexadecimal.


Como tenho um dispositivo USB conectado, em um sistema Linux, ele recebe automaticamente o arquivo ttyUSB0 . Esse é um recurso importante para interagir com dispositivos no Linux - trabalhar com o dispositivo como um arquivo. Os arquivos do dispositivo são armazenados no /dev .


Para funcionar corretamente com o DP, defina a taxa de transferência de dados:


 stty -F /dev/ttyUSB0 9600 

stty - o comando define os parâmetros de entrada / saída do terminal para o dispositivo. -F é o dispositivo. No nosso caso, a exibição do comprador é /dev/ttyUSB0 . E para este dispositivo, é definida uma velocidade de 9600 bauds.


Agora você pode tentar exibir uma mensagem de boas-vindas (em inglês até o momento):


 echo "Hello!" > /dev/ttyUSB0 

Se tudo foi feito corretamente, nossa mensagem aparecerá na tela. Mais detalhes sobre a equipe abaixo.


2 etapa. Programação


No estágio anterior, exibimos uma mensagem em inglês na parte superior da tela inicial do dispositivo. E não é muito bonito.


Para limpar a tela de exibição, execute o comando:


 echo -e -n "\x0c\x0b" > /dev/ttyUSB0 

comando de saída echo - terminal. A opção -e - habilita o suporte para a saída de seqüências de escape, -n - indica que não é necessário gerar feeds de linha. A entrada -en é permitida.


Combinações de caracteres que consistem em uma barra invertida \ seguida por uma letra ou um conjunto de números são chamadas seqüências de escape.

0 - limpa a tela do visor e cancela o modo de linha, 0b - move o cursor para a posição superior esquerda. Símbolo > - controle de fluxo (redireciona a saída). Nesse caso, o arquivo / dev / ttyUSB0 do nosso dispositivo. Se você acabou de executar o echo "Hello!" , o texto indicado entre aspas será exibido na janela do terminal.


A propósito, o comando que altera a velocidade de transmissão de dados para o dispositivo pode ser escrito da seguinte maneira:


 stty 9600 < /dev/ttyUSB0 

Bem, para exibir mensagens em russo, faça:


 echo -n "!" | iconv -f UTF-8 -t CP866 > /dev/ttyUSB0 

| - Redireciona a saída de um comando para a entrada de outro (pipeline). No nosso caso, a sequência de caracteres "Olá!" não é enviado imediatamente para o arquivo do dispositivo, mas transferido para o utilitário de "conversão" iconv. iconv - converte de uma codificação para outra.
O shell bash permite que você não apenas execute comandos diretamente no terminal, mas também grave arquivos de script.


Um script é um arquivo de texto sem formatação com uma sequência de comandos executados.

Para que o bash entenda que é isso, no início do arquivo é #! / Bin / bash . E para executar o script diretamente, você precisa executar o comando:


 sudo chmod u+x namefile.sh 

Onde namefile.sh é o arquivo de script. A extensão sh - significa que é um arquivo de script bash. chmod é um programa para alterar os direitos de acesso a arquivos e diretórios. u+x - define o direito de executar o arquivo para o usuário atual.


Vamos resolver o problema com dois scripts. O primeiro script é o principal ( dispos.sh ). Ele exibe todas as informações necessárias na tela do comprador. O segundo auxiliar ( parse.sh ) recebe dados climáticos, serviços de cotação de moeda e grava dados em arquivos intermediários. Arquivos de dados intermediários são usados ​​no primeiro script.


Para que os scripts possam ser executados, você deve executar os seguintes comandos:


 sudo chmod +x dispos.sh sudo chmod +x parse.sh 

Observe que apenas +x . Esta é uma versão abreviada de u+x .


Os scripts precisam ser executados em intervalos regulares. Para fazer isso, use o planejador crontab padrão. Para editar, use o comando:


 crontab -e 

Adicione duas linhas ao planejador:


 */20 * * * * /home/pi/parse.sh */1 * * * * /home/pi/dispos.sh 

O script parse.sh é executado a cada 20 minutos e o script dispos.sh a cada minuto.


Antes da exibição inicial do cliente na exibição, você deve primeiro executar o script parse.sh, que receberá os principais dados meteorológicos e de moeda.


 ./parse.sh 

A seguir, darei os scripts completos com pequenos comentários.


Descrição dos arquivos de script


Arquivo Dispos.sh


arquivo dispos.sh
 #!/bin/bash #        POSua LPOS-VFD. # -  ttyUSB0. #     tty  : # modprobe usbserial vendor=0x0000 product=0x0131. #  0x0000  0x0131  ,   # usb-devices, lsusb  dmesg. #    stty 9600 < /dev/ttyUSB0. #          parse.sh #     crontab      . # **************************************************************** #   # ttyUSB -      (POS-) DEV_DISPLAY="/dev/ttyUSB0" #        #   ,  ,   18:00:00 #    17:00:00 TIME_OF_WORKDAY="18:00:00" if (( $(date "+%u") >= 5 )); then TIME_OF_WORKDAY="17:00:00" fi #      ( 17:00:00) #      DAY_OF_WEEKEND=`date +"%s" --date="friday 17:00:00"` # **************************************************************** #       #    disp_clear(){ echo -en "\x0c\x0b" > "${DEV_DISPLAY}" } #       disp_cr(){ echo -e "\x0b" > "${DEV_DISPLAY}" } #       disp_print(){ echo -n $1 | iconv -f UTF-8 -t CP866 > "${DEV_DISPLAY}" } # **************************************************************** #    # 1.    disp_clear #   disp_print ": `date "+%A"`" disp_cr #     disp_print " `date "+%d.%m.%Y %H:%M"`" sleep 8 # **************************************************************** # 2.       disp_clear disp_print "   . :" disp_cr HOURS=$(( ( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) / 3600 )) MINUTES=$(( (( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) - $HOURS * 3600) / 60 )) #       if (( $MINUTES > -1 )); then OUTPUT_TIME=" ${HOURS} . ${MINUTES} ." else OUTPUT_TIME=" !" fi #       disp_print "${OUTPUT_TIME}" sleep 8 # **************************************************************** # 3.       disp_clear disp_print "  . :" disp_cr DAYS=$(( ($DAY_OF_WEEKEND-$(date +%s)) / (24*3600) )) HOURS=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600)) / 3600 )) MINUTES=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600) - ($HOURS*60*60)) / 60 )) #       if (( $MINUTES > -1 )); then OUTPUT_TIME="${DAYS} . ${HOURS} . ${MINUTES} " else OUTPUT_TIME=" !" fi #       disp_print "${OUTPUT_TIME}" sleep 8 # **************************************************************** # 4.     # 4.1.      LINE1=$(sed -n '1{p;q}' /tmp/weather.txt) DISPLAY_LINE1=${LINE1:0:19} DISPLAY_LINE2=${LINE1:19:19} #     (2 ) disp_clear disp_print "${DISPLAY_LINE1}" disp_cr disp_print "${DISPLAY_LINE2}" sleep 4 # 4.2.    LINE1=$(sed -n '2{p;q}' /tmp/weather.txt) DISPLAY_LINE1=${LINE1:0:14} DISPLAY_LINE2=${LINE1:14:19} #     (2 ) disp_clear disp_print " ${DISPLAY_LINE1}" disp_cr disp_print "${DISPLAY_LINE2}" sleep 8 # **************************************************************** # 5.      #      #  DOLLAR=$(sed -n '1{p;q}' /tmp/ex.txt) DOLLAR=${DOLLAR//–/-} #  EURO=$(sed -n '2{p;q}' /tmp/ex.txt) EURO=${EURO//–/-} #     disp_clear disp_print ": ${DOLLAR}" disp_cr disp_print ": ${EURO}" sleep 8 # **************************************************************** # 6.      #      # BTC while read line do BTC=${line:0:13} done </tmp/bitcoin.txt # ETH while read line do ETH=${line:0:13} done </tmp/ethereum.txt #     #      disp_clear disp_print "BTC: ${BTC//./,}" disp_cr disp_print "ETH: ${ETH//./,}" #sleep 8 # **************************************************************** # 7.      #      (.  20 ) #DISPLAY_LINE1="  !" #DISPLAY_LINE2="  !" #      #disp_clear #disp_print "${DISPLAY_LINE1:0:19}" #disp_cr #disp_print "${DISPLAY_LINE2:0:19}" 

Comentários


Para exibir a data atual, use o comando date . Exemplo


 echo `date "+%d.%m.%Y %H:%M"` 

Após a execução, obtemos a data do formulário: 20/05/2019 12:11.


Para calcular o tempo até o final do dia, usamos a variável adicional TIME_OF_WORKDAY e configuramos o valor TIME_OF_WORKDAY="18:00:00" . Bem, então calculamos as horas e minutos até o final do dia útil:


 HOURS=$(( ( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) / 3600 )) MINUTES=$(( (( $(date +%s --date=$TIME_OF_WORKDAY) - $(date +%s) ) - $HOURS * 3600) / 60 )) 

O símbolo $ indica que é uma variável.
O símbolo # é um comentário.


date +%s - obtém a data e a hora atuais em segundos.
date +%s --date=$TIME_OF_WORKDAY - obtenha o tempo em segundos até TIME_OF_WORKDAY ("18:00:00") .


Cálculo do tempo até o final da semana de trabalho:


 DAYS=$(( ($DAY_OF_WEEKEND-$(date +%s)) / (24*3600) )) HOURS=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600)) / 3600 )) MINUTES=$(( (($DAY_OF_WEEKEND-$(date +%s)) - ($DAYS*24*3600) - ($HOURS*60*60)) / 60 )) 

Onde DAY_OF_WEEKEND=`date +"%s" --date="friday 17:00:00"` é o tempo em segundos do tempo atual até sexta-feira 17:00:00.


Parte do script é implementada usando funções. Por exemplo


 #    disp_clear(){ echo -en "\x0c\x0b" > "${DEV_DISPLAY}" } 

disp_clear() é o nome da função. Em {} , comandos executáveis ​​são indicados.


A variável DEV_DISPLAY é "global" e é definida no início do script e, portanto, DEV_DISPLAY="/dev/ttyUSB0" .


Lendo dados de um arquivo, por exemplo, uma linha específica (1):


 LINE1=$(sed -n '1{p;q}' /tmp/weather.txt) 

sed é um editor de texto que executa operações de edição de informações em um fluxo ou arquivo de entrada padrão. A -n exibe a linha selecionada no momento. '1{p;q}' - imprime 1 linha e sai sem ler o restante ( p -print, q -output).


Outra opção para ler de um arquivo (linha por linha):


 while read line do BTC=${line:0:13} done </tmp/bitcoin.txt 

E, portanto, DISPLAY_LINE1=${LINE1:0:14} da linha LINE1 extraímos uma subcadeia de 14 caracteres de comprimento, começando em 0.


Os caracteres são substituídos pela combinação // , por exemplo, DOLLAR//–/- . O símbolo "-" é substituído por um "-".


Arquivo parse.sh


arquivo parse.sh
 #!/bin/bash #      RSS   http://rp5.ru/rss/1859/ru # 1859 -    #       conv(){ #        CURRENCY=$(sed -n '1!G;h;$p' /tmp/ex.xml | sed -n "${1}{p;q}") CURRENCY=${CURRENCY//[^,^(^)^0-9^–^+]/} echo $CURRENCY } #   c     # 1.  wget -q -O /tmp/rp5weather.xml http://rp5.ru/rss/1859/ru # 2.      wget -q -O /tmp/ex.xml http://currr.ru/rss/ # 3.   bitcoin/ethereum wget -q -O /tmp/bitcoin.json https://api.coinmarketcap.com/v1/ticker/bitcoin/ wget -q -O /tmp/ethereum.json https://api.coinmarketcap.com/v1/ticker/ethereum/ #   #   ,  ,    #     LINE31=$(sed -n '31{p;q}' /tmp/rp5weather.xml) LINE33=$(sed -n '33{p;q}' /tmp/rp5weather.xml) WEATHER1=${LINE31//"</title>"} WEATHER1=${WEATHER1//" °C"} WEATHER1=${WEATHER1//"  "} WEATHER1=${WEATHER1:29} WEATHER2=${LINE33##*} WEATHER2=${WEATHER2//"°"} echo "${WEATHER1}" > /tmp/weather.txt echo ${WEATHER2%.*} >> /tmp/weather.txt #   Bitcoin LINEBTC=$(sed -n '7{p;q}' /tmp/bitcoin.json) echo "${LINEBTC//[^.^0-9]/}" > /tmp/bitcoin.txt #   Ethereum LINEETH=$(sed -n '7{p;q}' /tmp/ethereum.json) echo "${LINEETH//[^.^0-9]/}" > /tmp/ethereum.txt #   DOLLAR=$(conv 8) echo $DOLLAR > /tmp/ex.txt EURO=$(conv 6) echo $EURO >> /tmp/ex.txt 

Comentários


O comando wget permite baixar arquivos, páginas etc. da rede. A opção -q - exibe um mínimo de informações, -O - salva no arquivo especificado.


As linhas abaixo gravam no arquivo:


 echo "${WEATHER1}" > /tmp/weather.txt echo ${WEATHER2%.*} >> /tmp/weather.txt 

Além disso, se o redirecionamento do fluxo de saída para o arquivo > , o conteúdo do arquivo será sobrescrito e use >> anexa dados ao arquivo.


Um exemplo de uso de um parâmetro em uma função:


 conv 6 

Diretamente em função:


 CURRENCY=$(sed -n '1!G;h;$p' /tmp/ex.xml | sed -n "${1}{p;q}") 

Onde {1} é o parâmetro. O número 6 é passado.


Preste atenção à função de substituição de substring complicada, por exemplo:


 LINEBTC//[^.^0-9]/ 

Somente o "." e todos os números são de 0 a 9.


Posfácio


No bash, quase todos os recursos das linguagens de programação "comuns" estão disponíveis. E algumas equipes, em comparação com os análogos em 1C, surpreendem com seu laconicismo e funcionalidade.


No momento, a exibição do cliente como um quadro de avisos está funcionando de forma estável há mais de seis meses.


Lista de recursos


  1. Página de exibição do comprador LPOS-VFD
  2. Programar símbolos de moeda para exibição do cliente
  3. Noções básicas do BASH (parte 1)
  4. Noções básicas do BASH (parte 2)
  5. Como usar o PuTTY
  6. Editor de texto nano Linux para iniciantes
  7. Manual para usuários do WinSCP

Source: https://habr.com/ru/post/pt457352/


All Articles