前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python开发物联网数据分析平台---web框架

Python开发物联网数据分析平台---web框架

原创
作者头像
MiaoGIS
修改2020-03-17 14:17:58
3.1K0
修改2020-03-17 14:17:58
举报
文章被收录于专栏:Python in AI-IOTPython in AI-IOT

前端使用Bootstrap主题框架AdminLTE,后台使用python语言的tornado作为web框架。利用tornado的模板作为主要的动态页面生成方式,以及巧妙使用模板将json数据渲染到页面hidden元素的值,然后在js中直接用eval函数计算隐藏域的值来生成图表JavaScript插件所需的json数据来生成页面中相应的可视化图表。

对于模板内容重复的问题,tornado 提供了模板继承的支持。这个机制和 Python 类 继承非常类似:我们可以定义一个父模板,一般会称之为基模板(base template)。基模板中包含完整的 HTML 结构和导航栏、页首、页脚都通用部分。 在子模板里,我们可以使用 extends 标签来声明继承自某个基模板。 基模板中需要在实际的子模板中追加或重写的部分则可以定义成块(block)。块使 用 block 标签创建, {% block 块名称 %} 作为开始标记, {% end %} 作为结束标记。通过在子模板里定义一个同样名 称的块,你可以向基模板的对应块位置追加或重写内容。

模板母页base.html代码如下:

代码语言:html
复制
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>面向数据</title>
    <!-- Tell the browser to be responsive to screen width -->
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Font Awesome -->
    <link rel="stylesheet" href="plugins/fontawesome-free/css/all.min.css">
    <!-- Ionicons -->
    <link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <!-- Tempusdominus Bbootstrap 4 -->
    <link rel="stylesheet" href="plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">

    <!-- Select2 -->
    <link rel="stylesheet" href="../../plugins/select2/css/select2.min.css">
    <link rel="stylesheet" href="../../plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css">

    <!-- iCheck -->
    <link rel="stylesheet" href="plugins/icheck-bootstrap/icheck-bootstrap.min.css">
    <!-- JQVMap -->
    <link rel="stylesheet" href="plugins/jqvmap/jqvmap.min.css">
    <!-- Theme style -->
    <link rel="stylesheet" href="dist/css/adminlte.min.css">
    <!-- overlayScrollbars -->
    <link rel="stylesheet" href="plugins/overlayScrollbars/css/OverlayScrollbars.min.css">
    <!-- Daterange picker -->
    <link rel="stylesheet" href="plugins/daterangepicker/daterangepicker.css">
    <!-- summernote -->
    <link rel="stylesheet" href="plugins/summernote/summernote-bs4.css">



    <!-- Google Font: Source Sans Pro -->
    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">

    {% block css %}{% end %}
</head>

<body class="hold-transition sidebar-mini layout-fixed">
    <div class="wrapper">

        <!-- Navbar -->
        <nav class="main-header navbar navbar-expand navbar-white navbar-light">
            <!-- Left navbar links -->
            <ul class="navbar-nav">
                <li class="nav-item">
                    <a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
                </li>
                <li class="nav-item d-none d-sm-inline-block">
                    <a href="./dashboard"  target="_blank" class="nav-link">首页</a>
                </li>
                <li class="nav-item d-none d-sm-inline-block">
                    <a href="#" class="nav-link">反馈</a>
                </li>
            </ul>

            <!-- SEARCH FORM -->
            <form class="form-inline ml-3">


                <div class="row" style="width: 450px;">
                    <div class="col-3">
                        <label>查询</label>
                    </div>
                    <div class="col-7">


                        <select class="form-control select2" multiple="multiple" style="width: 100%;" id="selectNames">

                            {%for i in range(len(dfNames)) %}
                            {%set row=dfNames.iloc[i] %}
                            <option {% if str(row['DevID']) in ids  %} selected {% else %}{% end %} value="{{row['DevID']}}">{{row['DevID']}}</option>

                            {% end %}

                        </select>
                    </div>
                    <div class="col-2">
                        <button class="btn btn-navbar" type="button" id="btnSearch">
                            <i class="fas fa-search"></i>
                        </button>
                    </div>
                </div>










                <!-- <div class="input-group input-group-sm">
                    <input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">
                    <div class="input-group-append">
                        <button class="btn btn-navbar" type="submit">
                            <i class="fas fa-search"></i>
                        </button>
                    </div>
                </div> -->
            </form>

            <!-- Right navbar links -->
