树莓派 + 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容