基于Tornado搭建Raspberry Pi监控平台

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Linjingke32/article/details/70247004

在《Tornado - 基于Python的Web服务器框架》讲到一个性能很不错的python的web服务器框架tornado,现在就使用它在树莓派开发板上搭建一个简单地监控开发板状态网站。

这里先给出这个小项目的文件目录总体结构:

hardware文件夹是对开发板进行操作的硬件层

static是项目中用到的静态文件,如这里用到了bootstrap和echarts框架等

templates是html模板页,用于编写页面

项目根目录下的index.py是对应于templates/index.html文件的脚本,用于执行动态操作。

        -----------------------------------------------------------------------------------------------------------------------------

1. 项目开始,先建立index.py文件和相关目录文件:

index.py文件内容如下:

#!/usr/bin/env python
# coding=utf-8

import os.path

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from hardware import board_ctrl
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)


class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html', cpu_temperature="%s°C" % board_ctrl.get_cpu_temp())
    
    def post(self):
        board_ctrl.init_gpio()
        arg = self.get_argument('k')

        if (arg == 'w'):
            print 'press w'

        if (arg == 'o'):
            board_ctrl.open_light()
            self.write(arg)

        if (arg == 'c'):
            board_ctrl.close_light()
            self.write(arg)

        if (arg == 't'):
            board_ctrl.get_cpu_temperature()
            self.write(arg)

        if (arg == 'p'):
            self.write(str(board_ctrl.get_cpu_temp()))


if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
            handlers=[(r'/', IndexHandler)],
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), "static"),
            debug=True
        )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()
这里创建了一个handler,用于处理页面的Get、Post请求,在post请求根据请求参数的不一样,执行对应的操作。在“
self.render('index.html', cpu_temperature="%s°C" % board_ctrl.get_cpu_temp())
”这行中,cpu_temperature是在index.html里的一个变量,我们在返回这个页面是需要传递对应的参数去生成最终的页面,在app的初始化中,声明了templates和static的目录路径,这样tornado在启动后就会在这个路径下面去寻找html文件和css、js文件。

2. 编写index.html页面文件:

<!DOCTYPE html>
<html>
    <head>
        <title>Raspberry Pi Remote Control</title>
        <meta charset="utf-8"/>
        <script src="{{static_url('js/jquery.min.js')}}"></script>
        <script src="{{static_url('js/echarts.min.js')}}"></script>
        <script src="{{static_url('js/bootstrap.min.js')}}"></script>
        <link rel="stylesheet" type="text/css" href="{{static_url('css/bootstrap.min.css')}}">
	    <script type="text/javascript">
	        $(document).ready(function(){
	            setInterval("refresh_time()", 1000);
	            setInterval("refresh_cpu_temp()", 3000);

                //初始化echarts实例
                var myChart = echarts.init(document.getElementById('cpu_tem'));

                var colors = ['#5793f3', '#d14a61', '#675bba'];


                option = {
                    color: colors,

                    tooltip: {
                        trigger: 'none',
                        axisPointer: {
                            type: 'cross'
                        }
                    },
                    legend: {
                        data:['CPU温度', 'GPU温度']
                    },
                    grid: {
                        top: 70,
                        bottom: 50
                    },
                    xAxis: [
                        {
                            type: 'category',
                            axisTick: {
                                alignWithLabel: true
                            },
                            axisLine: {
                                onZero: false,
                                lineStyle: {
                                    color: colors[1]
                                }
                            },
                            axisPointer: {
                                label: {
                                    formatter: function (params) {
                                        return '温度  ' + params.value + ':' + params.seriesData[0].data;
                                    }
                                }
                            },
                            data: ["20:05", "20:10", "20:15", "20:20", "20:25", "20:30", "20:35", "20:40", "20:45", "20:50", "20:55", "21:00"]
                        },
                        {
                            type: 'category',
                            axisTick: {
                                alignWithLabel: true
                            },
                            axisLine: {
                                onZero: false,
                                lineStyle: {
                                    color: colors[0]
                                }
                            },
                            axisPointer: {
                                label: {
                                    formatter: function (params) {
                                        return '温度  ' + params.value + ':' + params.seriesData[0].data;
                                    }
                                }
                            },
                            data: ["20:05", "20:10", "20:15", "20:20", "20:25", "20:30", "20:35", "20:40", "20:45", "20:50", "20:55", "21:00"]
                        }
                    ],
                    yAxis: [
                        {
                            type: 'value'
                        }
                    ],
                    series: [
                        {
                            name:'CPU温度',
                            type:'line',
                            xAxisIndex: 1,
                            smooth: true,
                            data: [31.6, 31.9, 39.0, 36.4, 38.7, 30.7, 30.6, 32.2, 38.7, 38.8, 32.0, 32.3]
                        },
                        {
                            name:'GPU温度',
                            type:'line',
                            smooth: true,
                            data: [21.6, 21.9, 22.0, 23.4, 22.7, 20.7, 20.6, 22.2, 33.7, 28.8, 22.0, 22.3]
                        }
                    ]
                };

                myChart.setOption(option);

                ////////////////////////////
                //初始化echarts实例
                var cpu_usage = echarts.init(document.getElementById('cpu_usage'));

                option_cpu_usage = {
                    tooltip : {
                        formatter: "{a} <br/>{b} : {c}%"
                    },
                    toolbox: {
                        feature: {
                            restore: {},
                            saveAsImage: {}
                        }
                    },
                    series: [
                        {
                            name: 'CPU负载',
                            type: 'gauge',
                            detail: {formatter:'{value}%'},
                            data: [{value: 2, name: '百分比'}]
                        }
                    ]
                };

                cpu_usage.setOption(option_cpu_usage);
	        });

	        function refresh_time() {
		        $("#nowtime").text((new Date()).toLocaleDateString() + " " + (new Date()).toLocaleTimeString());
	        }

	        function refresh_cpu_temp() {
                $.ajax({
                    url:'/',
                    data:{k:'p'},
                    type:'post',
                    dataType:'text',
                    success:function(msg){
                        $("#cpu").text(msg + "°C");
                    }
                })
	        }
	   </script>
        <style type="text/css">
            .div_left {
                float: left;
                width: 50%;
                height: 400px;
            }
            .div_right {
                float: right;
                width: 50%;
                height: 400px;
            }
        </style>
    </head>

    <body>
        <script type="text/javascript">
            function go(k) {
                $.post('/', {k:k}, function(){});
            }

            $(function(){
                window.document.onkeydown = abc;

                function abc(env) {
                    env = (env) ? env : window.event;

                    if (env.keyCode == '87') {
                        go('w');
                    }
                }
            });

            function open_light() {
                go('o');
            }

            function close_light() {
                go('c');
            }
        </script>

        <center><h1>树莓派远程控制</h1><h3>Raspberry Pi Remote Control</h3></center>
    	<center><h3 id="nowtime">--年--月--日 --:--:--</h3></center>
        <div class="panel panel-default">
            <div class="panel-heading"><h3 class="panel-title">终端信息与控制</h3></div>
            <div class="panel-body"><pre>    显示树莓派终端的信息与进行远程控制</pre></div>
            <table class="table">
                <tr>
                    <td>CPU实时温度(刷新频率:1秒)</td>
                    <td><text id="cpu">{{ cpu_temperature }}</text></td>
                </tr>

                <tr>
                    <td>房间灯</td>
                    <td>
                        <button type="submit" onclick="open_light();">开灯</button>
                        <button type="submit" onclick="close_light();">关灯</button>
                    </td>
                </tr>
            </table>
        </div>
        <br/>
        <div class="panel panel-primary">
            <div class="panel-heading"><h3 class="panel-title">CPU、GPU温度曲线</h3></div>
            <div class="panel-body">
                <div class="btn-group">
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">2017<span class="caret"></span></button>
                    <ul class="dropdown-menu" role="menu">
                        <li>
                            <a href="#">2016</a>
                        </li>
                        <li>
                            <a href="#">2015</a>
                        </li>
                    </ul>
                </div>
                <div id="cpu_tem" class="div_left"></div>
                <div id="cpu_usage" class="div_right"></div>
            </div>
        </div>
    </body>
</html>
为了方便,这里js都写在模板页面了。这里主要用到Ajax去定时刷新标签和执行post请求去执行对应操作。曲线数据还没实现,先写死数据看看效果。

3. 编写硬件层操作hardware/board_ctrl.py:

这里对IO口的操作还没实现,只是实现了一个获取CPU温度的接口。在树莓派系统,要对IO口进行操作,需要安装如下这个库:

这个库的使用后面再介绍,现在是搭建监控平台。

4. 主要文件都弄好了,现在启动这个网站:

python index.py

开发板的ip是192.168.31.50,默认启动的端口是8000 ,浏览器打开这个页面:

可以看到,CPU的温度在实时变化,达到我们的要求,后面如果要监控更多参数,实现如CPU持续过高就邮件通知就可以了,现在只是一个我业余做的一个智能家居系统雏形,下面的曲线和面板都是死数据,后面再慢慢修改实现真正的监控了,这里只搭建好一个基础框架。


我们点击“开灯”按钮,可以看到后台也确实调用了对应代码,实际的硬件还在画板,这里先不弄了,弄好再继续吧~:

展开阅读全文

没有更多推荐了,返回首页