<!--
            <ul class="navbar-nav ml-auto">
                 
                <li class="nav-item dropdown">
                    <a class="nav-link" data-toggle="dropdown" href="#">
                        <i class="far fa-comments"></i>
                        <span class="badge badge-danger navbar-badge">3</span>
                    </a>
                    <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
                        <a href="#" class="dropdown-item">
                            
                            <div class="media">
                                <img src="dist/img/user1-128x128.jpg" alt="User Avatar" class="img-size-50 mr-3 img-circle">
                                <div class="media-body">
                                    <h3 class="dropdown-item-title">
                                        刘
                                        <span class="float-right text-sm text-danger"><i class="fas fa-star"></i></span>
                                    </h3>
                                    <p class="text-sm">一条数据异常...</p>
                                    <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
                                </div>
                            </div>
                             
                        </a>
                        <div class="dropdown-divider"></div>
                        <a href="#" class="dropdown-item">
                             
                            <div class="media">
                                <img src="dist/img/user8-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
                                <div class="media-body">
                                    <h3 class="dropdown-item-title">
                                        张
                                        <span class="float-right text-sm text-muted"><i class="fas fa-star"></i></span>
                                    </h3>
                                    <p class="text-sm">XXX小区报警</p>
                                    <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
                                </div>
                            </div>
                             
                        </a>
                        <div class="dropdown-divider"></div>
                        <a href="#" class="dropdown-item">
                             
                            <div class="media">
                                <img src="dist/img/user3-128x128.jpg" alt="User Avatar" class="img-size-50 img-circle mr-3">
                                <div class="media-body">
                                    <h3 class="dropdown-item-title">
                                        马
                                        <span class="float-right text-sm text-warning"><i class="fas fa-star"></i></span>
                                    </h3>
                                    <p class="text-sm">数据库查询延迟</p>
                                    <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> 4 Hours Ago</p>
                                </div>
                            </div>
                           
                        </a>
                        <div class="dropdown-divider"></div>
                        <a href="#" class="dropdown-item dropdown-footer">所有信息</a>
                    </div>
                </li>
                
                <li class="nav-item dropdown">
                    <a class="nav-link" data-toggle="dropdown" href="#">
                        <i class="far fa-bell"></i>
                        <span class="badge badge-warning navbar-badge">15</span>
                    </a>
                    <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
                        <span class="dropdown-item dropdown-header">15 Notifications</span>
                        <div class="dropdown-divider"></div>
                        <a href="#" class="dropdown-item">
                            <i class="fas fa-envelope mr-2"></i> 4 new messages
                            <span class="float-right text-muted text-sm">3 mins</span>
                        </a>
                        <div class="dropdown-divider"></div>
                        <a href="#" class="dropdown-item">
                            <i class="fas fa-users mr-2"></i> 8 friend requests
                            <span class="float-right text-muted text-sm">12 hours</span>
                        </a>
                        <div class="dropdown-divider"></div>
                        <a href="#" class="dropdown-item">
                            <i class="fas fa-file mr-2"></i> 3 new reports
                            <span class="float-right text-muted text-sm">2 days</span>
                        </a>
                        <div class="dropdown-divider"></div>
                        <a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>
                    </div>
                </li>
                <li class="nav-item">
                    <a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#">
                        <i class="fas fa-th-large"></i>
                    </a>
                </li>
            </ul>
