Loading dashboard/app.js 0 → 100644 +15 −0 Original line number Diff line number Diff line var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.json()); var port=4000; app.listen(port, function () { console.log('Dashboard listening on port '+port) }) app.get('/', function (req, res) { res.sendFile(path.join(__dirname+'/index.html')); }) dashboard/index.html 0 → 100644 +288 −0 Original line number Diff line number Diff line <!DOCTYPE html> <html lang="en"> <head> <title>Fault Detection</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script> <script src="https://code.highcharts.com/stock/highstock.js"></script> <script src="https://code.highcharts.com/stock/modules/exporting.js"></script> <script src="https://code.highcharts.com/stock/modules/export-data.js"></script> <script src="https://code.highcharts.com/modules/series-label.js"></script> <script> var originator="Cae-admin"; var cseUri = "http://127.0.0.1:8080"; var cseId = "server"; var refresh = 1000; var threshold = 0.7; function getAEs(){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"?rcn=4", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); body["m2m:cb"].ae.forEach(function (ae) { if(ae.rn==="faultDetection"){ getCnts(ae.rn) } }); }, error : function(body,status,error) { } }); } function getCnts(ae_name){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"/"+ae_name+"?rcn=4", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); if(body["m2m:ae"].cnt!=undefined){ body["m2m:ae"].cnt.forEach(function (cnt) { $('#cards').append( '<div id="'+ae_name+'-'+cnt.rn+'-chart"></div><br>' ); getAllCin(ae_name,cnt.rn) //displayChart(ae_name,cnt.rn,data); }); } }, error : function(body,status,error) { } }); } function getCin(ae_name,cnt_name,series){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"/"+ae_name+"/"+cnt_name+"/la", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); var cin_con=body["m2m:cin"].con; var cin_ts=body["m2m:cin"].lt; var dat=new Date(convertDate(cin_ts)); var time = dat.getTime(); var jsonCon = JSON.parse(cin_con); var deviation = parseFloat(jsonCon.deviation); if(deviation>threshold || deviation <-threshold){ series[0].addPoint({x:time,y:parseFloat(jsonCon.original),color:"red",marker: { enabled: true,radius:6,symbol:'circle' }},false, false); }else{ series[0].addPoint([time, parseFloat(jsonCon.original)], false, false); } series[1].addPoint([time, parseFloat(jsonCon.prediction)], false, false); series[2].addPoint([time, parseFloat(jsonCon.deviation)], false, false); series[3].addPoint([time, parseFloat(threshold)], false, false); series[4].addPoint([time, parseFloat(-threshold)], true, false); //if(jsonCon.deviation>0,5 || jsonCon.deviation<-0,5){ //document.getElementById('alerts').append(jsonCon.deviation+"<br/>"); //} }, error : function(body,status,error) { } }); } function getAllCin(ae_name,cnt_name){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"/"+ae_name+"/"+cnt_name+"?rcn=4", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); var cins = body["m2m:cnt"].cin; var series = [ { name:"original", color:"CornflowerBlue", data:[] }, { name:"prediciton", color:"YellowGreen", data:[] }, { name:"deviation", color:"orange", data:[] }, { name:"deviation threshold", color:"red", data:[] }, { name:"deviation threshold", color:"red", data:[] } ]; for (var i=0; i<cins.length; i++) { var cin = cins[i]; var dat=new Date(convertDate(cin.lt)); var time = dat.getTime(); jsonCon = JSON.parse(cin.con); var deviation = parseFloat(jsonCon.deviation); if(deviation>threshold || deviation <-threshold){ series[0].data.push({x:time,y:parseFloat(jsonCon.original),color:"red",marker: { enabled: true,radius:6,symbol:'circle'}}); }else{ series[0].data.push([time,parseFloat(jsonCon.original)]); } series[1].data.push([time,parseFloat(jsonCon.prediction)]); //series[2].data.push([time,parseFloat(jsonCon.error)]); series[2].data.push([time,parseFloat(jsonCon.deviation)]); series[3].data.push([time,parseFloat(threshold)]); series[4].data.push([time,parseFloat(-threshold)]); } displayChart(ae_name,cnt_name,series) // var data = []; // var time = (new Date()).getTime(); // var i; // for (i = -99; i <= -10; i += 1) { // data.push([ // time + i * 1000, // 0 // ]); // } // return data; //return data; }, error : function(body,status,error) { } }); } function displayChart(ae_name,cnt_name,series){ Highcharts.stockChart(ae_name+'-'+cnt_name+'-chart', { chart: { //type: 'line', height: '55%', // 16:9 ratio events: { load: function () { var series = this.series; //getAllCin(ae_name,cnt_name,series); setInterval(function () { getCin(ae_name,cnt_name,series); }, refresh); } } }, rangeSelector: { selected: 4 }, time: { useUTC: false }, yAxis: { labels: { align: 'left' } }, title: { text: "Fault Detection | Model: ARIMA (10,0,1)" }, navigator: { series: { label: { enabled: false } } }, exporting: { enabled: true }, series: series, /*plotOptions: { series: { dataLabels: { enabled: true, formatter: function(){ var isLast = false; if(this.point.x === this.series.data[this.series.data.length -1].x && this.point.y === this.series.data[this.series.data.length -1].y) isLast = true; return isLast ? this.y : ''; } } } },*/ }); } function convertDate(cin_ts){ var date = cin_ts.substring(0, 4) + "-" + cin_ts.substring(4,6)+"-"+ cin_ts.substring(6,8)+"T"+cin_ts.substring(9,11)+":"+cin_ts.substring(11,13)+":"+cin_ts.substring(13,15); return date; } getAEs(); </script> </head> <body> <div class="container-fluid" id="cards" > </div> <div id="alerts"></div> </body> <html> monitoring/app.js 0 → 100644 +237 −0 Original line number Diff line number Diff line var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); var request = require('request'); var app = express(); var fs = require('fs'); var config = require('./config.json'); var cseUri = config.csePoa+"/~/"+config.cseId+"/"+config.cseName; const arima = require('arima') const l = 1 threshold = 0,5 app.use(bodyParser.json()) app.listen(config.aePort, function () { console.log('AE Monitor listening on port '+config.aePort); }); var ts = Array(100).fill(0).map((v,i) => Math.sin(i)+randomNumber(-0.2, 0.2)) app.post('/', function (req, res) { console.log("\n◀◀◀◀◀") console.log(req.body); var content = req.body['m2m:sgn'].nev.rep["m2m:cin"].con; //console.log("Content: "+JSON.stringify(content)); var data= JSON.parse(content); console.log(data) res.sendStatus(204); ts.push(data) ts.shift() console.log(ts) const [pred, errors] = arima(ts.slice(0, ts.length-l), l, { method: 0, optimizer: 6, p: 10, d: 0, q: 1, verbose: true }) console.log('Ytrue,Ypred,Err') pred.forEach((v, i) => { var o = ts[ts.length - l + i]; var e= errors[i] console.log(o + ',' + v + ',' + e) var deviation = o - v; var jsonCon = { "original": o, "prediction":v, "error":e, "deviation":deviation, "targetContainer":config.targetCnt } if(e<1){ createContenInstance(cseUri+"/"+config.aeName+"/report",jsonCon) } /*if(deviation>threshold || deviation<-threshold){ ts[99]=undefined }*/ }) }); createAE(cseUri); function createAE(targetUri){ console.log("\n▶▶▶▶▶"); var representation = { "m2m:ae":{ "rn":config.aeName, "api":config.appId, "rr":"true", "poa":["http://"+config.aeIp+":"+config.aePort+"/"] } }; console.log("POST "+targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=2" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); console.log(body); createSubscription(cseUri+config.targetCnt); createContainer(targetUri+"/"+config.aeName,"report") } }); } function createContainer(targetUri,name){ console.log("\n▶▶▶▶▶"); var representation = { "m2m:cnt":{ "rn":name, "mni":config.cntMni } }; console.log("POST "+ targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=3" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); console.log(body); } }); } function createSubscription(targetUri){ console.log("\n▶▶▶▶▶"); var representation = { "m2m:sub": { "rn": config.subName, "nu": ["/"+config.cseName+"/"+config.aeId], "nct": 2, "enc": { "net": [3] } } }; console.log("POST "+targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=23" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); console.log(body); } }); } function createContenInstance(targetUri,jsonCon){ console.log("\n▶▶▶▶▶"); //stringify(jsonCon) var representation = { "m2m:cin":{ "con": JSON.stringify(jsonCon) } }; console.log("POST "+targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=4" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); //console.log(body); } }); } function randomNumber(min, max) { return Math.random() * (max - min) + min; } function difference(a, b) { return Math.abs(a - b); } No newline at end of file monitoring/config.json 0 → 100644 +13 −0 Original line number Diff line number Diff line { "csePoa": "http://127.0.0.1:8080", "cseId": "server", "cseName": "server", "aeId": "Cae-faultDetection", "aeName": "faultDetection", "cntMni": 100, "appId": "app.company.com", "aeIp": "127.0.0.1", "aePort": 3000, "subName": "faultDetectionSub", "targetCnt": "/sensor/data" } Loading
dashboard/app.js 0 → 100644 +15 −0 Original line number Diff line number Diff line var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.json()); var port=4000; app.listen(port, function () { console.log('Dashboard listening on port '+port) }) app.get('/', function (req, res) { res.sendFile(path.join(__dirname+'/index.html')); })
dashboard/index.html 0 → 100644 +288 −0 Original line number Diff line number Diff line <!DOCTYPE html> <html lang="en"> <head> <title>Fault Detection</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script> <script src="https://code.highcharts.com/stock/highstock.js"></script> <script src="https://code.highcharts.com/stock/modules/exporting.js"></script> <script src="https://code.highcharts.com/stock/modules/export-data.js"></script> <script src="https://code.highcharts.com/modules/series-label.js"></script> <script> var originator="Cae-admin"; var cseUri = "http://127.0.0.1:8080"; var cseId = "server"; var refresh = 1000; var threshold = 0.7; function getAEs(){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"?rcn=4", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); body["m2m:cb"].ae.forEach(function (ae) { if(ae.rn==="faultDetection"){ getCnts(ae.rn) } }); }, error : function(body,status,error) { } }); } function getCnts(ae_name){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"/"+ae_name+"?rcn=4", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); if(body["m2m:ae"].cnt!=undefined){ body["m2m:ae"].cnt.forEach(function (cnt) { $('#cards').append( '<div id="'+ae_name+'-'+cnt.rn+'-chart"></div><br>' ); getAllCin(ae_name,cnt.rn) //displayChart(ae_name,cnt.rn,data); }); } }, error : function(body,status,error) { } }); } function getCin(ae_name,cnt_name,series){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"/"+ae_name+"/"+cnt_name+"/la", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); var cin_con=body["m2m:cin"].con; var cin_ts=body["m2m:cin"].lt; var dat=new Date(convertDate(cin_ts)); var time = dat.getTime(); var jsonCon = JSON.parse(cin_con); var deviation = parseFloat(jsonCon.deviation); if(deviation>threshold || deviation <-threshold){ series[0].addPoint({x:time,y:parseFloat(jsonCon.original),color:"red",marker: { enabled: true,radius:6,symbol:'circle' }},false, false); }else{ series[0].addPoint([time, parseFloat(jsonCon.original)], false, false); } series[1].addPoint([time, parseFloat(jsonCon.prediction)], false, false); series[2].addPoint([time, parseFloat(jsonCon.deviation)], false, false); series[3].addPoint([time, parseFloat(threshold)], false, false); series[4].addPoint([time, parseFloat(-threshold)], true, false); //if(jsonCon.deviation>0,5 || jsonCon.deviation<-0,5){ //document.getElementById('alerts').append(jsonCon.deviation+"<br/>"); //} }, error : function(body,status,error) { } }); } function getAllCin(ae_name,cnt_name){ $.ajax({ type : "GET", url : cseUri+"/"+cseId+"/"+ae_name+"/"+cnt_name+"?rcn=4", headers: { "X-M2M-Origin": originator, "Content-Type": "application/json" }, body:"json", success : function(body,code){ console.log(body); var cins = body["m2m:cnt"].cin; var series = [ { name:"original", color:"CornflowerBlue", data:[] }, { name:"prediciton", color:"YellowGreen", data:[] }, { name:"deviation", color:"orange", data:[] }, { name:"deviation threshold", color:"red", data:[] }, { name:"deviation threshold", color:"red", data:[] } ]; for (var i=0; i<cins.length; i++) { var cin = cins[i]; var dat=new Date(convertDate(cin.lt)); var time = dat.getTime(); jsonCon = JSON.parse(cin.con); var deviation = parseFloat(jsonCon.deviation); if(deviation>threshold || deviation <-threshold){ series[0].data.push({x:time,y:parseFloat(jsonCon.original),color:"red",marker: { enabled: true,radius:6,symbol:'circle'}}); }else{ series[0].data.push([time,parseFloat(jsonCon.original)]); } series[1].data.push([time,parseFloat(jsonCon.prediction)]); //series[2].data.push([time,parseFloat(jsonCon.error)]); series[2].data.push([time,parseFloat(jsonCon.deviation)]); series[3].data.push([time,parseFloat(threshold)]); series[4].data.push([time,parseFloat(-threshold)]); } displayChart(ae_name,cnt_name,series) // var data = []; // var time = (new Date()).getTime(); // var i; // for (i = -99; i <= -10; i += 1) { // data.push([ // time + i * 1000, // 0 // ]); // } // return data; //return data; }, error : function(body,status,error) { } }); } function displayChart(ae_name,cnt_name,series){ Highcharts.stockChart(ae_name+'-'+cnt_name+'-chart', { chart: { //type: 'line', height: '55%', // 16:9 ratio events: { load: function () { var series = this.series; //getAllCin(ae_name,cnt_name,series); setInterval(function () { getCin(ae_name,cnt_name,series); }, refresh); } } }, rangeSelector: { selected: 4 }, time: { useUTC: false }, yAxis: { labels: { align: 'left' } }, title: { text: "Fault Detection | Model: ARIMA (10,0,1)" }, navigator: { series: { label: { enabled: false } } }, exporting: { enabled: true }, series: series, /*plotOptions: { series: { dataLabels: { enabled: true, formatter: function(){ var isLast = false; if(this.point.x === this.series.data[this.series.data.length -1].x && this.point.y === this.series.data[this.series.data.length -1].y) isLast = true; return isLast ? this.y : ''; } } } },*/ }); } function convertDate(cin_ts){ var date = cin_ts.substring(0, 4) + "-" + cin_ts.substring(4,6)+"-"+ cin_ts.substring(6,8)+"T"+cin_ts.substring(9,11)+":"+cin_ts.substring(11,13)+":"+cin_ts.substring(13,15); return date; } getAEs(); </script> </head> <body> <div class="container-fluid" id="cards" > </div> <div id="alerts"></div> </body> <html>
monitoring/app.js 0 → 100644 +237 −0 Original line number Diff line number Diff line var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); var request = require('request'); var app = express(); var fs = require('fs'); var config = require('./config.json'); var cseUri = config.csePoa+"/~/"+config.cseId+"/"+config.cseName; const arima = require('arima') const l = 1 threshold = 0,5 app.use(bodyParser.json()) app.listen(config.aePort, function () { console.log('AE Monitor listening on port '+config.aePort); }); var ts = Array(100).fill(0).map((v,i) => Math.sin(i)+randomNumber(-0.2, 0.2)) app.post('/', function (req, res) { console.log("\n◀◀◀◀◀") console.log(req.body); var content = req.body['m2m:sgn'].nev.rep["m2m:cin"].con; //console.log("Content: "+JSON.stringify(content)); var data= JSON.parse(content); console.log(data) res.sendStatus(204); ts.push(data) ts.shift() console.log(ts) const [pred, errors] = arima(ts.slice(0, ts.length-l), l, { method: 0, optimizer: 6, p: 10, d: 0, q: 1, verbose: true }) console.log('Ytrue,Ypred,Err') pred.forEach((v, i) => { var o = ts[ts.length - l + i]; var e= errors[i] console.log(o + ',' + v + ',' + e) var deviation = o - v; var jsonCon = { "original": o, "prediction":v, "error":e, "deviation":deviation, "targetContainer":config.targetCnt } if(e<1){ createContenInstance(cseUri+"/"+config.aeName+"/report",jsonCon) } /*if(deviation>threshold || deviation<-threshold){ ts[99]=undefined }*/ }) }); createAE(cseUri); function createAE(targetUri){ console.log("\n▶▶▶▶▶"); var representation = { "m2m:ae":{ "rn":config.aeName, "api":config.appId, "rr":"true", "poa":["http://"+config.aeIp+":"+config.aePort+"/"] } }; console.log("POST "+targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=2" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); console.log(body); createSubscription(cseUri+config.targetCnt); createContainer(targetUri+"/"+config.aeName,"report") } }); } function createContainer(targetUri,name){ console.log("\n▶▶▶▶▶"); var representation = { "m2m:cnt":{ "rn":name, "mni":config.cntMni } }; console.log("POST "+ targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=3" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); console.log(body); } }); } function createSubscription(targetUri){ console.log("\n▶▶▶▶▶"); var representation = { "m2m:sub": { "rn": config.subName, "nu": ["/"+config.cseName+"/"+config.aeId], "nct": 2, "enc": { "net": [3] } } }; console.log("POST "+targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=23" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); console.log(body); } }); } function createContenInstance(targetUri,jsonCon){ console.log("\n▶▶▶▶▶"); //stringify(jsonCon) var representation = { "m2m:cin":{ "con": JSON.stringify(jsonCon) } }; console.log("POST "+targetUri); console.log(representation); var options = { uri: targetUri, method: "POST", headers: { "X-M2M-Origin": config.aeId, "X-M2M-RI": "123456", "Content-Type": "application/json;ty=4" }, json: representation }; request(options, function (error, response, body) { console.log("◀◀◀◀◀"); if(error){ console.log(error); }else{ console.log(response.statusCode); //console.log(body); } }); } function randomNumber(min, max) { return Math.random() * (max - min) + min; } function difference(a, b) { return Math.abs(a - b); } No newline at end of file
monitoring/config.json 0 → 100644 +13 −0 Original line number Diff line number Diff line { "csePoa": "http://127.0.0.1:8080", "cseId": "server", "cseName": "server", "aeId": "Cae-faultDetection", "aeName": "faultDetection", "cntMni": 100, "appId": "app.company.com", "aeIp": "127.0.0.1", "aePort": 3000, "subName": "faultDetectionSub", "targetCnt": "/sensor/data" }