[WIP] adjustments to topology

This commit is contained in:
Sina Blattmann 2023-06-13 09:27:56 +02:00
parent a9d95fd71e
commit 3a4c768074
10 changed files with 206 additions and 135 deletions

View File

@ -4,7 +4,6 @@ import { UnixTime, TimeSpan } from "../../../dataCache/time";
import { createTimes } from "../../../util/graph.util";
import {
DatePicker,
DateTimePicker,
DateTimeValidationError,
LocalizationProvider,
} from "@mui/x-date-pickers";

View File

@ -1,101 +1,14 @@
import React from "react";
import ScalarGraph, { testData } from "./ScalarGraph";
import TopologyColumn from "./TopologyColumn";
import { Box } from "@mui/material";
import { extractTopologyValues, parseCsv } from "../../../util/graph.util";
import { UnixTime } from "../../../dataCache/time";
import ScalarGraph from "./ScalarGraph";
import TopologyView from "./TopologyView";
const Log = () => {
const values = extractTopologyValues({
time: UnixTime.fromTicks(192384239),
value: parseCsv(testData),
});
if (values) {
return (
<>
<Box
sx={{
display: "flex",
flexDirection: "row",
width: "1000px",
overflow: "auto",
padding: 2,
}}
>
<div>
<TopologyColumn
centerBox={{
title: "Grid",
data: values.acInBus,
connectionData: values.gridToAcIn,
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "AcInBus",
data: values.acInBus,
connectionData: values.dcBusToDcDc,
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "AcOutBus",
data: values.acOutBus,
connectionData: values.dcBusToDcDc,
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "Inverter",
data: values.acOutBus,
connectionData: values.dcBusToDcDc,
}}
/>
</div>
<div>
<TopologyColumn
topBox={{
title: "MPPT",
data: values.acOutBus,
connectionData: values.mpptToDcBus,
}}
centerBox={{
title: "DcBus",
data: values.acOutBus,
connectionData: values.dcBusToDcDc,
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "DcDc",
data: values.acOutBus,
connectionData: values.dcDCToBattery,
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "Battery",
data: values.acOutBus,
}}
/>
</div>
</Box>
<TopologyView />
<ScalarGraph />
</>
);
}
return null;
};
export default Log;

View File