-->
        </nav>
        <!-- /.navbar -->

        <!-- Main Sidebar Container -->
        <aside class="main-sidebar sidebar-dark-primary elevation-4">
            <!-- Brand Logo -->
            <a href="index3.html" class="brand-link">
                <img src="dist/img/AdminLTELogo.png" alt="AdminLTE Logo" class="brand-image img-circle elevation-3" style="opacity: .8">
                <span class="brand-text font-weight-light">物联网数据分析</span>
            </a>

            <!-- Sidebar -->
            <div class="sidebar">
                <!-- Sidebar user panel (optional) -->
                <div class="user-panel mt-3 pb-3 mb-3 d-flex">
                    <div class="image">
                        <img src="dist/img/user2-160x160.jpg" class="img-circle elevation-2" alt="User Image">
                    </div>
                    <div class="info">
                        <a href="#" class="d-block">苗</a>
                    </div>
                </div>

                <!-- Sidebar Menu -->
                <nav class="mt-2">
                    <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
                        <!-- Add icons to the links using the .nav-icon class
               with font-awesome or any other icon font library -->
                        <li class="nav-item has-treeview menu-open" data-menu="overview">
                            <a href="#" class="nav-link active">
                                <i class="nav-icon fas fa-tachometer-alt"></i>
                                <p>
                                    总览
                                    <i class="right fas fa-angle-left"></i>
                                </p>
                            </a>
                            <ul class="nav nav-treeview">
                                <li class="nav-item"  data-menu="dashboard">
                                    <a href="./dashboard" class="nav-link active">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>看板</p>
                                    </a>
                                </li>
                                <li class="nav-item"  data-menu="ids">
                                    <a href="./ids" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>设备</p>
                                    </a>
                                </li>
                                <li class="nav-item"  data-menu="map">
                                    <a href="#" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>地图</p>
                                    </a>
                                </li>
                            </ul>
                        </li>

                        <li class="nav-item has-treeview"  data-menu="data">
                            <a href="#" class="nav-link">
                                <i class="nav-icon fas fa-table"></i>
                                <p>
                                    数据
                                    <i class="right fas fa-angle-left"></i>
                                </p>
                            </a>
                            <ul class="nav nav-treeview">
                                <li class="nav-item"  data-menu="minutes15">
                                    <a href="./minutes15" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>最近15分钟</p>
                                    </a>
                                </li>
                                <li class="nav-item"  data-menu="hour">
                                    <a href="./hour" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>最近一小时</p>
                                    </a>
                                </li>
                                <li class="nav-item"  data-menu="day">

                                    <a href="./day" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>最近一天</p>
                                    </a>
                                </li>
                               <li class="nav-item"  data-menu="year">

                                    <a href="./year?ids=1" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>最近一年(单设备)</p>
                                    </a>
                                </li>


                            </ul>
                        </li>
                        <li class="nav-item has-treeview"  data-menu="status">
                            <a href="#" class="nav-link">
                                <i class="nav-icon fas fa-chart-pie"></i>
                                <p>
                                    状态监测
                                    <i class="right fas fa-angle-left"></i>
                                </p>
                            </a>
                            <ul class="nav nav-treeview">
                                <li class="nav-item"  data-menu="id">
                                    <a href="./id?ids=1" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>设备状态</p>
                                    </a>
                                </li>
                                <li class="nav-item"  data-menu="error">
                                    <a href="./error" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>报警和异常</p>
                                    </a>
                                </li>
                                <li class="nav-item"  data-menu="offline">
                                    <a href="./offline" class="nav-link">
                                        <i class="far fa-circle nav-icon"></i>
                                        <p>掉线记录</p>
                                    </a>
                                </li>

                            </ul>
                        </li>








                    </ul>
                </nav>
                <!-- /.sidebar-menu -->
            </div>
            <!-- /.sidebar -->
        </aside>

        <!-- Content Wrapper. Contains page content -->
        {% block body %}子页面内容{% end %}
        <!-- /.content-wrapper -->
        <footer class="main-footer">
            <strong>Copyright &copy; 2014-2019 <a href="http://adminlte.io">AdminLTE.io</a>.</strong>
            All rights reserved.
            <div class="float-right d-none d-sm-inline-block">
                <b>Version</b> 3.0.0-rc.1
            </div>
        </footer>

        <!-- Control Sidebar -->
        <aside class="control-sidebar control-sidebar-dark">
            <!-- Control sidebar content goes here -->
        </aside>
        <!-- /.control-sidebar -->
    </div>
    <!-- ./wrapper -->




    <!-- jQuery -->
    <script src="plugins/jquery/jquery.min.js"></script>
    <!-- jQuery UI 1.11.4 -->
    <script src="plugins/jquery-ui/jquery-ui.min.js"></script>
    <!-- Resolve conflict in jQuery UI tooltip with Bootstrap tooltip -->
    <script>
        $.widget.bridge('uibutton', $.ui.button)

    </script>
    <!-- Bootstrap 4 -->
    <script src="plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
    <!-- Select2 -->
    <script src="../../plugins/select2/js/select2.full.min.js"></script>
    <!-- ChartJS -->
    <script src="plugins/chart.js/Chart.min.js"></script>
    <!-- Sparkline -->
    <script src="plugins/sparklines/sparkline.js"></script>
    <!-- JQVMap -->
    <script src="plugins/jqvmap/jquery.vmap.min.js"></script>
    <script src="plugins/jqvmap/maps/jquery.vmap.world.js"></script>
    <!-- jQuery Knob Chart -->
    <script src="plugins/jquery-knob/jquery.knob.min.js"></script>
    <!-- daterangepicker -->
    <script src="plugins/moment/moment.min.js"></script>
    <script src="plugins/daterangepicker/daterangepicker.js"></script>
    <!-- Tempusdominus Bootstrap 4 -->
    <script src="plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>
    <!-- Summernote -->
    <script src="plugins/summernote/summernote-bs4.min.js"></script>
    <!-- overlayScrollbars -->
    <script src="plugins/overlayScrollbars/js/jquery.overlayScrollbars.min.js"></script>
    <!-- AdminLTE App -->
    <script src="dist/js/adminlte.js"></script>
    <!-- AdminLTE dashboard demo (This is only for demo purposes) -->

    <!-- AdminLTE for demo purposes -->
    <script src="dist/js/demo.js"></script>
    <script src="static/js/base.js"></script>

    {% block script %}{% end %}
