Implement storing + display duty-cycle stats.

Note that these stats are only available for Concentratord based
gateways as these metrics must be aggregated by the gateway.
This commit is contained in:
Orne Brocaar
2024-04-17 14:34:11 +01:00
parent 2889da37c2
commit a5ff416fa2
23 changed files with 1012 additions and 201 deletions

View File

@ -3,6 +3,7 @@ import { Card } from "antd";
import { TimeUnit } from "chart.js";
import { Bar } from "react-chartjs-2";
import moment from "moment";
import palette from "google-palette";
import { Metric, Aggregation } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
@ -19,24 +20,6 @@ function MetricBar(props: IProps) {
unit = "month";
}
let backgroundColors = [
"#8bc34a",
"#ff5722",
"#ff9800",
"#ffc107",
"#ffeb3b",
"#cddc39",
"#4caf50",
"#009688",
"#00bcd4",
"#03a9f4",
"#2196f3",
"#3f51b5",
"#673ab7",
"#9c27b0",
"#e91e63",
];
const animation: false = false;
const options = {
@ -72,13 +55,13 @@ function MetricBar(props: IProps) {
datasets: [],
};
for (let ds of props.metric.getDatasetsList()) {
props.metric.getDatasetsList().forEach((ds, i) => {
data.datasets.push({
label: ds.getLabel(),
data: ds.getDataList(),
backgroundColor: backgroundColors.shift()!,
backgroundColor: palette("cb-Paired", props.metric.getDatasetsList().length).map((hex: string) => "#" + hex)[i],
});
}
});
return (
<Card title={props.metric.getName()} className="dashboard-chart">

View File

@ -3,6 +3,7 @@ import { Card } from "antd";
import { TimeUnit } from "chart.js";
import { Line } from "react-chartjs-2";
import moment from "moment";
import palette from "google-palette";
import { Metric, Aggregation, MetricKind } from "@chirpstack/chirpstack-api-grpc-web/common/common_pb";
@ -21,6 +22,9 @@ function MetricChart(props: IProps) {
} else if (props.aggregation === Aggregation.MONTH) {
unit = "month";
tooltipFormat = "MMM YYYY";
} else if (props.aggregation === Aggregation.MINUTE) {
unit = "minute";
tooltipFormat = "LT";
}
const animation: false = false;
@ -50,31 +54,37 @@ function MetricChart(props: IProps) {
let prevValue = 0;
let data = {
labels: props.metric.getTimestampsList().map(v => moment(v.toDate()).valueOf()),
datasets: props.metric.getDatasetsList().map(v => {
return {
label: v.getLabel(),
borderColor: "rgba(33, 150, 243, 1)",
backgroundColor: "rgba(0, 0, 0, 0)",
lineTension: 0,
pointBackgroundColor: "rgba(33, 150, 243, 1)",
data: v.getDataList().map(v => {
if (v === 0 && props.zeroToNull) {
return null;
} else {
if (props.metric.getKind() === MetricKind.COUNTER) {
let val = v - prevValue;
prevValue = v;
if (val < 0) {
return 0;
}
return val;
datasets: props.metric
.getDatasetsList()
.sort((a, b) => a.getLabel().localeCompare(b.getLabel()))
.map((v, i) => {
const colors = palette("cb-Paired", props.metric.getDatasetsList().length).map((hex: string) => "#" + hex);
console.log(v.getLabel());
console.log(colors[i]);
return {
label: v.getLabel(),
borderColor: colors[i],
pointBackgroundColor: colors[i],
lineTension: 0,
data: v.getDataList().map(v => {
if (v === 0 && props.zeroToNull) {
return null;
} else {
return v;
if (props.metric.getKind() === MetricKind.COUNTER) {
let val = v - prevValue;
prevValue = v;
if (val < 0) {
return 0;
}
return val;
} else {
return v;
}
}
}
}),
};
}),
}),
};
}),
};
let name = props.metric.getName();