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.
264 lines
11 KiB
264 lines
11 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<meta name="theme-color" content="#2196f3" />
|
|
<link rel="stylesheet" href="lib/framework7/css/framework7.bundle.min.css" />
|
|
<link rel="stylesheet" href="css/framework7-icons.css" />
|
|
<link rel="stylesheet" href="css/app.css" />
|
|
<title>设备</title>
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<div class="statusbar"></div>
|
|
<div class="view view-main view-init" data-url="/">
|
|
<div class="page">
|
|
<div class="navbar">
|
|
<div class="navbar-inner">
|
|
<div class="left">
|
|
<a href="node.html" class="external link back">
|
|
<i class="icon icon-back"></i>
|
|
<span class="if-not-md" style="transform: translate3d(0px, 0px, 0px);">Back</span>
|
|
</a>
|
|
</div>
|
|
<div class="title sliding">{{model.Name}}</div>
|
|
<div class="right">
|
|
<a href="index.html" class="external" data-panel="right">
|
|
<i class="f7-icons">close</i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="page-content">
|
|
<div class="block-title">场景</div>
|
|
<div class="list links-list">
|
|
<ul>
|
|
<li class="item-content" v-for="sence in _.orderBy(model.Sences,['DisplayOrder','Name'])" v-on:click="sendSence(sence.Id)">
|
|
<div class="item-media"><i class="f7-icons">link</i></div>
|
|
<div class="item-inner">
|
|
<div class="item-title">{{sence.Name}}</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="block-title">设备</div>
|
|
<div class="list links-list">
|
|
<ul>
|
|
<li v-for="d in _.orderBy(model.Devices,['DisplayOrder','Name'])" v-on:click="sendSence(sence.Id)">
|
|
<a class="external item-content" :href="'device.html?id='+d.Id">
|
|
<div class="item-media"><i class="f7-icons">link</i></div>
|
|
<div class="item-inner">
|
|
<div class="item-title">{{d.DisplayName||d.Name}}</div>
|
|
<div class="item-after">
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="lib/mobile.detect/mobile-detect.min.js"></script>
|
|
<script src="lib/lodash/lodash.min.js"></script>
|
|
<script src="lib/jquery/jquery.min.js"></script>
|
|
<script src="lib/framework7/js/framework7.bundle.min.js"></script>
|
|
<script src="lib/signalr/signalr.min.js"></script>
|
|
<script src="lib/vue/vue.min.js"></script>
|
|
<script src="lib/dayjs/dayjs.min.js"></script>
|
|
<script src="lib/URI.js/URI.min.js"></script>
|
|
<script src="js/app.js"></script>
|
|
<script>
|
|
function getJsonExt(url) {
|
|
console.log('send:' + url);
|
|
app.dialog.progress();
|
|
$.getJSON(url, function (result) {
|
|
console.log(result);
|
|
app.dialog.close();
|
|
if (result.code === 0) {
|
|
if (result.type === 0) {
|
|
if (result.format === 1) {
|
|
console.log('format/1/base64 jpeg image');
|
|
$('#callback .page-content .block').html('<img class="shot" src="' + result.data + '">');
|
|
}
|
|
else {
|
|
console.log('format/0/json object');
|
|
$('#callback .page-content .block').html(result.data);
|
|
}
|
|
app.popup.open('#callback');
|
|
}
|
|
}
|
|
else {
|
|
app.dialog.alert(result.message, "消息", function () {
|
|
setTimeout(function () { app.dialog.close(); }, 3000);
|
|
});
|
|
}
|
|
}).fail(function () {
|
|
console.log('error');
|
|
app.dialog.close();
|
|
});;
|
|
}
|
|
</script>
|
|
<script>
|
|
var number = URI.parseQuery(location.search).number;
|
|
var id = URI.parseQuery(location.search).id;
|
|
var baseUrl = "http://" + localStorage.getItem('iotServer');
|
|
var wsUrl = baseUrl + '/hub?group=node-' + number;
|
|
var ajaxUrl = baseUrl + "/Home/GetNode/" + id;
|
|
var $$ = Dom7;
|
|
var username = localStorage.getItem("username");
|
|
var server = localStorage.getItem("server");
|
|
var iotPageIndex = 1;
|
|
function init() {
|
|
Framework7.request.json(ajaxUrl, null, function (response) {
|
|
vm.model = response;
|
|
}, null, 'json');
|
|
}
|
|
</script>
|
|
<script>
|
|
const connection = new signalR.HubConnectionBuilder()
|
|
.withUrl(wsUrl)
|
|
.build();
|
|
function connect() {
|
|
if (connection && connection.connection.connectionState === 1) {
|
|
console.log('has connected');
|
|
}
|
|
else {
|
|
console.log('start connect to server:' + Date());
|
|
connection.start().then(function () {
|
|
console.log('signalR>start');
|
|
}).catch(function (err) {
|
|
console.error(err.toString());
|
|
setTimeout(connect, 10 * 1000);
|
|
});
|
|
}
|
|
}
|
|
connection.on("UpdateNode", (message) => {
|
|
var node = JSON.parse(message);
|
|
var oldNode = _.chain(vm.model).filter(o => o.Number === node.Number).first().value();
|
|
oldNode.Name = node.Name;
|
|
console.log('update:' + node.Name);
|
|
});
|
|
connection.on("UpdateDevice", (message) => {
|
|
var device = JSON.parse(message);
|
|
device.Data = null;
|
|
device.Apis = null;
|
|
var update = false;
|
|
var node = _.chain(vm.model).filter(o => o.Number === device.Node.Number).first().value();
|
|
for (var i = 0; i < node.Devices.length; i++) {
|
|
if (node.Devices[i].Number == device.Number) {
|
|
update = true;
|
|
break;
|
|
}
|
|
}
|
|
if (update) {
|
|
node.Devices.splice(i, 1, device);
|
|
}
|
|
else {
|
|
node.Devices.push(device);
|
|
}
|
|
console.log('update:' + device.DisplayName);
|
|
});
|
|
connection.on("DeleteDevice", (message) => {
|
|
var number = message;
|
|
for (var i = 0; i < vm.model.length; i++) {
|
|
var node = vm.model[i];
|
|
for (var j = 0; j < node.Devices.length; j++) {
|
|
if (node.Devices[j].Number == number) {
|
|
node.Devices.splice(j, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
console.log('delete:' + number);
|
|
});
|
|
connection.onclose(function () {
|
|
setTimeout(connect, 10 * 1000);
|
|
});
|
|
</script>
|
|
<script>
|
|
var app;
|
|
var vm = new Vue({
|
|
el: '#app',
|
|
data: {
|
|
model: {
|
|
Name: '',
|
|
Sences: [],
|
|
Devices: []
|
|
}
|
|
},
|
|
mounted: function () {
|
|
console.log('vue>mounted');
|
|
|
|
var os = new MobileDetect(navigator.userAgent).os();
|
|
var theme = os == "AndroidOS" ? "md" : "ios";
|
|
|
|
if (document.location.search.indexOf('theme=') >= 0) {
|
|
theme = document.location.search.split('theme=')[1].split('&')[0];
|
|
}
|
|
app = new Framework7({
|
|
root: '#app',
|
|
theme: theme,
|
|
routes: [
|
|
{
|
|
path: '(.*)',
|
|
async: function (routeTo, routeFrom, resolve, reject) {
|
|
resolve({ url: routeTo.url });
|
|
}
|
|
}
|
|
],
|
|
on: {
|
|
pageInit: function (page) {
|
|
console.log('f7>page init');
|
|
|
|
}
|
|
}
|
|
});
|
|
init();
|
|
connect();
|
|
},
|
|
methods: {
|
|
sendSence: function (id) {
|
|
var url = baseUrl + '/Command/Sence/?node=' + this.model.Number + '&id=' + id;
|
|
getJsonExt(url);
|
|
},
|
|
getDeviceDataValue: function (device, dataName) {
|
|
if (device != null) {
|
|
|
|
var data = _.first(_.filter(device.Data, function (o) { return o.Name === dataName }));
|
|
if (data != null) {
|
|
|
|
if (data.Value) {
|
|
var value = data.Value;
|
|
if (data.Unit) {
|
|
value += " " + data.Unit;
|
|
}
|
|
if (data.Description) {
|
|
value += " " + data.Description;
|
|
}
|
|
return value;
|
|
}
|
|
else {
|
|
console.log('值为空:' + device.Name + '/' + dataName);
|
|
}
|
|
}
|
|
else {
|
|
console.log('无法找到:' + device.Name + '/' + dataName);
|
|
}
|
|
|
|
}
|
|
else {
|
|
console.log('无法找到:' + dataName);
|
|
}
|
|
return "";
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |