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.
iot/projects/IoT/IoTNode/wwwroot/js/app.js

649 lines
43 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 connectionId;
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) {
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(); }, 0)
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://49.4.92.112: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: {
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;
}).always(function () {
app.dialog.close();
});
},
destroyed() {
node = null;
},
methods: {
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 "";
},
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();
},
callSence(id) {
var url = vm.IoTServer + '/App/Sence/?node=' + this.Node.Number + '&id=' + id;
ajax(url);
},
call: function (id, cmd, query) {
query = query || '';
var url = vm.IoTServer + '/App/Exec/?connectionId=' + connectionId + '&node=' + this.Node.Number + '&cmd=' + cmd + '&id=' + id;
if (query != '') {
url += "&" + query;
}
ajax(url);
},
callAll: function (name, cmd, query) {
query = query || '';
var url = vm.IoTServer + '/App/ExecAll/?connectionId=' + 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);
}
}
});
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=' + 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')
}
});
},
isChart(data) {
return data.Type === 'Int' || data.Type === 'Float';
}
},
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=' + 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 (this.Token) {
this.init();
}
else {
setTimeout(function () { app.view.current.router.navigate('/login/') }, 0);
}
});
},
methods: {
init() {
if (this.Token) {
var baseUrl = this.IoTServer;
var wsUrl = baseUrl + "/hub?group=page";
var ajaxUrl = baseUrl + "/App/GetNodes?token=" + this.Token;
$.get(ajaxUrl, function (response) {
vm.Nodes = response;
});
connection = new signalR.HubConnectionBuilder().withUrl(wsUrl).build();
onMessage();
connect();
}
}
}
});