</body>

</html>

模板母页对应的js代码,主要实现搜索框点击搜索按钮时,页面根据搜索条件跳转url,以及根据当前页面url地址更新菜单栏当前菜单选中的样式。base.js如下:

代码语言:javascript
复制
 $(function () {
     //Initialize Select2 Elements
     $('.select2').select2({
         theme: 'bootstrap4'
     })
     var baseUrl = document.location.pathname;
     $('#btnSearch').click(function () {

         var ids = $('#selectNames').val();

         if (ids.length > 0) {
             document.location = baseUrl + "?ids="+ids.toString();
         } else {
             document.location = baseUrl;
         }

     });
     $('.mt-2>ul>li.has-treeview.nav-item>ul>li>a').removeClass('active');
     var menus=$('.content-wrapper').data('menu').split(' ');
     console.log(menus);
     
     var menu1=$('.nav-item.has-treeview[data-menu='+menus[0]+']');
     menu1.addClass('menu-open');

      menu1.siblings().removeClass('menu-open');
     menu1.find('>a').addClass('active');
     menu1.siblings().find('>a').removeClass('active');
     console.log(menu1);
     var  menu2=menu1.find('ul.nav-treeview>li[data-menu='+menus[1]+']');
     console.log(menu2);
     menu2.find('>a').addClass('active');
      
 })

web框架后台代码server.py代码如下:

代码语言:python
复制
# -*- coding:utf-8 -*-

import tornado.web
import tornado.httpserver
import tornado.ioloop
import queryDF
from tornado.options import define,options
import os
define('port',default=9000,type=int,help="input your port")

