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.

836 lines
57 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

var vm;
var app;
var node;
var device;
var connection;
var isApp = false;
var flvPlayer;
var timer;
var decodedFrames;
var isiOS = new MobileDetect(window.navigator.userAgent).os() === 'iOS';
//func
$.ajaxSetup({
cache: false,
timeout: 5000
});
$('body').on('click', 'img.shot', function () {
$(this).toggleClass('zoom');
});
function ajax(url) {
console.log(url);
app.dialog.progress();
$.get(url, function (response) {
var result = response;
if (result.code === 0) {
if (result.type === 0) {
if (result.format === 1) {
console.log('format/1/base64 jpeg image');
$('#callback .page-content').html('<img class="shot" src="' + result.data + '">');
}
else {
console.log('format/0/json object');
$('#callback .page-content').html(result.data);
}
app.popup.open('#callback');
}
}
}).fail(function (result) {
console.log('error');
console.log(result);
}).always(function () {
app.dialog.close();
});;
}
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);
});
}
}
function onMessage() {
connection.on('Connected', function (id) {
vm.ConnectionId = id;
});
connection.on('ApiResult', function (result) {
result = JSON.parse(result);
if (result.code === 0) {
if (result.type === 0) {
if (result.format === 1) {
console.log('format/1/base64 jpeg image');
$('#callback .page-content').html('<img class="shot" src="' + result.data + '">');
}
else {
console.log('format/0/json object');
$('#callback .page-content').html(result.data);
}
app.popup.open('#callback');
}
}
});
connection.on("UpdateNode", (message) => {
var newNode = JSON.parse(message);
var oldNode = _.chain(vm.Nodes).filter(o => o.Number === newNode.Number).first().value();
oldNode.Name = newNode.Name;
if (node && node.Node.Number === newNode.Number) {
node.Node.Name = newNode.Name;
}
console.log('update:' + newNode.Name);
});
connection.on("UpdateDevice", (message) => {
var newDevice = JSON.parse(message);
while (vm.Messages.length >= 20) {
vm.Messages.pop();
}
vm.Messages.push(newDevice);
if (node && node.Node.Id == newDevice.NodeId) {
var update = false;
for (var i = 0; i < node.Node.Devices.length; i++) {
if (node.Node.Devices[i].Number == newDevice.Number) {
update = true;
break;
}
}
if (update) {
node.Node.Devices.splice(i, 1, newDevice);
}
else {
node.Node.Devices.push(newDevice);
}
}
if (device && device.Device.Number == newDevice.Number) {
device.Device.Name = newDevice.Name;
device.Device.DisplayName = newDevice.DisplayName;
device.Device.Data = newDevice.Data;
updateChart();
}
});
connection.on("DeleteDevice", (message) => {
var newDevice = JSON.parse(message);
if (node && node.Node.Id === newDevice.NodeId) {
for (var i = 0; i < node.Node.Devices.length; i++) {
if (node.Node.Devices[i].Number == newDevice.Number) {
node.Node.Devices.splice(i, 1);
break;
}
}
console.log('delete:' + newDevice.Number);
}
});
connection.on("UpdateSence", function (message) {
var sence = JSON.parse(message);
if (node && node.Node.Id === sence.NodeId) {
var update = false;
for (var i = 0; i < node.Node.Sences.length; i++) {
if (node.Node.Sences[i].Id == sence.Id) {
update = true;
break;
}
}
if (update) {
node.Node.Sences.splice(i, 1, sence);
}
else {
node.Node.Sences.push(sence);
}
console.log('update:' + sence.DisplayName);
}
});
connection.on("DeleteSence", function (message) {
var sence = JSON.parse(message);
if (node && node.Node.Id === sence.NodeId) {
for (var i = 0; i < node.Node.Sences.length; i++) {
if (node.Node.Sences[i].Id == sence.Id) {
node.Node.Sences.splice(i, 1);
break;
}
}
console.log('delete:' + sence.Name);
}
});
connection.onclose(function () {
setTimeout(connect, 10 * 1000);
});
}
function playFlv(url) {
var id = 'flvPlayer';
var videoElement = document.getElementById(id);
try {
if (flvPlayer != null) {
closePlayer();
}
flvPlayer = flvjs.createPlayer({
type: 'flv',
url: url,
isLive: true,
cors: true
}, {
enableWorker: true,
enableStashBuffer: false,
stashInitialSize: 1,
fixAudioTimestampGap: false
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
setTimeout(function () {
flvPlayer.play();
}, 150);
timer = setInterval(function () {
console.log('.');
if (flvPlayer.statisticsInfo.speed == 0) {
console.log('reload1');
closePlayer();
playFlv(url);
}
else if (decodedFrames && flvPlayer.statisticsInfo.decodedFrames <= decodedFrames) {
console.log('reload2');
closePlayer();
playFlv(url);
}
else if (flvPlayer.buffered.end(0) - flvPlayer.currentTime > 1) {
console.log('reset currentTime');
flvPlayer.currentTime = flvPlayer.buffered.end(0) - 0.001;
}
decodedFrames = flvPlayer.statisticsInfo.decodedFrames;
}, 10 * 1000);
} catch (e) {
console.log(e);
}
}
function closePlayer() {
if (timer) {
clearInterval(timer);
timer = null;
}
if (flvPlayer != null) {
flvPlayer.pause();
flvPlayer.unload();
flvPlayer.detachMediaElement();
flvPlayer.destroy();
flvPlayer = null;
}
}
function createChart() {
$('canvas.chart').each(function () {
var id = $(this).attr('id');
var canvas = document.getElementById(id);
var label = $(this).attr('data-label');
var ctx = canvas.getContext('2d');
var config = createConfig(label, [], []);
new Chart(ctx, config);
});
}
function createConfig(label, labels, data) {
return {
type: 'line',
data: {
labels: labels,
datasets: [{
label: label,
data: data,
borderColor: 'green',
fill: false
}]
},
options: {
responsive: true,
title: {
display: true,
text: label,
}
}
};
}
function updateChart() {
var url = vm.IoTServer + '/App/Data?id=' + device.Device.Id;
$.getJSON(url, function (result) {
console.log(result);
$.each(result, function (i, n) {
var id = n.id;
Chart.helpers.each(Chart.instances, function (instance) {
if (instance.chart.canvas.id == id) {
console.log('update chart:' + id);
instance.chart.data.labels = n.labels;
instance.chart.data.datasets[0].data = n.data;
instance.chart.update();
}
})
});
}).fail(function () {
console.log('error');
}).always(function () {
app.dialog.close();
});;
}
Framework7.use(Framework7Vue);
Vue.component('page-home', {
template: '#page-home',
data() {
return {
};
},
mounted() {
},
methods: {
}
});
Vue.component('page-login', {
template: '#page-login',
data() {
return {
Server: localStorage.getItem('Server') || 'http://localhost:8000',
UserName: localStorage.getItem('UserName'),
Password: null,
RememberMe: localStorage.getItem('RememberMe')
};
},
mounted() {
localStorage.removeItem('Token');
$('form.login').removeData('validator');
$('form.login').removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse('form.login');
},
methods: {
FaceLogin: function (server, rememberMe) {
window.location.href = "uniwebview://facelogin?Server=" + encodeURIComponent(server) + "&RememberMe=" + rememberMe;
},
OnSubmit: function (e) {
if (!$(e.target).valid()) {
return;
}
var url = e.target.action;
var data = $(e.target).serialize();
var current = this;
$.post(url, data, function (response) {
if (response.Code === 0) {
vm.Token = response.Token;
if (current.RememberMe === true) {
localStorage.setItem("Token", response.Token);
localStorage.setItem("Server", current.Server);
localStorage.setItem("UserName", current.UserName);
localStorage.setItem("NickName", response.NickName);
localStorage.setItem("Title", response.Title);
localStorage.setItem("IoTServer", _.trimEnd(response.IoTServer, ['/']));
}
else {
localStorage.removeItem("Token");
}
vm.Server = current.Server;
vm.RememberMe = current.RememberMe;
vm.UserName = current.UserName;
vm.NickName = response.NickName;
vm.Title = response.Title;
vm.IoTServer = _.trimEnd(response.IoTServer, ['/']);
vm.$f7.view.current.router.back();
}
else {
app.dialog.alert(response.Message, "消息");
}
}).fail(function (e) {
var message;
if (e.status === 0) {
message = "不是有效的服务器地址";
}
else {
message = e.status + ":" + e.statusText;
}
vm.$f7.dialog.alert(message, "消息");
});
}
}
});
Vue.component('page-node', {
template: '#page-node',
data() {
return {
Node: {
Number: null,
Name: null,
Sences: [],
Devices: []
}
}
},
mounted() {
this.Node.Number = this.$f7route.params.number;
this.Node.Name = this.$f7route.params.name;
node = this;
var ajaxUrl = vm.IoTServer + "/App/GetNode?token=" + vm.Token + '&number=' + this.Node.Number;
app.dialog.progress();
$.get(ajaxUrl, function (response) {
node.Node = response;
Vue.nextTick(function () {
$('video.video').each(function () {
var videoElement = $(this)[0];
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: $(this).attr('src'),
isLive: true,
cors: true
}, {
enableWorker: true,
enableStashBuffer: false,
stashInitialSize: 1,
fixAudioTimestampGap: false
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
setInterval(function () {
console.log('.');
if (flvPlayer.buffered.end(0) - flvPlayer.currentTime > 1) {
console.log('reset currentTime');
flvPlayer.currentTime = flvPlayer.buffered.end(0) - 0.001;
}
decodedFrames = flvPlayer.statisticsInfo.decodedFrames;
}, 10 * 1000);
});
});
}).always(function () {
app.dialog.close();
});
},
destroyed() {
node = null;
},
methods: {
getDevices: function () {
var args = arguments;
return _.chain(this.Node.Devices).filter(function (device) {
return _.chain(args).filter(function (name) { return device.Name.indexOf(name) != -1; }).value().length > 0;
}).orderBy(['DisplayOrder', 'Name']).value();
},
getValue(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;
return value;
}
else {
console.log('值为空:' + device.Name + '/' + dataName);
}
}
else {
console.log('无法找到:' + device.Name + '/' + dataName);
}
}
else {
console.log('无法找到:' + dataName);
}
return "";
},
getData(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 "";
},
callSence(id) {
var url = vm.IoTServer + '/App/Sence/?node=' + this.Node.Number + '&id=' + id;
ajax(url);
},
call: function (gateway,number, cmd, query) {
query = query || '';
var url = vm.IoTServer + '/App/Exec/?connectionId=' + vm.ConnectionId + '&gateway=' + gateway + '&number=' + number + '&method=' + cmd + query;
if (query != '') {
url += "&" + query;
}
ajax(url);
},
callAll: function (name, cmd, query) {
query = query || '';
var url = vm.IoTServer + '/App/ExecAll/?connectionId=' + vm.ConnectionId + '&node=' + this.Node.Number + '&cmd=' + cmd;
var list = this.getDevices(name);
for (var i = 0; i < list.length; i++) {
url += '&id[' + i + ']=' + list[i].Id;
}
if (query != '') {
url += "&" + query;
}
ajax(url);
},
change1(e,device) {
var data = _.first(_.filter(device.Data, function (o) { return o.Name === '按键' }));
var form = $(e.target).parents('form');
if (form.hasClass('KeyCodeType1')) {
if (form.find("[name='power']").val() == '1') {
data.Value = "1";//form.find("[name = 'code']").val(1);
}
else {
var code = 2;
code += parseInt(form.find("[name = 'pattern']").val());
code += parseInt(form.find("[name = 'direction']").val());
code += parseInt(form.find("[name = 'wind']").val());
code += parseInt(form.find("[name = 'temperature']").val());
data.Value = code;//form.find("[name = 'code']").val(code);
}
}
var url = form.attr('action') + '?' + form.serialize();
ajax(url);
},
getCode1(code) {
var pattern = 0;
var direction = 0;
var wind = 0;
var power = 2;
var temperature = 1;
if (code > 480 + 2) {
pattern = 480;
}
else if (code > 360 + 2) {
pattern = 360;
}
else if (code > 240 + 2) {
pattern = 240;
}
else if (code > 120 + 2) {
pattern = 120;
}
else {
pattern = 0;
}
code -= pattern;
if (code > 75 + 2) {
direction = 75;
}
else if (code > 60 + 2) {
direction = 60;
}
else {
direction = 0;
}
code -= direction;
if (code > 45+2) {
wind = 45;
}
else if (code > 30 + 2) {
wind = 30;
}
else if (code > 15 + 2) {
wind = 15;
}
else {
wind = 0;
}
code -= wind;
if (code === 1) {
power = 1;
}
else {
power = 2;
temperature = code - power;
}
return {
pattern: pattern,
direction: direction,
wind: wind,
power: power,
temperature: temperature
};
}
}
});
Vue.component('page-device', {
template: '#page-device',
data() {
return {
Device: {
Number: null,
Name: null,
Data: [],
Apis: []
}
}
},
mounted() {
this.Device.Number = this.$f7route.params.number;
this.Device.Name = this.$f7route.params.name;
device = this;
var ajaxUrl = vm.IoTServer + "/App/GetDevice?token=" + vm.Token + '&number=' + this.Device.Number;
app.dialog.progress();
$.get(ajaxUrl, function (response) {
device.Device = response;
Vue.nextTick(function () {
createChart();
updateChart();
$('form.command').removeData('validator');
$('form.command').removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse('form.command');
});
}).always(function () {
app.dialog.close();
});
},
methods: {
isSelect: function (device, key) {
return _.filter(device.Data, function (o) { return o.Key == key + '[]' }).length > 0;
},
getSelect: function (device, key) {
var data = _.first(_.filter(device.Data, function (o) { return o.Key == key + '[]' })).Value;
var result = JSON.parse(data);
return result;
},
getParameter: function (name) {
console.log(name);
var prop = _.chain(this.Device.Data).filter(function (o) { return o.Key == name; }).first().value();
return prop ? prop.Value : '';
},
call: function (e) {
if (!$(e.target).valid()) {
return;
}
var url = vm.IoTServer + '/App/Exec/?connectionId=' + vm.ConnectionId + '&node=' + this.getNodeNumber(this.Device.NodeId) + '&' + $(e.target).serialize();
ajax(url);
},
getNodeNumber(nodeId) {
return _.chain(vm.Nodes).filter(function (o) {
return o.Id === nodeId;
}).first().value().Number;
},
showData(name) {
if (name === 'hidden' || name.indexOf('rtsp') != -1 || name.indexOf('rtmp') != -1 || name.indexOf('flv') != -1 || name.indexOf('hls') != -1) {
return false;
}
return true;
},
showApi(api) {
if (this.Device.Name === '摄像头') {
if (this.getParameter('Ptz3DZoomSupport') === '否') {
if (api.Name !== '截屏') {
return false;
}
}
}
return true;
},
getUrl(type) {
var url = _.chain(this.Device.Data).filter(function (o) { return o.Name === (type + '2'); }).first().value().Value;
url += '?id=' + this.Device.Id;
url += '&host=' + encodeURIComponent(vm.IoTServer);
url += '&node=' + _.chain(vm.Nodes).filter(function (o) { return o.Id === device.Device.NodeId; }).first().value().Number;
if (this.getParameter('Ptz3DZoomSupport') !== '否') {
url += '&ptz=true';
}
return url;
},
flv() {
this.$f7router.navigate('/camera/', {
props: {
name: this.Device.DisplayName || this.Device.Name,
url: this.getParameter('flv2'),
ptz: this.getParameter('Ptz3DZoomSupport') !== '否',
node: this.getNodeNumber(this.Device.NodeId),
id: this.Device.Id,
hls: this.getParameter('hls2')
}
});
}
},
destroyed() {
device = null;
},
});
Vue.component('page-camera', {
template: '#page-camera',
props: ['name', 'url', 'ptz', 'node', 'id', 'hls'],
data() {
return {
}
},
mounted() {
this.play();
},
methods: {
play: function () {
var url = this.$props.url;
if (isiOS) {
$('#flvPlayer').attr('src', this.$props.hls);
}
else {
playFlv(url);
}
},
call: function (cmd) {
console.log(cmd);
var url = vm.IoTServer + '/App/Exec/?connectionId=' + vm.ConnectionId + '&cmd=' + cmd + '&node=' + this.$props.node + '&id=' + this.$props.id;
ajax(url);
return false;
}
},
destroy() {
closePlayer();
}
});
Vue.component('page-not-found', {
template: '#page-not-found'
});
vm = new Vue({
el: '#app',
data() {
return {
f7params: {
root: '#app',
id: 'io.framework7.testapp',
name: 'Framework7',
theme: 'ios',
routes: [
{
path: '/',
component: 'page-home'
},
{
path: '/login/',
component: 'page-login'
},
{
path: '/node/:number/name/:name',
component: 'page-node'
},
{
path: '/device/:number/name/:name',
component: 'page-device'
},
{
path: '/camera/',
component: 'page-camera'
},
{
path: '(.*)',
component: 'page-not-found',
},
],
},
Title: localStorage.getItem('Title'),
Server: localStorage.getItem('Server'),
Token: localStorage.getItem('Token'),
UserName: localStorage.getItem('UserName'),
RememberMe: localStorage.getItem('RememberMe'),
NickName: localStorage.getItem('NickName'),
IoTServer: localStorage.getItem('IoTServer'),
User: null,
Nodes: [],
Messages: [],
}
},
mounted() {
this.$f7ready((f7) => {
app = this.$f7;
if ((window.navigator.userAgent.indexOf("app") > -1)) {
window.location.href = "uniwebview://init";
}
else {
load();
}
});
},
methods: {
init() {
if (vm.Token) {
var baseUrl = this.IoTServer;
var wsUrl = baseUrl + "/hub?group=page";
var ajaxUrl = baseUrl + "/App/GetNodes?token=" + vm.Token;
$.get(ajaxUrl, function (response) {
vm.Nodes = response;
});
connection = new signalR.HubConnectionBuilder().withUrl(wsUrl).build();
onMessage();
connect();
}
}
}
});
function load() {
if (localStorage.getItem('Token')) {
vm.init();
}
else {
setTimeout(function () { app.view.current.router.navigate('/login/') }, 0);
}
}
function load2(message)
{
var response = JSON.parse(message);
vm.Token = response.Token;
if (response.RememberMe === true) {
localStorage.setItem("Token", response.Token);
localStorage.setItem("Server", response.Server);
localStorage.setItem("UserName", response.UserName);
localStorage.setItem("NickName", response.NickName);
localStorage.setItem("Title", response.Title);
localStorage.setItem("IoTServer", _.trimEnd(response.IoTServer, ['/']));
}
else {
localStorage.removeItem("Token");
}
vm.Server = response.Server;
vm.RememberMe = response.RememberMe;
vm.UserName = response.UserName;
vm.NickName = response.NickName;
vm.Title = response.Title;
vm.IoTServer = _.trimEnd(response.IoTServer, ['/']);
vm.$f7.view.current.router.back();
vm.init();
}
//
$('body').on('change', 'input.ajax', function (e) {
var form = $(this).parents('form');
var url = form.attr('action') + '?' + form.serialize();
if (form.hasClass('KeyCodeType1')) {
if (e.target.name == "power" && e.target.value=="1") {
url = new URI(url).setQuery('Code','1').toString();
}
else {
var list = {};
list['power'] = form.find("[name = 'power']:checked").val();
list['pattern'] = form.find("[name = 'pattern']:checked").val();
list['direction'] = form.find("[name = 'direction']:checked").val();
list['wind'] = form.find("[name = 'wind']:checked").val();
list['temperature'] = form.find("[name = 'temperature']").val();
list[e.target.name] = e.target.value;
var code = 0;
for (var name in list) {
code += parseInt(list[name]);
}
url = new URI(url).setQuery('Code', code).toString();
}
}
ajax(url);
return false;
});