买方展示信息的结论

出现了客户显示。 尝试将其用作信息面板来显示有关当前日期,直到工作日/周结束的时间,天气信息和汇率的信息变得很有趣。


同时,我不想使用资源密集型应用程序和PC。 他停在一堆微型PC Raspberry + Linux +客户显示器上。


@客户显示信息|中心| 700x0


@Raspberry Pi 2 |中心| 300x0


必填项


在本文中,我不考虑在Raspberry设备上安装和配置Linux OS。

为了在Linux中编辑文本,我使用了nano和mcedit编辑器。
为了从Windows访问基于Linux的微型PC,他使用客户端通过SSH协议KiTTY / PuTTY进行远程访问。
为了在Windows和Linux之间传输文件,我使用了WinSCP。

Bash-壳(shell)。
Bash是“ Bourne-Again Shell”(“复活的” shell)的缩写。 该语言的关键字,语法和其他基本功能是从另一个sh shell(shell的缩写)中借用的。
Bash也是一种功能强大的编程语言。

我从事基于1C的软件产品的维护,对我来说,这是我自己熟悉Linux环境中编程的机会。
据我所知,我将解释正在执行的命令。 这样做的目的是吸引大量观众。

你用了什么?


  • 安装了Raspbian GNU / Linux 9.4(拉伸)的Raspberry Pi 2 Model B v1.1单板计算机。
  • 客户显示POSUA LPOS-VFD USB。
  • bash外壳

第一阶段。 连接并设置客户展示


将客户的显示器(DP)连接到USB端口后,我们将查找所连接设备的参数。 在终端中,执行以下命令:


usb-devices 

获取连接到Raspberry的USB设备的列表:


 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 

从命令收到的信息中,我们找到行Product = POSua LPOS-II-VFD USB CDC 。 这是我们的客户显示。 在本节中,我们需要行Vendor = 0000 ProdID = 0131 Rev = 01.00。 即vendor = 0000 prodID = 0131 。 因此设备可以识别自己。


为了使DP正确运行,必须将USB操作模块加载到系统内核中。 以提升的特权运行命令:


 sudo modprobe usbserial vendor=0x0000 product=0x0131 

modprobe是用于将模块添加到Linux内核的程序。 usbserial是一个内核模块,可模拟USB设备上的COM端口。 0x-表示十六进制格式。


由于我连接了一个USB设备,因此在Linux系统上,它会自动接收ttyUSB0文件。 这是与Linux中的设备进行交互的一项重要功能-将设备作为文件使用。 设备文件存储在/dev


要正确使用DP,请设置数据传输速率:


 stty -F /dev/ttyUSB0 9600 

stty该命令设置设备的终端输入/输出参数。 -F是设备。 在我们的例子中,买方的显示是/dev/ttyUSB0 。 对于此设备,设置的速度为9600波特。


现在,您可以尝试显示欢迎消息(到目前为止为英语):


 echo "Hello!" > /dev/ttyUSB0 

如果一切都正确完成,那么我们的消息将出现在屏幕上。 有关以下团队的更多详细信息。


2阶段。 程式设计


在上一阶段,我们在设备的初始屏幕上方以英文显示了一条消息。 而且不是很漂亮。


要清除显示屏,请执行以下命令:


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

echo终端输出命令。 选项-e启用对转义序列输出的支持, -n表示不需要输出换行。 允许-en条目。


由反斜杠\后跟一个字母或一组数字组成的字符组合称为转义序列。

0清除显示屏并取消线路模式, 0b将光标移动到最左上位置。 符号> -流量控制(重定向输出)。 在这种情况下,我们设备的文件/ dev / ttyUSB0 。 如果只运行echo "Hello!" ,则引号中指示的文本将出现在终端窗口中。


顺便说一句,更改将数据传输到设备的速度的命令可以编写为:


 stty 9600 < /dev/ttyUSB0 

好吧,要显示俄语消息,请执行以下操作:


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

| -将一个命令的输出重定向到另一个(管道)的输入。 在我们的例子中,字符序列“ Hello!” 它不会立即输出到设备文件中,而是会传输到“转换”实用程序iconv中。 iconv从一种编码转换为另一种编码。
bash shell使您不仅可以直接在终端中执行命令,还可以编写脚本文件。


