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

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 气象数据收集与可视化)