class pressureHandler(tornado.web.RequestHandler):
	def get(self):
	    
	    devID=self.get_argument('devID',None)
	    start=self.get_argument('start',None)
	    end=self.get_argument('end',None)
	    
	    if((not devID) or (not start) or (not end)):
		
		    self.write({'result':'{}'})
		    return
	    
	    result=queryDF.getData(int(devID),start,end)
	    self.write({'result':result})

class dashboardHandler(tornado.web.RequestHandler):
        def get(self):
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                info=queryDF.getInfo(ids)
                dfNames=queryDF.getNames()
                self.render('dashboard.html',info=info,dfNames=dfNames,ids=ids)
                

class dayHandler(tornado.web.RequestHandler):
        def get(self):
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                df0=queryDF.getDay(ids)
                dfNames=queryDF.getNames()
                self.render('day.html',df0=df0,dfNames=dfNames,ids=ids)
                
class minutes15Handler(tornado.web.RequestHandler):
        def get(self):
                
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                df0=queryDF.getMinutes15(ids)
                dfNames=queryDF.getNames()
                self.render('minutes15.html',df0=df0,dfNames=dfNames,ids=ids)

class offlineHandler(tornado.web.RequestHandler):
        def get(self):
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                minutes=self.get_argument('minutes',16)
                minutes=int(minutes)
                dfNames=queryDF.getNames()        
                df0=queryDF.getDeltaM(ids,minutes)
                self.render('offline.html',df0=df0,dfNames=dfNames,ids=ids,minutes=minutes)
                
class hourHandler(tornado.web.RequestHandler):
        def get(self):
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                df0=queryDF.getHour(ids)
                dfNames=queryDF.getNames()
                self.render('hour.html',df0=df0,dfNames=dfNames,ids=ids)

class idsHandler(tornado.web.RequestHandler):
        def get(self):
                
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                df0=queryDF.getIds(ids)
                dfNames=queryDF.getNames()
                self.render('ids.html',df0=df0,dfNames=dfNames,ids=ids)
                
class idHandler(tornado.web.RequestHandler):
        def get(self):
                ID=self.get_argument('ids',None)
                print(ID)
                
                info=queryDF.getId(ID)
                dfNames=queryDF.getNames()
                self.render('id.html',info=info,dfNames=dfNames,ids=[ID])



class yearHandler(tornado.web.RequestHandler):
        def get(self):
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                
                df0=queryDF.getYear(ids)
                dfNames=queryDF.getNames()
                self.render('year.html',df0=df0,dfNames=dfNames,ids=ids)


class errorHandler(tornado.web.RequestHandler):
        def get(self):
                ids=self.get_argument('ids',None)
                if ids!=None:
                        ids=ids.split(',')
                else:
                        ids=[]
                 
                info=queryDF.getError(ids)
                dfNames=queryDF.getNames()
                self.render('error.html',info=info,dfNames=dfNames,ids=ids)
            
app=tornado.web.Application(
	handlers=[
                (r'/', tornado.web.RedirectHandler, {"url": "/dashboard?ids=1"}),
                (r'/dashboard',dashboardHandler),
                   
                   (r'/day',dayHandler),
                  (r'/id',idHandler),
                  (r'/ids',idsHandler),
                  (r'/hour',hourHandler),
                  (r'/year',yearHandler),
                  (r'/offline',offlineHandler),
                  (r'/minutes15',minutes15Handler),
                   (r'/error',errorHandler),
                (r'/api/pressure',pressureHandler),
		  (r'/dist/(.*)',tornado.web.StaticFileHandler,{'path':'static/AdminLTE/dist'}),
		  (r'/plugins/(.*)',tornado.web.StaticFileHandler,{'path':'static/AdminLTE/plugins'}),
		],
        template_path=os.path.join(os.path.curdir,'templates'),static_path=os.path.join(os.path.curdir,'static'),cookie_secret='miaojiyue',debug=True
        )
if __name__=='__main__':
    queryDF.loadData()
    tornado.options.parse_command_line()
    httpserver=tornado.httpserver.HTTPServer(app)
    httpserver.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云 BI
腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档