脚本是具有一系列已执行命令的纯文本文件。

为了使bash知道它是“ his”,在文件的开头指示#!/ bin / bash 。 要直接执行脚本,您需要运行以下命令:


 sudo chmod u+x namefile.sh 

其中,namefile.sh是脚本文件。 sh扩展名-表示它是bash脚本文件。 chmod是用于更改文件和目录访问权限的程序。 u+x设置为当前用户执行文件的权限。


我们将用两个脚本解决问题。 第一个脚本是主要的脚本( dispos.sh )。 它在买家的显示屏上显示所有必要的信息。 第二个辅助工具( parse.sh )接收天气数据,货币报价服务,并将数据写入中间文件。 在第一个脚本中使用中间数据文件。


为了使脚本能够运行,您需要运行以下命令:


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

请注意,仅使用+x 。 这是u+x的简化版本。


脚本需要定期运行。 为此,请使用标准的crontab调度程序。 要编辑,请使用以下命令:


 crontab -e 

向调度程序添加两行:


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

parse.sh脚本每20分钟运行一次,而dispos.sh脚本每分钟运行一次。


在客户首次显示在显示屏上之前,必须首先运行parse.sh脚本该脚本将接收主要的天气和货币数据。


 ./parse.sh 

接下来,我将给出完整的脚本,并附有简短的注释。


脚本文件说明


Dispos.sh文件


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}" 

留言


要显示当前日期,请使用date命令。 例子


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

执行后,我们得到表格的日期:05/20/2019 12:11。


要计算直到一天结束的时间,我们使用附加变量TIME_OF_WORKDAY并设置值TIME_OF_WORKDAY="18:00:00" 。 好吧,然后我们计算直到工作日结束的小时和分钟:


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

$符号表示它是一个变量。
#符号为注释。


date +%s以秒为单位获取当前日期和时间。
date +%s --date=$TIME_OF_WORKDAY以秒为单位获取直到TIME_OF_WORKDAY ("18:00:00")为止的时间。


计算到工作周结束的时间:


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

其中DAY_OF_WEEKEND=`date +"%s" --date="friday 17:00:00"`是从当前时间到星期五17:00:00的时间,以秒为单位。


该脚本的一部分是使用函数实现的。 举个例子


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

disp_clear()是函数的名称。 在{} ,指示可执行命令。


变量DEV_DISPLAY是“ global”,并且在脚本的开头设置,因此DEV_DISPLAY="/dev/ttyUSB0"


从文件读取数据,例如特定行(1):


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

sed是一种文本编辑器,可对标准输入流或文件中的信息执行编辑操作。 -n显示当前选定的行。 '1{p;q}' -打印1行并退出,不读取其余内容( p打印, q输出)。


从文件读取的另一种选项(逐行):


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

因此,从第LINE1行中, DISPLAY_LINE1=${LINE1:0:14}LINE1提取了一个从0开始长度为14个字符的子字符串。


字符由组合//代替,例如DOLLAR//–/- 。 “-”符号由“-”代替。


文件parse.sh


文件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 

留言


wget命令允许您从网络下载文件,页面等。 选项-q显示最少信息, -O保存到指定文件。


下面的行将写入文件:


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

而且,如果使用了将输出流重定向到文件> ,那么文件的内容将被覆盖,并使用>>将数据追加到文件中。


在函数中使用参数的示例:


 conv 6 

直接作用:


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

其中{1}是参数。 数字6已通过。


请注意复杂的子字符串替换功能,例如:


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

只有“。” 所有数字都从0到9。


后记


在bash中,“常规”编程语言的几乎所有功能都可用。 与1C中的类似物相比,有些团队对其简洁性和功能性感到惊讶。


目前,客户在电子公告板上的显示效果已经稳定运行了六个多月。


资源清单


  1. LPOS-VFD买家显示页面
  2. 用于客户显示的程序货币符号
  3. BASH基础(第1部分)
  4. BASH基础(第2部分)
  5. 如何使用腻子
  6. 适用于初学者的Linux Nano文本编辑器
  7. WinSCP用户手册

Source: https://habr.com/ru/post/zh-CN457352/


All Articles