美文网首页玩转树莓派物联网相关技术研究物联网IOT创意开发
树莓派 + pyecharts + nginx 气象数据收集与可

树莓派 + pyecharts + nginx 气象数据收集与可

作者: 在路上_lemo | 来源:发表于2019-11-04 13:00 被阅读0次
    h4.png

    这个小“项目”已经稳定运行近2年了。主要特性是树莓派将收集的室内温度、湿度和室外温度以及CPU温度等数据存入sqlite数据库,利用pyecharts进行数据可视化,用nginx做服务器,可通过网页浏览。申请公网IP后,外出时也可以查看数据。

    硬件清单

    1. 树莓派 Zero W
    2. ds18b20模块
    3. sht30模块
    

    软件清单

    1. python
    2. pyecharts
    3. nginx
    

    硬件搭设

    1. 树莓派 zero w价格便宜,自带wifi模块,功能强大。到手后刷入官方lite版系统,不需要桌面。具体请参考教程,“无屏幕和键盘配置树莓派WiFi和SSH”。
      raspberry-pi-zero-w.jpg
    1. 室外温度采用ds18b20模块,此模块为“单总线模块”,数据和电源共用一条线,加上地线共两条线,正好一根据电话线即可,接线见下图。


      ds18b202.png

    总接线图如下

    1. sht30是盛世瑞恩出产的一款基于i2c传输协议的温、湿度传感器,联线比较简单,唯一需要注意的是它的电压是3.3V,不要接到5V上去了。


      set.png

    编写程序

    1. 主程序

    主程序调用各个模块的功能。

    1. 获取温度、湿度等数据
    2. 将获得的数据存入sqlite数据库
    3. 利用用pycharts生成可视化数据
    #run.py
    import sys
    import time
    import genHtml2
    import rpi_stat
    import sht30
    import sys
    import sqlite3
    
    wait = 10
    interval = 60*10
    while True:
        #取得当前时间
        time_date = time.strftime("%Y/%m/%d",time.localtime())
        time_time = time.strftime("%H:%M",time.localtime())
        #取得CPU温度和负载
        cpu_t =rpi_stat.getCPUTemp()
        cpu_load = rpi_stat.getLoad()
        #取得室内温、湿度
        room_t, room_h = sht30.get()
        #取得室外温度
        out_t = getDs18b20()
        #将数据存入数据库
        cn = sqlite3.connect('weather.db')
        cu = cn.cursor()
        item = [None]
        item.append(time_date)
        item.append(time_time)
        item.append(room_t)
        item.append(out_t)
        item.append(room_h)
        item.append(cpu_t)
        item.append(cpu_load)
        item.append(volt)
        cu.execute("INSERT INTO record values(?,?,?,?,?,?,?,?,?)", tuple(item))
        cn.commit()
        #生成pyecharts网页
        genHtml2.gen()
        time.sleep(interval)
    

    2. 获取室内温、湿度

    #sht30.py
    import smbus
    import time
    
    def get():
        bus = smbus.SMBus(1)
        bus.write_i2c_block_data(0x44, 0x2C, [0x06])
        time.sleep(0.5)
        data = bus.read_i2c_block_data(0x44, 0x00, 6)
        cTemp = ((((data[0] * 256.0) + data[1]) * 175) / 65535.0) - 45
        humidity = 100 * (data[3] * 256 + data[4]) /65535.0
        
        return(round(cTemp,2),round(humidity,2))
    

    3. 获取室外温度

    def getDs18b20():
        with open("/sys/bus/w1/devices/28-000004b1dd3f/w1_slave") as f:
            text = f.readlines()
            secondline=text[1]
            temp = secondline.split(" ")[9]
            temp = temp.strip()
            temp = float(temp[2:])/1000
            return temp
    

    4. 获取CPU温度和负载

    rpi_stat.py
    import time
    import os
    
    def getCPUTemp():
        with open("/sys/class/thermal/thermal_zone0/temp") as file:
            res = file.readline()
        return round(int(res)/1000,2)
    
    def getLoad():
        res = os.popen("uptime").readline().split()[-3]
        return int(float(res.replace(',',''))*100)
    

    5. 使用pyecharts生成网页

    pyecharts是一款将python与echarts结合的强大的数据可视化工具,是Python数据可视化利器!
    项目地址https://github.com/pyecharts/pyecharts,有详细的教程。

    安装 pyecharts
    pip install pyecharts

    #genHtml.py
    from pyecharts import Line,Page
    import platform
    import sqlite3
    import util
    
    def gen():
        cn = sqlite3.connect('weather.db')
        cu = cn.cursor()
    
        textsize = 32
        time_st = []
        room_t = []
        out_t = []
        room_h = []
        cpu_t = []
        cpu_load = []
        bat_volt = []
    
        sql = "SELECT *  FROM record order by id desc limit 100 "
        rec = cu.execute(sql)
        # print(type(list(rec)))
        lst = list(rec)
        lst.reverse()
    
        for line in lst:
            tm_st = line[1][5:].replace("/","-") +" "+line[2]
            time_st.append(tm_st)
            room_t.append(line[3])
            out_t.append(line[4])
            room_h.append(line[5])
            cpu_t.append(line[6])
            cpu_load.append(line[7])
            bat_volt.append(line[8])
    
        page = Page(page_title="My RPi Center")
    
        #数据总个数
        amount = len(time_st)
        #需要显示的个数(24小时)
        display = 72
        #display range
        dis_range = int((1-display/amount)*100)
    #    print(amount)
    
        line_room_t = Line("气温  %s/%s℃"%(str(room_t[-1]),str(out_t[-1])),
                title_pos='center',
                title_text_size=textsize,
                title_top='5%')
        line_room_t.add("室温", time_st, room_t,
                 xaxis_name='时间',
                 yaxis_name='温度(℃)',
                 yaxis_name_pos='end',
                 xaxis_name_pos='end',
                 xaxis_label_textsize=textsize,
                 yaxis_label_textsize=textsize,
                    label_text_size=textsize,
                        label_emphasis_textsize=textsize,
                        tooltip_font_size=textsize,
                        mark_point_textsize=10,
                 is_label_show=True,
                 line_width = 3,
                 line_curve = 0.5,
                 is_datazoom_show=True,
                 datazoom_type='slider',
                        datazoom_range=[80,100],
                 is_more_utils=True,
                 xaxis_force_interval=50,
                 yaxis_min=min(room_t)-5,
                 yaxis_max=max(room_t)+5,
                 tooltip_tragger='axis',
                 mark_point=['min','max'],
                 mark_line=['average'])
    
        page.add(line_room_t)
        ······
        #太长了,在此省略,详见https://github.com/lemodd
    
        #将页面保存到目录
        page.render('/home/pi/www/index.html')
    

    6. 完成

    到此用浏览器打开生成的index.html文件就可以看到结果了。这样只能在本机上查看,为了能随时随地的查看,需要一个http服务器,别的电脑和手机就可以用浏览器查看了。


    Snipaste_2019-11-02_20-05-48.png

    安装、配置nginx

    百度百科
    Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

    1.安装 nginx

    在终端运行命令
    sudo apt-get install nginx

    一路确认,即可完成安装。

    启动Nginx
    sudo /etc/init.d/nginx start

    可通过http://树莓派IP访问到 Nginx 的默认页。如果出现下图则说明nginx安装成功。

    nginx-start1.png

    2. 配置nginx

    修改 nginx 的配置文件
    sudo nano /etc/nginx/sites-available/default

    默认路径 html 所在路径,修改为你自己的。
    root /home/pi/www/

    监听的端口号,如果与其它软件冲突,可以在这里更改。
    listen 80 default_server

    重新加载
    sudo /etc/init.d/nginx reload

    再次打开树莓派IP,如果没有错误,就可以看到刚才生成的图表了。


    site.png

    外网访问设置

    到目前只能在家里的局域网访问,为了能在外网顺利访问到还需以下几步。

    1. 获取公网IP

    为了可以获得公网IP直接打宽带运营商的客服电话,一般会直接告诉你如何设置。不同的运营商和地区各有不同,我所在城市只需在用户名后加数字8即可变为外网IP。

    2. 设置端口转发

    即便获得了公网IP,80端口也是屏蔽的,需要设置下端口转发,外网端口设的8000,如下:


    port.png

    在路由器的互联网态中查到你的公网IP,访问地址 http://公网IP:8000,如果能看到图表,说明一切设置无误。这时在任何可以上网的地方都能查到家里的数据了。

    3. DDNS设置

    虽然现在可以在外网访问了,但是外网IP是不断变化的,每次拨号都会分配一个新的IP。为了能像一般网站一样用域名访问,只需设置下DDNS就可以了,打开路由器的DDNS设置,取一个别人没占用的名字。


    DDNS.png

    以后都可以通过二级域名来访问你的网站了。

    配置supervisor

    为了保证应用一直处于运行状态,在遇到断电、程序异常、报错等情况,导致应用终止时,需要保证程序可以立刻重启,继续提供服务。所以,就需要一个工具,时刻监控应用的运行情况,管理该进程。

    Supervisor 就是解决这种需求的工具,可以保证程序崩溃后,重新把程序启动起来等功能。

    安装supervisor
    sudo apt-get install supervisor

    新建配置文件
    sudo nano /etc/supervisor/conf.d/raspi-echarts.conf

    主要设置如下

    user=pi
    command=/usr/bin/python3 run.py ; 要运行的命令
    directory=/home/pi/py/echarts/  ; 程序所在的目录
    autorestart=True                ; 程序异常退出后自动重启
    autostart=True                  ; 在 supervisord 启动的时候也自动启动
    stdout_logfile=/var/log/supervisor/echarts.log
    stdout_logfile_maxbytes=1MB
    stdout_logfile_backups=10
    

    进入supervisorctl客户端,查看状态和管理
    sudo supervisorctl
    可以看到正在运行的进程。用help命令可以查看常用的命令。

    结束

    项目的所有源码在https://github.com/lemodd/raspberrypi-pyecharts

    相关文章

      网友评论

        本文标题:树莓派 + pyecharts + nginx 气象数据收集与可

        本文链接:https://www.haomeiwen.com/subject/mvzrbctx.html