@ -641,6 +641,7 @@ const ScalarGraph = () => {
layout={{
width: 1000,
height: 500,
autosize: true,
title: visibleGraphs[index],
uirevision: uiRevision,
xaxis: {
@ -781,7 +782,7 @@ const ScalarGraph = () => {
.length
}
itemSize={() => 500}
width={1000}
width="100%"
itemData={coordinateTimeSeries}
>
{Row}

View File

@ -9,12 +9,14 @@ export type BoxData = {
export type TopologyBoxProps = {
title?: string;
data?: BoxData[];
connectionData?: BoxData[];
};
const isInt = (value: number) => {
return value % 1 === 0;
};
export const BOX_SIZE = 150;
const TopologyBox = (props: TopologyBoxProps) => {
console.log("boxdata", props.data);
return (
<Box
sx={{
@ -26,10 +28,22 @@ const TopologyBox = (props: TopologyBoxProps) => {
}}
>
<Box sx={{ padding: "5px" }}>
{props.title}
<p style={{ marginBlockStart: "2px" }}>{props.title}</p>
{props.data &&
props.data.map((el) => (
<p>{`${el.label} ${el.values} ${el.unit}`}</p>
<div>
{el.label}
{el.values.map((value) => {
return (
<p
style={{ marginBlockStart: "2px", marginBlockEnd: "2px" }}
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
>{`${
!isInt(Number(value)) ? Number(value).toPrecision(8) : value
}${el.unit}`}</p>
);
})}
</div>
))}
</Box>
</Box>

View File

@ -1,12 +1,16 @@
import { Box } from "@mui/material";
import TopologyBox, { TopologyBoxProps } from "./ToplogyBox";
import TopologyFlow from "./TopologyFlow";
import TopologyFlow, { TopologyFlowProps } from "./TopologyFlow";
type TopologyColumnProps = {
topBox?: TopologyBoxProps;
topConnection?: TopologyFlowProps;
centerBox?: TopologyBoxProps;
centerConnection?: TopologyFlowProps;
bottomBox?: TopologyBoxProps;
bottomConnection?: TopologyFlowProps;
};
const TopologyColumn = (props: TopologyColumnProps) => {
return (
<Box
@ -21,26 +25,23 @@ const TopologyColumn = (props: TopologyColumnProps) => {
<div>
<TopologyBox {...props.topBox} />
<TopologyFlow
{...props.topConnection}
orientation="vertical"
amount={0.5}
hidden={!props.topBox}
data={props.topBox?.connectionData}
/>
<TopologyBox {...props.centerBox} />
<TopologyFlow
{...props.bottomConnection}
orientation="vertical"
amount={0.7}
hidden={!props.bottomBox}
data={props.bottomBox?.connectionData}
/>
<TopologyBox {...props.bottomBox} />
</div>
<div>
<TopologyFlow
{...props.centerConnection}
orientation="horizontal"
amount={0.1}
hidden={!props.centerBox}
data={props.centerBox?.connectionData}
/>
</div>
</Box>

View File

@ -9,8 +9,8 @@
.container {
position: relative;
width: 150px;
height: 150px;
width: 130px;
height: 130px;
overflow: hidden;
}

View File

@ -2,30 +2,35 @@ import { Box } from "@mui/material";
import { BOX_SIZE, BoxData } from "./ToplogyBox";
import "./TopologyFlow.scss";
type TopologyFlowProps = {
orientation: "vertical" | "horizontal";
amount: number;
export type TopologyFlowProps = {
orientation?: "vertical" | "horizontal";
amount?: number;
direction?: "leftToRight" | "rightToLeft";
data?: BoxData[];
hidden?: boolean;
};
const TopologyFlow = (props: TopologyFlowProps) => {
const length = Math.abs(props.amount * BOX_SIZE);
console.log("props", props.data);
const length = Math.abs((props.amount ?? 1) * (BOX_SIZE - 20));
return (
<>
{props.data?.map((value) => value.values)}
<Box
sx={{
width: props.orientation === "horizontal" ? BOX_SIZE : length,
height: props.orientation === "vertical" ? BOX_SIZE : length,
backgroundColor: "grey",
width: props.orientation === "horizontal" ? BOX_SIZE - 20 : length,
height: props.orientation === "vertical" ? BOX_SIZE - 20 : length,
backgroundColor: "#f4b3504d",
visibility: props.hidden || !props.data ? "hidden" : "visible",
}}
>
{props.data?.map((value) => value.values)}
<div
className="container"
style={{
transform: props.orientation === "vertical" ? "rotate(90deg)" : "",
transform:
props.orientation === "vertical"
? "rotate(90deg)"
: props.direction === "rightToLeft"
? "rotate(180deg)"
: "",
}}
>
<div className="data-flow">

View File

@ -0,0 +1,122 @@
import { Box } from "@mui/material";
import TopologyColumn from "./TopologyColumn";
import { UnixTime } from "../../../dataCache/time";
import { extractTopologyValues, parseCsv } from "../../../util/graph.util";
import { testData } from "./ScalarGraph";
const TopologyView = () => {
const values = extractTopologyValues({
time: UnixTime.fromTicks(192384239),
value: parseCsv(testData),
});
console.log("csvValue", parseCsv(testData));
if (values) {
return (
<Box
sx={{
display: "flex",
flexDirection: "row",
overflow: "auto",
padding: 2,
}}
>
<div>
<TopologyColumn
centerBox={{
title: "Grid",
data: values.acInBus,
}}
centerConnection={{
amount: 0.5,
data: values.gridToAcIn,
direction: "rightToLeft",
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "AcInBus",
data: values.acInBus,
}}
centerConnection={{
amount: 0.5,
data: values.gridToAcIn,
direction: "leftToRight",
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "AcOutBus",
data: values.acOutBus,
}}
centerConnection={{
amount: 0.5,
data: values.gridToAcIn,
direction: "leftToRight",
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "Inverter",
data: values.acOutBus,
}}
centerConnection={{
amount: 0.5,
data: values.gridToAcIn,
direction: "leftToRight",
}}
/>
</div>
<div>
<TopologyColumn
topBox={{
title: "MPPT",
data: values.acOutBus,
}}
topConnection={{
amount: 0.5,
data: values.gridToAcIn,
}}
centerBox={{
title: "DcBus",
data: values.acOutBus,
}}
centerConnection={{
amount: 0.5,
data: values.gridToAcIn,
direction: "rightToLeft",
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "DcDc",
data: values.acOutBus,
}}
centerConnection={{
amount: 0.5,
data: values.gridToAcIn,
}}
/>
</div>
<div>
<TopologyColumn
centerBox={{
title: "Battery",
data: values.acOutBus,
}}
/>
</div>
</Box>
);
}
return null;
};
export default TopologyView;

View File

@ -2,20 +2,28 @@ import { Maybe } from "yup";
import { Timestamped } from "./types";
import { isDefined } from "./utils/maybe";
export type DataRecord = Record<string, number | string>
export type DataRecord = Record<string, number | string>;
export type DataPoint = Timestamped<Maybe<DataRecord>>
export type RecordSeries = Array<DataPoint>
export type PointSeries = Array<Timestamped<Maybe<number| string>>>
export type DataSeries = Array<Maybe<number| string>>
export type DataPoint = Timestamped<Maybe<DataRecord>>;
export type RecordSeries = Array<DataPoint>;
export type PointSeries = Array<Timestamped<Maybe<number | string>>>;
export type DataSeries = Array<Maybe<number | string>>;
export function getPoints(recordSeries: RecordSeries, series: keyof DataRecord): PointSeries
{
return recordSeries.map(p => ({time: p.time, value: isDefined(p.value) ? p.value[series] : undefined}))
export function getPoints(
recordSeries: RecordSeries,
series: keyof DataRecord
): PointSeries {
return recordSeries.map((p) => ({
time: p.time,
value: isDefined(p.value) ? p.value[series] : undefined,
}));
}
export function getData(recordSeries: RecordSeries, series: keyof DataRecord): DataSeries
{
return recordSeries.map(p => (isDefined(p.value) ? p.value[series] : undefined))
export function getData(
recordSeries: RecordSeries,
series: keyof DataRecord
): DataSeries {
return recordSeries.map((p) =>
isDefined(p.value) ? p.value[series] : undefined
);
}

View File

@ -55,7 +55,7 @@ export const extractTopologyValues = (
const values = topologyValues[topologyKey].map(
(topologyPath) => timeSeriesValue[topologyPath]
);
console.log("values", values);
console.log("values", topologyValues);
return {
...acc,
[topologyKey]: [
@ -64,7 +64,7 @@ export const extractTopologyValues = (
topologyKey === "gridToAcIn"
? [values.reduce((acc, curr) => Number(acc) + Number(curr))]
: values,
label: topologyKey.split("/").pop(),
label: topologyValues[topologyKey][0].split("/").pop(),
unit: "V",
} as BoxData,
],
@ -93,6 +93,14 @@ export const topologyValues: { [key: string]: string[] } = {
battery: ["/Battery/Soc", "/Battery/Dc/Voltage"],
};
export interface CsvEntry {
value: string | number;
unit: string;
}
export interface Csv {
[key: string]: CsvEntry;
}
export const parseCsv = (text: string) => {
console.log("split", text.split(/\r?\n/));
const y = text