From 84697743c1718b09bc9b6ff570a13c6f9cfe8599 Mon Sep 17 00:00:00 2001
From: Sina Blattmann
Date: Mon, 26 Jun 2023 11:36:14 +0200
Subject: [PATCH] [WIP] bugfixing for graphs
---
.../src/components/Installations/Alarms.tsx | 11 ---
.../Installations/InstallationList.tsx | 2 +-
.../Installations/InstallationTabs.tsx | 14 +--
.../Installations/Installations.tsx | 4 +-
.../src/components/Installations/LiveView.tsx | 7 ++
.../Installations/Log/DateRangePicker.tsx | 9 +-
.../src/components/Installations/Log/Log.tsx | 2 -
.../Installations/Log/ScalarGraph.tsx | 43 +++++++---
.../Installations/Log/ShortcutButton.tsx | 18 ++--
.../Installations/Log/TopologyBox.tsx | 17 +++-
.../Installations/Log/TopologyFlow.tsx | 14 ++-
.../Installations/Log/TopologyView.tsx | 79 ++++++++++++-----
typescript/Frontend/src/lang/de.json | 2 +-
typescript/Frontend/src/lang/en.json | 2 +-
typescript/Frontend/src/routes.json | 2 +-
typescript/Frontend/src/util/graph.util.tsx | 85 ++++++++++++++++---
16 files changed, 214 insertions(+), 97 deletions(-)
delete mode 100644 typescript/Frontend/src/components/Installations/Alarms.tsx
create mode 100644 typescript/Frontend/src/components/Installations/LiveView.tsx
diff --git a/typescript/Frontend/src/components/Installations/Alarms.tsx b/typescript/Frontend/src/components/Installations/Alarms.tsx
deleted file mode 100644
index fce927204..000000000
--- a/typescript/Frontend/src/components/Installations/Alarms.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { FormattedMessage } from "react-intl";
-
-const Alarms = () => {
- return (
-
-
-
- );
-};
-
-export default Alarms;
diff --git a/typescript/Frontend/src/components/Installations/InstallationList.tsx b/typescript/Frontend/src/components/Installations/InstallationList.tsx
index 79679e51e..77673bbab 100644
--- a/typescript/Frontend/src/components/Installations/InstallationList.tsx
+++ b/typescript/Frontend/src/components/Installations/InstallationList.tsx
@@ -42,7 +42,7 @@ const InstallationList = (props: InstallationListProps) => {
const routeMatch = useRouteMatch([
routes.installations + routes.list + routes.installation + ":id",
- routes.installations + routes.list + routes.alarms + ":id",
+ routes.installations + routes.list + routes.liveView + ":id",
routes.installations + routes.list + routes.log + ":id",
]);
diff --git a/typescript/Frontend/src/components/Installations/InstallationTabs.tsx b/typescript/Frontend/src/components/Installations/InstallationTabs.tsx
index ea7db5818..0d20be0b5 100644
--- a/typescript/Frontend/src/components/Installations/InstallationTabs.tsx
+++ b/typescript/Frontend/src/components/Installations/InstallationTabs.tsx
@@ -9,7 +9,7 @@ import { AntTabs, StyledTab } from "../../util/installation.util";
const InstallationTabs = () => {
const routeMatch = useRouteMatch([
routes.installations + routes.list + routes.installation + ":id",
- routes.installations + routes.list + routes.alarms + ":id",
+ routes.installations + routes.list + routes.liveView + ":id",
routes.installations + routes.list + routes.log + ":id",
]);
@@ -40,14 +40,16 @@ const InstallationTabs = () => {
to={routes.installation + id}
/>
{
element={}
index
/>
- } />
+ } />
} />
diff --git a/typescript/Frontend/src/components/Installations/LiveView.tsx b/typescript/Frontend/src/components/Installations/LiveView.tsx
new file mode 100644
index 000000000..7d01b20e7
--- /dev/null
+++ b/typescript/Frontend/src/components/Installations/LiveView.tsx
@@ -0,0 +1,7 @@
+import TopologyView from "./Log/TopologyView";
+
+const LiveView = () => {
+ return ;
+};
+
+export default LiveView;
diff --git a/typescript/Frontend/src/components/Installations/Log/DateRangePicker.tsx b/typescript/Frontend/src/components/Installations/Log/DateRangePicker.tsx
index 329457d3c..8c6971914 100644
--- a/typescript/Frontend/src/components/Installations/Log/DateRangePicker.tsx
+++ b/typescript/Frontend/src/components/Installations/Log/DateRangePicker.tsx
@@ -10,7 +10,7 @@ import { TimeRange, UnixTime } from "../../../dataCache/time";
interface DateRangePickerProps {
setRange: (value: Date[]) => void;
range: Date[];
- getCacheSeries: (xaxisRange0: number, xaxisRange1: number) => void;
+ getCacheSeries: (xaxisRange0: Date, xaxisRange1: Date) => void;
}
const DateRangePicker = (props: DateRangePickerProps) => {
const { setRange, range, getCacheSeries } = props;
@@ -23,8 +23,11 @@ const DateRangePicker = (props: DateRangePickerProps) => {
),
100
);
- setRange([timeRange[0].toDate(), timeRange[timeRange.length - 1].toDate()]);
- getCacheSeries(timeRange[0].ticks, timeRange[timeRange.length - 1].ticks);
+ const timeRange0 = timeRange[0].toDate();
+ const timeRange1 = timeRange[timeRange.length - 1].toDate();
+
+ setRange([timeRange0, timeRange1]);
+ getCacheSeries(timeRange0, timeRange1);
};
return (
diff --git a/typescript/Frontend/src/components/Installations/Log/Log.tsx b/typescript/Frontend/src/components/Installations/Log/Log.tsx
index 93517caab..d1156f14e 100644
--- a/typescript/Frontend/src/components/Installations/Log/Log.tsx
+++ b/typescript/Frontend/src/components/Installations/Log/Log.tsx
@@ -1,11 +1,9 @@
import React from "react";
import ScalarGraph from "./ScalarGraph";
-import TopologyView from "./TopologyView";
const Log = () => {
return (
<>
-
>
);
diff --git a/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx b/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx
index d43f46f72..156227f3e 100644
--- a/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx
+++ b/typescript/Frontend/src/components/Installations/Log/ScalarGraph.tsx
@@ -491,6 +491,7 @@ const s3Access = new S3Access(
"f2KtCWN4EHFqtvH2kotdyI0w5SjjdHVPAADdcD3ik8g",
""
);
+
export const fetchData = (
timestamp: UnixTime
): Promise> => {
@@ -516,7 +517,7 @@ export const fetchData = (
const ScalarGraph = () => {
const timeRange = createTimes(
UnixTime.now() /* .fromTicks(1682085650) */
- .rangeBefore(TimeSpan.fromHours(5)),
+ .rangeBefore(TimeSpan.fromDays(1)),
NUMBER_OF_NODES
);
const [timeSeries, setTimeSeries] = useState([]);
@@ -596,11 +597,11 @@ const ScalarGraph = () => {
);
};
- const getCacheSeries = (xaxisRange0: number, xaxisRange1: number) => {
+ const getCacheSeries = (xaxisRange0: Date, xaxisRange1: Date) => {
const times = createTimes(
TimeRange.fromTimes(
- UnixTime.fromTicks(xaxisRange0),
- UnixTime.fromTicks(xaxisRange1)
+ UnixTime.fromDate(xaxisRange0),
+ UnixTime.fromDate(xaxisRange1)
),
NUMBER_OF_NODES
);
@@ -661,14 +662,29 @@ const ScalarGraph = () => {
"autoScale2d",
],
}}
+ onUpdate={(params) => {
+ console.log("event onupdate", params);
+ }}
+ onSliderChange={(params) => {
+ console.log("event sliderchange", params);
+ }}
+ onRestyle={(params) => {
+ console.log("event restyle", params);
+ }}
onRelayout={(params) => {
+ console.log("event relayout", params);
+
const xaxisRange0 = params["xaxis.range[0]"];
const xaxisRange1 = params["xaxis.range[1]"];
-
+ console.log("relayout", xaxisRange0, xaxisRange1);
if (xaxisRange0 && xaxisRange1) {
- setRange([new Date(xaxisRange0), new Date(xaxisRange1)]);
+ console.log("relayout", xaxisRange0, xaxisRange1);
+ const range0 = new Date(xaxisRange0);
+ const range1 = new Date(xaxisRange1);
+
+ setRange([range0, range1]);
setUiRevision(Math.random());
- getCacheSeries(xaxisRange0, xaxisRange1);
+ getCacheSeries(range0, range1);
}
}}
/>
@@ -680,13 +696,13 @@ const ScalarGraph = () => {
if (
checkedToggles &&
- Object.keys(checkedToggles).find((toggle) => checkedToggles[toggle])
+ Object.keys(checkedToggles).find((toggle) => {
+ return checkedToggles[toggle];
+ })
) {
- console.log("timeseries", timeSeries);
const coordinateTimeSeries = transformToGraphData(timeSeries);
- console.log("timeSeries", timeSeries);
return (
- <>
+
{
itemCount={
Object.keys(checkedToggles).filter(
(toggle) => checkedToggles[toggle]
- ).length
+ ).length - 1
}
itemSize={() => 500}
width="100%"
@@ -707,9 +723,10 @@ const ScalarGraph = () => {
>
{Row}
- >
+
);
}
+
return (
void;
- getCacheSeries: (xaxisRange0: number, xaxisRange1: number) => void;
+ getCacheSeries: (xaxisRange0: Date, xaxisRange1: Date) => void;
dayRange: number;
children?: React.ReactNode;
}
@@ -13,19 +13,15 @@ const ShortcutButton = (props: ShortcutButtonProps) => {
return (
{
- const weekRange = createTimes(
+ const range = createTimes(
UnixTime.now().rangeBefore(TimeSpan.fromDays(props.dayRange)),
100
);
- console.log("weekrange", weekRange[0].ticks);
- props.setRange([
- weekRange[0].toDate(),
- weekRange[weekRange.length - 1].toDate(),
- ]);
- props.getCacheSeries(
- weekRange[0].ticks,
- weekRange[weekRange.length - 1].ticks
- );
+ const range0 = range[0].toDate();
+ const range1 = range[range.length - 1].toDate();
+
+ props.setRange([range0, range1]);
+ props.getCacheSeries(range0, range1);
}}
sx={{ mt: 2, mb: 2, mr: 2 }}
>
diff --git a/typescript/Frontend/src/components/Installations/Log/TopologyBox.tsx b/typescript/Frontend/src/components/Installations/Log/TopologyBox.tsx
index 541a5a0e4..c73b9e3ea 100644
--- a/typescript/Frontend/src/components/Installations/Log/TopologyBox.tsx
+++ b/typescript/Frontend/src/components/Installations/Log/TopologyBox.tsx
@@ -1,4 +1,5 @@
import { Box } from "@mui/material";
+import { getBoxColor } from "../../../util/graph.util";
export type BoxData = {
label: string;
@@ -17,6 +18,8 @@ const isInt = (value: number) => {
export const BOX_SIZE = 85;
const TopologyBox = (props: TopologyBoxProps) => {
+ const { titleColor, boxColor } = getBoxColor(props.title);
+ if (props.title === "Battery") console.log(props.data?.values, "data");
return (
{
style={{
marginBlockStart: "0",
marginBlockEnd: "0",
- backgroundColor: "#e74c3c",
+ backgroundColor: titleColor,
padding: "5px",
borderTopLeftRadius: "4px",
borderTopRightRadius: "4px",
+ display: "flex",
+ justifyContent: "center",
}}
>
{props.title}
{props.data && (
<>
- {props.data.values.map((value) => {
+ {props.data.values.map((value, index) => {
return (
{`${
+ props.data && props.data.values.length === 3
+ ? "L" + (index + 1) + " "
+ : ""
+ }${
!isInt(Number(value)) ? Number(value).toPrecision(4) : value
}${props.data?.unit}`}
);
diff --git a/typescript/Frontend/src/components/Installations/Log/TopologyFlow.tsx b/typescript/Frontend/src/components/Installations/Log/TopologyFlow.tsx
index 7de1442c6..d3def8fb3 100644
--- a/typescript/Frontend/src/components/Installations/Log/TopologyFlow.tsx
+++ b/typescript/Frontend/src/components/Installations/Log/TopologyFlow.tsx
@@ -9,6 +9,7 @@ export type TopologyFlowProps = {
hidden?: boolean;
};
const TopologyFlow = (props: TopologyFlowProps) => {
+ console.log("amount", props.amount, props.data?.values);
const length = Math.abs((props.amount ?? 1) * BOX_SIZE);
const values = props.data?.values;
return (
@@ -25,7 +26,7 @@ const TopologyFlow = (props: TopologyFlowProps) => {
sx={{
width: props.orientation === "horizontal" ? BOX_SIZE : length,
height: props.orientation === "vertical" ? BOX_SIZE : length,
- backgroundColor: "#f4b3504d",
+ backgroundColor: "#FFEBCD",
visibility: props.hidden || !props.data ? "hidden" : "visible",
display: "flex",
alignItems: "center",
@@ -37,11 +38,16 @@ const TopologyFlow = (props: TopologyFlowProps) => {
style={{
position: "absolute",
zIndex: 1,
+ width: BOX_SIZE,
+ display: "flex",
+ justifyContent: "center",
}}
>
- {values?.map(
- (value) => `${Math.round(value as number)} ${props.data?.unit}`
- )}
+ {values
+ ?.filter((value) => (value as number) !== 0)
+ .map(
+ (value) => `${Math.round(value as number)} ${props.data?.unit}`
+ )}
{
const [values, setValues] = useState
(null);
@@ -31,7 +32,7 @@ const TopologyView = () => {
);
}
})
- .catch((err) => console.log(err));
+ .catch((err) => console.error(err));
}, 2000);
return () => clearInterval(interval);
@@ -66,12 +67,15 @@ const TopologyView = () => {
{
data: values.gridBusToPvOnGridbusConnection,
}}
topBox={{
- title: "PvOnGridBus",
+ title: "Pv",
}}
bottomConnection={{
amount: getAmount(
@@ -91,22 +95,35 @@ const TopologyView = () => {
data: values.gridBusToLoadOnGridBusConnection,
}}
bottomBox={{
- title: "LoadOnGridBus",
+ title: "Load",
}}
/>
{
{
data: values.dcBusToDcDcConnection,
}}
bottomConnection={{
- amount: 0.2,
+ amount: getAmount(
+ highestConnectionValue,
+ values.dcBusToLoadOnDcConnection.values
+ ),
data: values.dcBusToLoadOnDcConnection,
}}
bottomBox={{
- title: "LoadOnDc",
+ title: "Load",
}}
/>
@@ -162,7 +188,7 @@ const TopologyView = () => {
{
);
}
- return null;
+ return (
+
+
+
+ );
};
export default TopologyView;
diff --git a/typescript/Frontend/src/lang/de.json b/typescript/Frontend/src/lang/de.json
index 037eeab43..295b87a34 100644
--- a/typescript/Frontend/src/lang/de.json
+++ b/typescript/Frontend/src/lang/de.json
@@ -1,5 +1,5 @@
{
- "alarms": "Alarme",
+ "liveView": "Live Ansicht",
"allInstallations": "Alle Installationen",
"applyChanges": "Änderungen übernehmen",
"country": "Land",
diff --git a/typescript/Frontend/src/lang/en.json b/typescript/Frontend/src/lang/en.json
index aabb7b8fe..3cbbc6634 100644
--- a/typescript/Frontend/src/lang/en.json
+++ b/typescript/Frontend/src/lang/en.json
@@ -1,5 +1,5 @@
{
- "alarms": "Alarms",
+ "liveView": "Live view",
"allInstallations": "All installations",
"applyChanges": "Apply changes",
"country": "Country",
diff --git a/typescript/Frontend/src/routes.json b/typescript/Frontend/src/routes.json
index 27947ff1b..f2ec5fff1 100644
--- a/typescript/Frontend/src/routes.json
+++ b/typescript/Frontend/src/routes.json
@@ -1,6 +1,6 @@
{
"installation": "installation/",
- "alarms": "alarms/",
+ "liveView": "liveView/",
"users": "/users/",
"log": "log/",
"installations": "/installations/",
diff --git a/typescript/Frontend/src/util/graph.util.tsx b/typescript/Frontend/src/util/graph.util.tsx
index a2e52162c..1693e21c7 100644
--- a/typescript/Frontend/src/util/graph.util.tsx
+++ b/typescript/Frontend/src/util/graph.util.tsx
@@ -48,17 +48,28 @@ export type TopologyValues = {
islandBusToLoadOnIslandBusConnection: BoxData;
gridBusToPvOnGridbusConnection: BoxData;
gridBusToLoadOnGridBusConnection: BoxData;
+ inverter: BoxData;
+ dcDc: BoxData;
+ islandBusToInverter: BoxData;
+ inverterToDcBus: BoxData;
+ gridBusToIslandBusConnection: BoxData;
+ pvOnDcBusToDcBusConnection: BoxData;
+ pvOnIslandBusToIslandBusConnection: BoxData;
};
type TopologyPaths = { [key in keyof TopologyValues]: string[] };
export const topologyPaths: TopologyPaths = {
gridToAcInConnection: [
- "/GridMeter/Ac/L1/Power/Apparent",
- "/GridMeter/Ac/L2/Power/Apparent",
- "/GridMeter/Ac/L3/Power/Apparent",
+ "/GridMeter/Ac/L1/Power/Active",
+ "/GridMeter/Ac/L2/Power/Active",
+ "/GridMeter/Ac/L3/Power/Active",
+ ],
+ gridBus: [
+ "/GridMeter/Ac/L1/Voltage",
+ "/GridMeter/Ac/L2/Voltage",
+ "/GridMeter/Ac/L3/Voltage",
],
- gridBus: ["/GridMeter/Ac/L2/Voltage"],
islandBus: [
"/AcDc/Ac/L1/Voltage",
"/AcDc/Ac/L2/Voltage",
@@ -69,12 +80,58 @@ export const topologyPaths: TopologyPaths = {
dcDCToBatteryConnection: ["/DcDc/Dc/Battery/Power"],
battery: ["/Battery/Soc", "/Battery/Dc/Voltage"],
dcBusToLoadOnDcConnection: ["/LoadOnDc/Power"],
- islandBusToLoadOnIslandBusConnection: ["/LoadOnAcIsland/Ac/Power/Apparent"],
- gridBusToPvOnGridbusConnection: ["/PvOnAcGrid/Power/Apparent"],
- gridBusToLoadOnGridBusConnection: ["/LoadOnAcGrid/Power/Apparent"],
+ islandBusToLoadOnIslandBusConnection: ["/LoadOnAcIsland/Ac/Power/Active"],
+ gridBusToPvOnGridbusConnection: ["/PvOnAcGrid/Power/Active"],
+ gridBusToLoadOnGridBusConnection: ["/LoadOnAcGrid/Power/Active"],
+ inverter: ["/AcDc/Devices/1/Status/Ac/Power/Active"],
+ dcDc: ["/DcDc/Devices/1/Status/Dc/Battery/Voltage"],
+ islandBusToInverter: ["/AcDc/Ac/Power/Active"],
+ inverterToDcBus: ["/AcDc/Dc/Power"],
+ gridBusToIslandBusConnection: ["/AcGridToAcIsland/Power/Active"],
+ pvOnDcBusToDcBusConnection: ["/PvOnDc/Dc/Power"],
+ pvOnIslandBusToIslandBusConnection: ["/PvOnAcIsland/Power/Active"],
};
-const getBoxColor = () => {};
+interface BoxColor {
+ titleColor: string;
+ boxColor: string;
+}
+export const getBoxColor = (boxTitle?: string): BoxColor => {
+ switch (boxTitle) {
+ case "Grid":
+ return {
+ titleColor: "#e74c3c",
+ boxColor: "#c0392b",
+ };
+ case "Island Bus":
+ case "Grid Bus":
+ return {
+ titleColor: "#adadad",
+ boxColor: "#8e8e8e",
+ };
+ case "Inverter":
+ return {
+ titleColor: "#4789d0",
+ boxColor: "#4789d0",
+ };
+ case "Pv":
+ return {
+ titleColor: "#f4b350",
+ boxColor: "#f39c12",
+ };
+
+ case "Load":
+ return {
+ titleColor: "#2ecc71",
+ boxColor: "#27ae60",
+ };
+ default:
+ return {
+ titleColor: "#e74c3c",
+ boxColor: "#c0392b",
+ };
+ }
+};
export const extractTopologyValues = (
timeSeriesData: DataPoint
@@ -86,7 +143,7 @@ export const extractTopologyValues = (
const values = topologyPaths[topologyKey as keyof TopologyValues].map(
(topologyPath) => timeSeriesValue[topologyPath]
);
- console.log("AAA", topologyKey);
+ console.log("values", values, topologyKey);
switch (topologyKey as keyof TopologyValues) {
case "gridToAcInConnection":
topologyValues = [
@@ -94,7 +151,7 @@ export const extractTopologyValues = (
];
break;
default:
- topologyValues = values.map(({ value }) => value);
+ topologyValues = values.map((element) => element.value);
}
console.log("topologyValues", topologyValues);
return {
@@ -116,8 +173,9 @@ export const getHighestConnectionValue = (values: TopologyValues) =>
Object.keys(values)
.filter((value) => value.includes("Connection"))
.reduce((acc, curr) => {
- const value = values[curr as keyof TopologyValues].values[0] as number;
- console.log("reduce", value, acc);
+ const value = Math.abs(
+ values[curr as keyof TopologyValues].values[0] as number
+ );
return value > acc ? value : acc;
}, 0);
@@ -125,8 +183,7 @@ export const getAmount = (
highestConnectionValue: number,
values: (string | number)[]
) => {
- console.log("amount", values[0] as number, highestConnectionValue);
- return (values[0] as number) / highestConnectionValue;
+ return Math.abs(values[0] as number) / highestConnectionValue;
};
export interface CsvEntry {