[WIP] adjustments to topology
This commit is contained in:
parent
a9d95fd71e
commit
3a4c768074
|
@ -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";
|
||||
|
|
|
@ -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>
|
||||
<ScalarGraph />
|
||||
</>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
return (
|
||||
<>
|
||||
<TopologyView />
|
||||
<ScalarGraph />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Log;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
.container {
|
||||
position: relative;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
width: 130px;
|
||||
height: 130px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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;
|
|
@ -1,21 +1,29 @@
|
|||
import { Maybe } from "yup";
|
||||
import {Timestamped} from "./types";
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue