import {Component, OnInit} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {PacketGroup} from "../../entities/PacketGroup";
import {Chart} from "chart.js/auto";
import {devicesToRequest, numToColor} from "../../utils/Utils";
import {KeyValueMap} from "../../entities/KeyValueMap";
import {NodeDTO} from "../../entities/NodeDTO";
import {ActivatedRoute} from "@angular/router";
import {PacketSignalDTO} from "../../entities/PacketSignalDTO";
import {DatePipe} from "@angular/common";
@Component({
selector: "app-network-status",
template: `
Статистика всей сети (желательно нажать ф5 если до этого смотрели другую ноду)
Статистика ноды {{getNumName(NUM)}} в сети
За день
За неделю
За месяц
`
})
export class NetworkStatusComponent implements OnInit {
DAY = 86400;
WEEK = this.DAY * 7;
MONTH = this.DAY * 30;
MODE: "ALL"|"NODE" = "ALL"
NUM:number = 0;
signalMode:"day"|"month"|"week"|string = "day"
signalCanvasId = "signalCanvasId";
signalChart = {
chart: null as unknown as Chart,
config: this.generateConfigTChart("Проходимость сигнала", true, "line") as any
};
nodesNames: KeyValueMap = {}
//общая статичтика по perPortNum за день\неделю\месяц / ?=
//top кто насрал пакетами всего за день\неделю\месяц / ?=packetsSumNode=true
graphs:any[] = this.generateGraps();
constructor(private http: HttpClient,
private route: ActivatedRoute,
private datepipe: DatePipe) {}
getNumName(num:number) {
if (`${num}` in this.nodesNames)
return this.nodesNames[`${num}`].long_name
else return `${num}`
}
generateGraps() {
return [
{
header: "Cтатистика пакетов в сети",
type: 'perPortNum',
requestMode: "ALL",
endpoint:"api/packet/stats",
cards:[{
chart: null as unknown as Chart,
canvasId: "DayPerPB",
params: "?=",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.DAY,
config: this.generateConfigTChart("Cтатистика по пакетам в сети за день")
},{
chart: null as unknown as Chart,
canvasId: "WeekPerPB",
params: "?=",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.WEEK,
config: this.generateConfigTChart("Cтатистика по пакетам в сети за неделю")
},{
chart: null as unknown as Chart,
canvasId: "MonthPerPB",
params: "?=",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.MONTH,
config: this.generateConfigTChart("Cтатистика по пакетам в сети за месяц")
}]
},
{
header: "Общая статистика пакетов в сети",
type: 'perSumNode',
requestMode: "ALL",
endpoint:"api/packet/stats",
cards:[{
chart: null as unknown as Chart,
canvasId: "DaySumPB",
params: "?packetsSumNode=true",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.DAY,
config: this.generateConfigTChart("Количество пакетов от пользоватей за день", false)
},{
chart: null as unknown as Chart,
canvasId: "WeekSumPB",
params: "?packetsSumNode=true",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.WEEK,
config: this.generateConfigTChart("Количество пакетов от пользоватей за неделю", false)
},{
chart: null as unknown as Chart,
canvasId: "MonthSumPB",
params: "?packetsSumNode=true",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.MONTH,
config: this.generateConfigTChart("Количество пакетов от пользоватей за месяц", false)
}]
},{
header: "Cтатистика пакетов в сети",
type: 'packetsPerNode',
requestMode: "NODE",
endpoint:"api/packet/stats",
cards:[{
chart: null as unknown as Chart,
canvasId: "DayPerNodePB",
params: "?packetsPerNode=true",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.DAY,
config: this.generateConfigTChart("Cтатистика по пакетам в сети за день")
},{
chart: null as unknown as Chart,
canvasId: "WeekPerNodePB",
params: "?packetsPerNode=true",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.WEEK,
config: this.generateConfigTChart("Cтатистика по пакетам в сети за неделю")
},{
chart: null as unknown as Chart,
canvasId: "MonthPerNodePB",
params: "?packetsPerNode=true",
before: new Date().getTime()/1000,
after: (new Date().getTime()/1000) - this.MONTH,
config: this.generateConfigTChart("Cтатистика по пакетам в сети за месяц")
}]
}
]
}
generateConfigTChart(name: string, legend: boolean = true, type: string = "pie") {
return {
type: type,
data: {
labels: [] as any[],
datasets: [] as any[]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom',
display: legend
},
title: {
display: true,
text: name
}
}
}
}
}
ngOnInit(): void {
this.route.params.subscribe(
(params) => {
const num: number = Number.parseInt(params["num"]);
switch (num) {
case 0: {
this.MODE = "ALL";
this.http.get(`api/nodes/list?q=${devicesToRequest()}`).subscribe(
(obj) => {
(obj as NodeDTO[]).forEach(
(node) => {
this.nodesNames[`${node.num}`] = node;
}
)
}
).add(
() => {
this.graphs = this.generateGraps();
this.updateGraphs();
}
)
break;
}
default: {
this.MODE = "NODE";
this.NUM = num;
this.http.get(`api/nodes/${num}?q=${devicesToRequest()}`).subscribe(
(obj) => {
const node: NodeDTO = obj as NodeDTO
if (node)
this.nodesNames[`${node.num}`] = node;
}
).add(
() => {
this.graphs = this.generateGraps();
this.updateGraphs();
this.updateSignalGraph();
}
)
break;
}
}
})
}
updateSignalGraph() {
const before = new Date().getTime() / 1000;
let after;
switch (this.signalMode) {
case "day": {
after = (new Date().getTime()/1000) - this.DAY;
break;
}
case "week": {
after = (new Date().getTime()/1000) - this.WEEK;
break;
}
case "month": {
after = (new Date().getTime()/1000) - this.MONTH;
break;
}
}
this.http.get(`api/packet/signal?before=${before}&after=${after}&nums=${this.NUM}${devicesToRequest()}`).subscribe(
(obj) => {
this.signalChart.config.data = {labels: [], datasets:[{label: "snr",data:[]},{label: "rssi",data:[]}]};
(obj as PacketSignalDTO[]).forEach(
(packet: PacketSignalDTO) => {
this.signalChart.config.data.labels.push(this.datepipe.transform(packet.ts*1000, 'HH:mm dd.MM.yyyy'))
this.signalChart.config.data.datasets[0].data.push(packet.rx_snr)
this.signalChart.config.data.datasets[1].data.push(packet.rx_rssi)
return;
}
)
if (this.signalChart.chart != null)
this.signalChart.chart.destroy()
this.signalChart.chart = new Chart(this.signalCanvasId, this.signalChart.config)
}
)
}
updateGraphs() {
this.graphs.forEach(
(graph) => {
graph.cards.forEach((settings:any) => {
if (this.MODE != graph.requestMode) return;
this.http.get(`${graph.endpoint}${settings.params}&before=${settings.before}&after=${settings.after}&${this.NUM == 0?'':('&nums='+this.NUM)}${devicesToRequest()}`)
.subscribe((data) => {
settings.config.data = {
labels: [],
datasets: [
{
label: settings.canvasId,
data: [],
backgroundColor: []
}
]
};
(data as Object[]).map((obj) => PacketGroup.fromDto(obj)).sort((p1, p2) => p2.count - p1.count).forEach(
(d) => {
switch (graph.type) {
case "perPortNum":
case "packetsPerNode":{
settings.config.data.labels.push(`${d.portnumName} - ${d.count}`)
settings.config.data.datasets[0].data.push(d.count)
settings.config.data.datasets[0].backgroundColor.push(numToColor(d.portnum, 0))
break;
}
case "perSumNode": {
const name = `${d.from}` in this.nodesNames ? this.nodesNames[`${d.from}`].long_name : `${d.from}`
settings.config.data.labels.push(`${name} - ${d.count}`)
settings.config.data.datasets[0].data.push(d.count)
settings.config.data.datasets[0].backgroundColor.push(numToColor(d.from, 0))
break;
}
default: {
console.log("missing type: " + graph.type);
break;
}
}
}
)
if (settings.chart)
settings.chart.destroy()
settings.chart = new Chart(settings.canvasId, settings.config)
})
})
}
)
}
}