From b21d28e39ce52e0bfa0340b16b4531e624a1e53f Mon Sep 17 00:00:00 2001 From: gsd Date: Thu, 12 Feb 2026 23:31:08 +0300 Subject: [PATCH] packet stats per node --- ui/src/app/app.module.ts | 7 +- .../packet/NetworkStatus.component.ts | 105 ++++++++++++++---- ui/src/app/entities/PacketSignalDTO.ts | 8 ++ 3 files changed, 99 insertions(+), 21 deletions(-) create mode 100644 ui/src/app/entities/PacketSignalDTO.ts diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts index a89d904..04e02a0 100644 --- a/ui/src/app/app.module.ts +++ b/ui/src/app/app.module.ts @@ -23,6 +23,8 @@ import {MatDividerModule} from "@angular/material/divider"; import {MatCardModule} from "@angular/material/card"; import {MatSelectModule} from "@angular/material/select"; import {NetworkStatusComponent} from "./components/packet/NetworkStatus.component"; +import {MatRadioModule} from "@angular/material/radio"; +import {DatePipe} from "@angular/common"; @NgModule({ declarations: [ @@ -53,13 +55,14 @@ import {NetworkStatusComponent} from "./components/packet/NetworkStatus.componen MatCardModule, NodeDtoSortPipe, MatSelectModule, - NodeDtoSearchPipe + NodeDtoSearchPipe, + MatRadioModule ], providers: [{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true - }], + }, DatePipe], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/ui/src/app/components/packet/NetworkStatus.component.ts b/ui/src/app/components/packet/NetworkStatus.component.ts index 023ecc7..d3e3a70 100644 --- a/ui/src/app/components/packet/NetworkStatus.component.ts +++ b/ui/src/app/components/packet/NetworkStatus.component.ts @@ -6,15 +6,33 @@ import {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}} + + +
+
@@ -34,13 +52,21 @@ export class NetworkStatusComponent implements OnInit { 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 route: ActivatedRoute, + private datepipe: DatePipe) {} getNumName(num:number) { if (`${num}` in this.nodesNames) @@ -54,22 +80,23 @@ export class NetworkStatusComponent implements OnInit { header: "Cтатистика пакетов в сети", type: 'perPortNum', requestMode: "ALL", + endpoint:"api/packet/stats", cards:[{ - chart: Chart, + 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: Chart, + 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: Chart, + chart: null as unknown as Chart, canvasId: "MonthPerPB", params: "?=", before: new Date().getTime()/1000, @@ -81,22 +108,23 @@ export class NetworkStatusComponent implements OnInit { header: "Общая статистика пакетов в сети", type: 'perSumNode', requestMode: "ALL", + endpoint:"api/packet/stats", cards:[{ - chart: Chart, + 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: Chart, + 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: Chart, + chart: null as unknown as Chart, canvasId: "MonthSumPB", params: "?packetsSumNode=true", before: new Date().getTime()/1000, @@ -107,22 +135,23 @@ export class NetworkStatusComponent implements OnInit { header: "Cтатистика пакетов в сети", type: 'packetsPerNode', requestMode: "NODE", + endpoint:"api/packet/stats", cards:[{ - chart: Chart, + 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: Chart, + 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: Chart, + chart: null as unknown as Chart, canvasId: "MonthPerNodePB", params: "?packetsPerNode=true", before: new Date().getTime()/1000, @@ -133,10 +162,13 @@ export class NetworkStatusComponent implements OnInit { ] } - generateConfigTChart(name: string, legend: boolean = true) { + generateConfigTChart(name: string, legend: boolean = true, type: string = "pie") { return { - type: 'pie', - data: {}, + type: type, + data: { + labels: [] as any[], + datasets: [] as any[] + }, options: { responsive: true, plugins: { @@ -157,7 +189,6 @@ export class NetworkStatusComponent implements OnInit { this.route.params.subscribe( (params) => { const num: number = Number.parseInt(params["num"]); - console.log(num); switch (num) { case 0: { this.MODE = "ALL"; @@ -190,6 +221,7 @@ export class NetworkStatusComponent implements OnInit { () => { this.graphs = this.generateGraps(); this.updateGraphs(); + this.updateSignalGraph(); } ) break; @@ -198,12 +230,48 @@ export class NetworkStatusComponent implements OnInit { }) } + 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}`).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(`api/packet/stats${settings.params}&before=${settings.before}&after=${settings.after}&${this.NUM == 0?'':('&nums='+this.NUM)}`) + this.http.get(`${graph.endpoint}${settings.params}&before=${settings.before}&after=${settings.after}&${this.NUM == 0?'':('&nums='+this.NUM)}`) .subscribe((data) => { settings.config.data = { labels: [], @@ -239,9 +307,8 @@ export class NetworkStatusComponent implements OnInit { } } ) - //if (settings.chart) - // settings.chart.destroy() - + if (settings.chart) + settings.chart.destroy() settings.chart = new Chart(settings.canvasId, settings.config) }) }) diff --git a/ui/src/app/entities/PacketSignalDTO.ts b/ui/src/app/entities/PacketSignalDTO.ts new file mode 100644 index 0000000..27574ba --- /dev/null +++ b/ui/src/app/entities/PacketSignalDTO.ts @@ -0,0 +1,8 @@ +export interface PacketSignalDTO { + from: number, + rx_snr: number, + rx_rssi: number, + ts: number, + hop_start: number, + hop_limit: number +}