Commit 4ea6f186 authored by Laurent Velez's avatar Laurent Velez
Browse files

Initial commit

parents
Loading
Loading
Loading
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"
}
+0 −0

File added.

Preview size limit exceeded, changes collapsed.