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)}} в сети

За день За неделю За месяц {{signalChart}}
{{p1.chart}}
` }) 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) }) }) } ) } }