You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
578 lines
17 KiB
578 lines
17 KiB
<%@ page language="java" contentType="text/html; charset=UTF-8"
|
|
pageEncoding="UTF-8"%>
|
|
<%@ page import="com.lp.cfg.ProConfig"%>
|
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
|
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<%@ include file="/WEB-INF/oss/iot/common/variable.jsp"%>
|
|
<%@ include file="/WEB-INF/oss/iot/common/variable_js.jsp"%>
|
|
<%@ include file="/WEB-INF/oss/iot/common/resource_lib.jsp"%>
|
|
<script type="text/javascript" src="<%=basePath%>/lib/mqtt/mqtt.min.js"></script>
|
|
|
|
<link type="text/css" href="<%=basePath%>/css/oss/iot/monitor_device.css?<%=v%>" rel="stylesheet"/>
|
|
<style type="text/css">
|
|
.red-span{
|
|
background: #f44336;
|
|
padding: 2px 6px;
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
.span-dis{
|
|
display: inline-block;width: 300px;text-align: left;margin-right: 100px;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;overflow: hidden;
|
|
}
|
|
|
|
.blue-span{
|
|
background: #3499da;
|
|
padding: 3px 6px;
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
}
|
|
.sensorlon{
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
overflow: hidden;
|
|
width: 100%;
|
|
display: block;
|
|
}
|
|
.blue-span{
|
|
background: #3499da;
|
|
padding: 3px 6px;
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.pro-span{
|
|
background: #4caf50;
|
|
padding: 3px 6px;
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.grey-span{
|
|
background: #aaa;
|
|
padding: 3px 6px;
|
|
color: #fff;
|
|
border-radius: 4px;
|
|
opacity: 0.9;
|
|
}
|
|
.time-span{
|
|
color: #999894;
|
|
}
|
|
|
|
.line{
|
|
width: 50%;
|
|
float: left ;
|
|
}
|
|
.sensor_info_container{
|
|
overflow: hidden;
|
|
}
|
|
.sensor-value{
|
|
font-size: 21px;
|
|
}
|
|
.icon-style{
|
|
margin-left: 5px;font-size: 18px;color:#666;cursor: pointer;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div>
|
|
<!-- 下方部位 -->
|
|
<div>
|
|
<!-- 左边栏 -->
|
|
<div class="float-left index_theLeft" style="width:170px;">
|
|
<div class="prolist">
|
|
<span>项目列表</span>
|
|
</div>
|
|
<ul class="dashboard-menu scoll">
|
|
<c:forEach items="${info.data.getData()}" varStatus="status" var="obj">
|
|
<li onclick="changeScene(this)"
|
|
<c:if test="${id !=null }">
|
|
<c:if test="${obj.id ==id}">
|
|
class="active"
|
|
</c:if>
|
|
</c:if>
|
|
<c:if test="${id ==null }">
|
|
<c:if test="${status.index ==0}">
|
|
class="active"
|
|
</c:if>
|
|
</c:if>
|
|
sid="${obj.id}">
|
|
<span class="icon-stack-overflow"></span> ${obj.name }
|
|
</li>
|
|
</c:forEach>
|
|
</ul>
|
|
</div>
|
|
<div class="mapContainer" >
|
|
<div class="app-container">
|
|
<div style="padding: 6px 8px 6px 10px;background: #fff;border-left: 1px solid #f2f2f2;">
|
|
<input type="text" style="display: inline;width: 210px;margin-right: 20px;"
|
|
autocomplete="off" placeholder="设备号检索" class="layui-input device_code">
|
|
<button type="button" onclick="searchDevice();" style="line-height: 34px;height:34px;" class="layui-btn layui-btn-normal">检索</button>
|
|
</div>
|
|
<div class="container-layout sceneList-info">
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="template0" class="hide">
|
|
<div class="box join-device-box" >
|
|
<div class="device_container" ><i class="icon-hdd-o"></i>
|
|
<span style="width: 100px;display: inline-block;">{0}</span> <span> {1}</span>
|
|
<span class="float-right pro-span" style="margin-right:20px;cursor: pointer;" onclick="deviceSetting({4})" tag="{4}">设置参数</span>
|
|
<span class="float-right span-dis" style="">设备号:{2}</span>
|
|
</div>
|
|
<div class="sensor_info_container">
|
|
{3}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 连续型 -->
|
|
<div id="template1" class="hide">
|
|
<div class="line" >
|
|
<div class="x6">
|
|
<div>
|
|
<div style="float: left;margin-top: 7.5px;">
|
|
<img class="sensor_img" alt="image" src="<%=basePath%>/image/oss/iot/{6}.png">
|
|
</div>
|
|
<div style="float: left;margin-top: 9px;">
|
|
<div style="margin: 2px 0 0 0;" class="sensor_name">{0}</div>
|
|
<div style="padding: 2px 0 0px 10px;" class="time-span" >{2}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="x4">
|
|
<span class="sensor-value">{3}</span>
|
|
<span class="icon-edit icon-style {7}" onclick="downparam({4})" ></span>
|
|
</div>
|
|
<div class="x2 text-align-center">
|
|
<a href="<%=basePath%>/service/iot/sensors_detail?id={4}&sid={5}">详情 <span class="icon-angle-double-right"></span> </a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 开关 -->
|
|
<div id="template2" class="hide">
|
|
<div class="line" >
|
|
<div class="x6">
|
|
<div>
|
|
<div style="float: left;margin-top: 7.5px;">
|
|
<img class="sensor_img" alt="image" src="<%=basePath%>/image/oss/iot/{8}.png">
|
|
</div>
|
|
<div style="float: left;margin-top: 9px;">
|
|
<div style="margin: 2px 0 0 0;" class="sensor_name">{0}</div>
|
|
<div style="padding: 2px 0 0px 10px;" class="time-span" >{2}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="x4">
|
|
<img style="cursor: pointer;" tag="{7}" onclick="switchSensor(this,{4},{5})" {3} >
|
|
<span> </span>
|
|
<span class="icon-edit icon-style {9}" onclick="downparam({4})" ></span>
|
|
</div>
|
|
<div class="x2 text-align-center">
|
|
<a href="<%=basePath%>/service/iot/sensors_detail?id={4}&sid={6}">详情 <span class="icon-angle-double-right"></span> </a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 点动控制 -->
|
|
<div id="template7" class="hide">
|
|
<div class="line" >
|
|
<div class="x6">
|
|
<div>
|
|
<div style="float: left;margin-top: 7.5px;">
|
|
<img class="sensor_img" alt="image" src="<%=basePath%>/image/oss/iot/{8}.png">
|
|
</div>
|
|
<div style="float: left;margin-top: 9px;">
|
|
<div style="margin: 2px 0 0 0;" class="sensor_name">{0}</div>
|
|
<div style="padding: 2px 0 0px 10px;" class="time-span" >{2}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="x4">
|
|
<img style="margin:10px 0 0 33px;cursor: pointer;width:35px;" tag="{7}" onclick="switchSensordian(this,{4},{5})" {3} >
|
|
</div>
|
|
<div class="x2 text-align-center">
|
|
<a href="<%=basePath%>/service/iot/sensors_detail?id={4}&sid={6}">详情 <span class="icon-angle-double-right"></span> </a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 离散 -->
|
|
<div id="template3" class="hide">
|
|
<div class="line" >
|
|
<div class="x6">
|
|
<div>
|
|
<div style="float: left;margin-top: 7.5px;">
|
|
<img class="sensor_img" alt="image" src="<%=basePath%>/image/oss/iot/{6}.png">
|
|
</div>
|
|
<div style="float: left;margin-top: 9px;">
|
|
<div style="margin: 2px 0 0 0;" class="sensor_name">{0}</div>
|
|
<div style="padding: 2px 0 0px 10px;" class="time-span" >{2}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="x4">
|
|
<span class="sensor-value">{3}</span>
|
|
<span class="icon-edit icon-style {7}" onclick="downparam({4})" ></span>
|
|
</div>
|
|
<div class="x2 text-align-center">
|
|
<a href="<%=basePath%>/service/iot/sensors_detail?id={4}&sid={5}">详情 <span class="icon-angle-double-right"></span> </a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 定位型 -->
|
|
<div id="template6" class="hide">
|
|
<div class="line" >
|
|
<div class="x6">
|
|
<div>
|
|
<div style="float: left;margin-top: 7.5px;">
|
|
<img class="sensor_img" alt="image" src="<%=basePath%>/image/oss/iot/{6}.png">
|
|
</div>
|
|
<div style="float: left;margin-top: 9px;">
|
|
<div style="margin: 2px 0 0 0;" class="sensor_name">{0}</div>
|
|
<div style="padding: 2px 0 0px 10px;" class="time-span" >{2}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="x4">
|
|
<span style="font-size: 18px;" class="sensor-value sensorlon">{3}</span>
|
|
</div>
|
|
<div class="x2 text-align-center">
|
|
<a href="<%=basePath%>/service/iot/sensors_detail?id={4}&sid={5}">详情 <span class="icon-angle-double-right"></span> </a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
<script type="text/javascript">
|
|
|
|
/**
|
|
* 数据下发
|
|
*/
|
|
function downparam(id){
|
|
layer.prompt({title: '数据下发', formType: 3}, function(val, index){
|
|
commonAjax('PUT',localUrl+'/sensor/param/down.json', {sdata : val ,id:id },function(data){
|
|
if(isOK(data)){
|
|
tip("写指令下发成功,请稍后...");
|
|
}else{
|
|
tip(data.statusMsg) ;
|
|
}
|
|
});
|
|
layer.close(index);
|
|
});
|
|
}
|
|
|
|
// 切换项目
|
|
function changeScene(obj){
|
|
var tempT = "/scene/update/"+ $(".dashboard-menu li.active").attr("sid") ;
|
|
client.unsubscribe(tempT );
|
|
|
|
if(! $(obj).hasClass("active") ){
|
|
$(".device_code").val('');
|
|
device_code = '' ;
|
|
}
|
|
$(".dashboard-menu li").removeClass("active");
|
|
$(obj).addClass("active");
|
|
|
|
reflash( $(".dashboard-menu li.active").attr("sid"));
|
|
|
|
// 关注其他项目
|
|
tempT = "/scene/update/"+ $(".dashboard-menu li.active").attr("sid") ;
|
|
client.subscribe(tempT );
|
|
// 发送订阅
|
|
client.publish('/sys/update/scene' , $(".dashboard-menu li.active").attr("sid") );
|
|
}
|
|
/**
|
|
* 控制
|
|
*/
|
|
function switchSensor(obj,id,value){
|
|
var obj = $(obj) ;
|
|
var requestData = '',src='' ;
|
|
if( obj.attr("src").indexOf("loading") >-1 ){
|
|
return ;
|
|
}
|
|
var measure_type_value = obj.attr("tag");
|
|
if(convertControl(value,measure_type_value,'打开')){
|
|
requestData = convertControl(value,measure_type_value,'打开');
|
|
src = "<%=basePath%>/image/oss/iot/off_loading.gif";
|
|
}else if(convertControl(value,measure_type_value,'关闭')){
|
|
requestData =convertControl(value,measure_type_value,'关闭') ;
|
|
src = "<%=basePath%>/image/oss/iot/on_loading.gif" ;
|
|
}else if(convertControl(value,measure_type_value,'开门成功')){
|
|
requestData = convertControl(value,measure_type_value,'开门成功');
|
|
src = "<%=basePath%>/image/oss/iot/off_loading.gif";
|
|
}else if(convertControl(value,measure_type_value,'正常')){
|
|
requestData = convertControl(value,measure_type_value,'正常');
|
|
src = "<%=basePath%>/image/oss/iot/on_loading.gif";
|
|
}
|
|
obj.attr("src",src);
|
|
commonAjax('PUT',localUrl+"/sensor/control/realtime/update", {id:id,request_sdata:requestData },function(data){
|
|
if(isOK(data)){
|
|
obj.attr("src",src);
|
|
}else{
|
|
tip(data.statusMsg);
|
|
}
|
|
|
|
// 确保更新时间在3s前
|
|
lastTime = new Date().getTime() - 3*1000 ;
|
|
});
|
|
}
|
|
|
|
function switchSensordian(obj,id,value){
|
|
commonAjax('PUT',localUrl+"/sensor/control/realtime/update", {id:id,request_sdata: value },function(data){
|
|
if(isOK(data)){
|
|
tip("下发成功");
|
|
}else{
|
|
tip(data.statusMsg);
|
|
}
|
|
});
|
|
}
|
|
|
|
var device_code ='' ;
|
|
|
|
$(function(){
|
|
|
|
reflash( $(".dashboard-menu li.active").attr("sid"));
|
|
|
|
setInterval(function(){
|
|
reflash( $(".dashboard-menu li.active").attr("sid"));
|
|
},30 * 1000);
|
|
|
|
})
|
|
|
|
function searchDevice(){
|
|
if( validater.empty( $(".device_code").val() ) ){
|
|
tip("请输入的设备号");
|
|
return ;
|
|
}else{
|
|
device_code = $(".device_code").val() ;
|
|
reflash( $(".dashboard-menu li.active").attr("sid"));
|
|
}
|
|
}
|
|
|
|
// 刷新传感器数据
|
|
function reflash(sid){
|
|
if( validater.empty(sid) ){
|
|
return ;
|
|
}
|
|
searchDeviceInfo( {scene_id:sid, node_data_type:0 , device_code:device_code } );
|
|
}
|
|
|
|
function searchDeviceInfo(dataParam){
|
|
postAjax(localUrl+"/page/node/sensor/list.json", dataParam ,function(data){
|
|
$(".sceneList-info").empty();
|
|
if(isOK(data)){
|
|
var dataObj = data.data ;
|
|
for(var i=0; i <dataObj.length;i++){
|
|
$(".sceneList-info").append($("#template0").html().format( dataObj[i].name ,
|
|
nodeStatusInfo(dataObj[i].iot_node_status ,dataObj[i].data.iot_node_status) ,
|
|
dataObj[i].device_code, getSensorListHtml( dataObj[i].iotSensorList, dataParam.scene_id ,dataObj[i].iot_node_status ) ,dataObj[i].id ) );
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function getSensorListHtml(dataT,sid , node_status){
|
|
var str = '' ;
|
|
var src1 = 'src="<%=basePath%>/image/oss/iot/on.png"';
|
|
var src2 = 'src="<%=basePath%>/image/oss/iot/off.png"';
|
|
for(var i=0;i<dataT.length;i++){
|
|
// 传感器logo数据
|
|
var sensorLogo = dataT[i].measure_unit_type ;
|
|
if( dataT[i].iot_sensor_type == 25 ){
|
|
|
|
str+=$("#template1").html().format(disvalue(dataT[i].name,9),
|
|
dataT[i].data.iot_sensor_status,
|
|
timeStamp2String(dataT[i].mtime,'yyyy/MM/dd hh:mm:ss'),
|
|
getDsv( gdv(dataT[i].sdata,0),node_status) +" "+dataT[i].data.measure_unit_type,dataT[i].id,sid ,sensorLogo , getDisInfo(dataT[i]) );
|
|
}else if( dataT[i].iot_sensor_type == 26 ){
|
|
|
|
if( dataT[i].measure_unit_type == 250 ){
|
|
str+=$("#template3").html().format(disvalue(dataT[i].name,9),
|
|
dataT[i].data.iot_sensor_status,
|
|
timeStamp2String(dataT[i].mtime,'yyyy/MM/dd hh:mm:ss'),
|
|
getDsv( getWindUint(gdv(dataT[i].sdata,0)) ,node_status) ,dataT[i].id,sid ,sensorLogo );
|
|
}else{
|
|
str+=$("#template3").html().format(disvalue(dataT[i].name,9),
|
|
dataT[i].data.iot_sensor_status,
|
|
timeStamp2String(dataT[i].mtime,'yyyy/MM/dd hh:mm:ss'),
|
|
getDsv( gdv(dataT[i].data.measure_unit_type,'-'),node_status) ,dataT[i].id,sid ,sensorLogo , getDisInfo(dataT[i]));
|
|
}
|
|
}else if( dataT[i].iot_sensor_type == 27 ){
|
|
str+=$("#template2").html().format(disvalue(dataT[i].name,9),
|
|
dataT[i].data.iot_sensor_status,
|
|
timeStamp2String(dataT[i].mtime,'yyyy/MM/dd hh:mm:ss'),
|
|
tom( getSwitch(dataT[i].sdata,node_status) == 1.0 ,src1,src2 ),
|
|
dataT[i].id,dataT[i].sdata,sid,dataT[i].data.measure_unit_type_value,sensorLogo, getDisInfo(dataT[i]) );
|
|
}else if(dataT[i].iot_sensor_type == 90 ){
|
|
// gps定位数据
|
|
|
|
str+=$("#template6").html().format(disvalue(dataT[i].name,9),
|
|
dataT[i].data.iot_sensor_status,
|
|
timeStamp2String(dataT[i].mtime,'yyyy/MM/dd hh:mm:ss'),
|
|
getDsv( gdv(dataT[i].str_sdata,'-'), node_status) ,dataT[i].id,sid, sensorLogo );
|
|
}else if(dataT[i].iot_sensor_type == 190){
|
|
|
|
str+=$("#template7").html().format(disvalue(dataT[i].name,9),
|
|
dataT[i].data.iot_sensor_status,
|
|
timeStamp2String(dataT[i].mtime,'yyyy/MM/dd hh:mm:ss'),
|
|
'src="<%=basePath%>/image/oss/iot/switch.png"',
|
|
dataT[i].id,dataT[i].param_type,sid,dataT[i].data.measure_unit_type_value,sensorLogo );
|
|
}
|
|
}
|
|
if( validater.empty(str) ){
|
|
str = "<p style='color:#aaa;text-align:center;'>暂无设备传感点</p>"
|
|
}
|
|
return str ;
|
|
}
|
|
|
|
function getDisInfo(data){
|
|
var t =eval('('+ gdv( data.infos,'{}') +')');
|
|
if( t!= null && t.readType == 1){
|
|
return "" ;
|
|
}else{
|
|
return "hide" ;
|
|
}
|
|
}
|
|
|
|
function getSwitch(value, status){
|
|
if( status != 16 ){
|
|
return 0 ;
|
|
}else{
|
|
return value ;
|
|
}
|
|
}
|
|
|
|
function getDsv(value ,status ){
|
|
if( status != 16 ){
|
|
return "-" ;
|
|
}else{
|
|
return value ;
|
|
}
|
|
}
|
|
|
|
|
|
function getMoreSwitch(data,dataType,sensor_id){
|
|
var html = '' ;
|
|
var str = dataType.split(",");
|
|
for(var o =0;o<str.length; o++){
|
|
var tmp = str[o].split(":");
|
|
if(tmp[0] == data ){
|
|
html += '<button type="button" onclick="change(this,'+tmp[0]+','+ sensor_id +')" class="button border-sub active">'+tmp[1]+'</button>' ;
|
|
}else{
|
|
html += '<button type="button" onclick="change(this,'+tmp[0]+','+sensor_id+')" class="button border-sub ">'+tmp[1]+'</button>' ;
|
|
}
|
|
}
|
|
var butn =
|
|
'<div class="button-group button-group-small" style="margin-top:15px;" >'+
|
|
html+
|
|
'</div>' ;
|
|
return butn ;
|
|
}
|
|
|
|
function nodeStatusInfo(code,value){
|
|
if(code == 16){
|
|
return "<span class='blue-span'>"+value+"</span>" ;
|
|
}else{
|
|
return "<span class='red-span'>"+value+"</span>" ;
|
|
}
|
|
}
|
|
|
|
function change(obj,data,sensor_id){
|
|
layer.load(2);
|
|
setTimeout(function() {
|
|
layer.closeAll();
|
|
commonAjax('PUT',localUrl+"/sensor/control/realtime/update", {id: sensor_id ,request_sdata: data },function(data){
|
|
if(isOK(data)){
|
|
|
|
}else{
|
|
tip(data.statusMsg);
|
|
}
|
|
});
|
|
}, 500);
|
|
}
|
|
|
|
function getWindUint(sdata){
|
|
if( sdata == 0 ){
|
|
return "北风 " ;
|
|
}else if( sdata >0 && sdata <90 ){
|
|
return "东北 ";
|
|
}else if( sdata == 90 ){
|
|
return "东 ";
|
|
}else if( sdata >90 && sdata <180 ){
|
|
return "东南 ";
|
|
}else if( sdata== 180 ){
|
|
return "南 ";
|
|
}else if( sdata >180 && sdata <270 ){
|
|
return "西南 ";
|
|
}else if( sdata ==270 ){
|
|
return "西 ";
|
|
}else if( sdata >270 ){
|
|
return "西北 ";
|
|
}
|
|
}
|
|
|
|
function deviceSetting(node_id){
|
|
layer.open({
|
|
type: 2,
|
|
title: '设备参数配置',
|
|
area: ['730px', '460px'],
|
|
shade: 0.1,
|
|
closeBtn: 1,
|
|
shadeClose: true,
|
|
content: localUrl+"/iot/device_setting?id="+node_id
|
|
});
|
|
}
|
|
|
|
// 上次刷新时间
|
|
var lastTime = new Date().getTime() ;
|
|
|
|
//客户端
|
|
var client ;
|
|
function mqttInit(){
|
|
// 连接选项
|
|
const options = {
|
|
connectTimeout: 4000, // 超时时间
|
|
// 认证信息
|
|
clientId: 'brower_' + parseInt(Math.random()/31.1*10000000000),
|
|
username: '<%=ProConfig.MQTT.USERNAME%>',
|
|
password: '<%=ProConfig.MQTT.PASSWORD%>',
|
|
}
|
|
client = mqtt.connect('ws://'+document.domain+':8083/mqtt', options) ;
|
|
client.on('reconnect', function(error) {
|
|
reflash( $(".dashboard-menu li.active").attr("sid"));
|
|
})
|
|
client.on('error', function(error) {
|
|
console.log('连接失败:', error)
|
|
})
|
|
client.on('message', function(topic, message,s) {
|
|
if( message.toString() == '1' ){
|
|
if( lastTime + 3*1000 < new Date().getTime() ){
|
|
reflash( $(".dashboard-menu li.active").attr("sid"));
|
|
lastTime = new Date().getTime() ;
|
|
}
|
|
}
|
|
})
|
|
}
|
|
$(function(){
|
|
mqttInit();
|
|
|
|
$(".index_theLeft ul").height( $(window).height() - 50);
|
|
|
|
setTimeout( function() {
|
|
var tempT = "/scene/update/"+ $(".dashboard-menu li.active").attr("sid") ;
|
|
client.subscribe(tempT );
|
|
|
|
client.publish('/sys/update/scene' , $(".dashboard-menu li.active").attr("sid") );
|
|
}, 1000);
|
|
|
|
})
|
|
|
|
</script>
|
|
</html>
|