Compare commits
9 Commits
f77a86c4fc
...
4c7bc55526
Author | SHA1 | Date |
---|---|---|
Noe | 4c7bc55526 | |
Noe | 490d721795 | |
Noe | d88a18c982 | |
Noe | ca3c9d2903 | |
Noe | 0428770b48 | |
Noe | c0bc1d601a | |
Noe | 950308e4cd | |
Noe | 55fc1708da | |
Noe | d9ae1d7b94 |
|
@ -2,14 +2,15 @@ namespace InnovEnergy.App.Backend.DataTypes;
|
||||||
|
|
||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
public Double MinimumSoC { get; set; }
|
public Double MinimumSoC { get; set; }
|
||||||
public Double GridSetPoint { get; set; }
|
public Double GridSetPoint { get; set; }
|
||||||
public CalibrationChargeType ForceCalibrationCharge { get; set; }
|
public CalibrationChargeType ForceCalibrationCharge { get; set; }
|
||||||
|
public DateTime CalibrationChargeDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum CalibrationChargeType
|
public enum CalibrationChargeType
|
||||||
{
|
{
|
||||||
No,
|
RepetitivelyEvery,
|
||||||
UntilEoc,
|
AdditionallyOnce,
|
||||||
Yes
|
ChargePermanently
|
||||||
}
|
}
|
|
@ -4,8 +4,9 @@ namespace InnovEnergy.App.SaliMax.DataTypes;
|
||||||
|
|
||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
public Double MinimumSoC { get; set; }
|
public Double MinimumSoC { get; set; }
|
||||||
public Double GridSetPoint { get; set; }
|
public Double GridSetPoint { get; set; }
|
||||||
public CalibrationChargeType ForceCalibrationCharge { get; set; }
|
public CalibrationChargeType ForceCalibrationCharge { get; set; }
|
||||||
|
public DateTime CalibrationChargeDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -190,13 +190,13 @@ public static class Controller
|
||||||
var calibrationChargeForced = statusRecord.Config.ForceCalibrationCharge;
|
var calibrationChargeForced = statusRecord.Config.ForceCalibrationCharge;
|
||||||
var batteryCalibrationChargeRequested = statusRecord.Battery is { CalibrationChargeRequested: true };//BatteryCalibrationChargeRequested(statusRecord.Battery?.CalibrationChargeRequested?? false) ;
|
var batteryCalibrationChargeRequested = statusRecord.Battery is { CalibrationChargeRequested: true };//BatteryCalibrationChargeRequested(statusRecord.Battery?.CalibrationChargeRequested?? false) ;
|
||||||
|
|
||||||
var mustDoCalibrationCharge = batteryCalibrationChargeRequested || calibrationChargeForced == CalibrationChargeType.Yes || calibrationChargeForced == CalibrationChargeType.UntilEoc ;
|
var mustDoCalibrationCharge = batteryCalibrationChargeRequested || calibrationChargeForced == CalibrationChargeType.ChargePermanently || calibrationChargeForced == CalibrationChargeType.AdditionallyOnce ;
|
||||||
|
|
||||||
if (statusRecord.Battery is not null)
|
if (statusRecord.Battery is not null)
|
||||||
{
|
{
|
||||||
if (calibrationChargeForced == CalibrationChargeType.UntilEoc && statusRecord.Battery.Eoc )
|
if (calibrationChargeForced == CalibrationChargeType.AdditionallyOnce && statusRecord.Battery.Eoc )
|
||||||
{
|
{
|
||||||
statusRecord.Config.ForceCalibrationCharge = CalibrationChargeType.No;
|
statusRecord.Config.ForceCalibrationCharge = CalibrationChargeType.RepetitivelyEvery;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mustDoCalibrationCharge;
|
return mustDoCalibrationCharge;
|
||||||
|
|
|
@ -64,7 +64,7 @@ public static class MiddlewareAgent
|
||||||
|
|
||||||
Configuration? config = JsonSerializer.Deserialize<Configuration>(message);
|
Configuration? config = JsonSerializer.Deserialize<Configuration>(message);
|
||||||
|
|
||||||
Console.WriteLine($"Received a configuration message: GridSetPoint is " + config.GridSetPoint + ", MinimumSoC is " + config.MinimumSoC + " and ForceCalibrationCharge is " + config.ForceCalibrationCharge);
|
Console.WriteLine($"Received a configuration message: GridSetPoint is " + config.GridSetPoint + ", MinimumSoC is " + config.MinimumSoC + " and ForceCalibrationCharge is " + config.ForceCalibrationCharge+ " and CalibrationChargeDate is " + config.CalibrationChargeDate);
|
||||||
|
|
||||||
// Send the reply to the sender's endpoint
|
// Send the reply to the sender's endpoint
|
||||||
UdpListener.Send(replyData, replyData.Length, serverEndpoint);
|
UdpListener.Send(replyData, replyData.Length, serverEndpoint);
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace InnovEnergy.App.SaliMax.SystemConfig;
|
||||||
|
|
||||||
public enum CalibrationChargeType
|
public enum CalibrationChargeType
|
||||||
{
|
{
|
||||||
No,
|
RepetitivelyEvery,
|
||||||
UntilEoc,
|
AdditionallyOnce,
|
||||||
Yes
|
ChargePermanently
|
||||||
}
|
}
|
|
@ -40,7 +40,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
|
||||||
public static Config Default => new()
|
public static Config Default => new()
|
||||||
{
|
{
|
||||||
MinSoc = 20,
|
MinSoc = 20,
|
||||||
ForceCalibrationCharge = CalibrationChargeType.No,
|
ForceCalibrationCharge = CalibrationChargeType.RepetitivelyEvery,
|
||||||
DisplayIndividualBatteries = false,
|
DisplayIndividualBatteries = false,
|
||||||
PConstant = .5,
|
PConstant = .5,
|
||||||
GridSetPoint = 0,
|
GridSetPoint = 0,
|
||||||
|
@ -117,7 +117,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
|
||||||
public static Config Default => new()
|
public static Config Default => new()
|
||||||
{
|
{
|
||||||
MinSoc = 20,
|
MinSoc = 20,
|
||||||
ForceCalibrationCharge = CalibrationChargeType.No,
|
ForceCalibrationCharge = CalibrationChargeType.RepetitivelyEvery,
|
||||||
DisplayIndividualBatteries = false,
|
DisplayIndividualBatteries = false,
|
||||||
PConstant = .5,
|
PConstant = .5,
|
||||||
GridSetPoint = 0,
|
GridSetPoint = 0,
|
||||||
|
|
|
@ -36,12 +36,22 @@ function BatteryView(props: BatteryViewProps) {
|
||||||
}
|
}
|
||||||
const currentLocation = useLocation();
|
const currentLocation = useLocation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const numOfBatteries = props.values.batteryView.length;
|
const sortedBatteryView = [...props.values.batteryView].sort(
|
||||||
|
(a, b) => b.BatteryId - a.BatteryId
|
||||||
|
);
|
||||||
|
|
||||||
const handleMainStatsButton = () => {
|
const handleMainStatsButton = () => {
|
||||||
navigate(routes.mainstats);
|
navigate(routes.mainstats);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const findBatteryData = (batteryId: number) => {
|
||||||
|
for (let i = 0; i < props.values.batteryView.length; i++) {
|
||||||
|
if (props.values.batteryView[i].BatteryId == batteryId) {
|
||||||
|
return props.values.batteryView[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Container maxWidth="xl">
|
<Container maxWidth="xl">
|
||||||
|
@ -97,14 +107,14 @@ function BatteryView(props: BatteryViewProps) {
|
||||||
<MainStats s3Credentials={props.s3Credentials}></MainStats>
|
<MainStats s3Credentials={props.s3Credentials}></MainStats>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{Array.from({ length: numOfBatteries }).map((_, i) => (
|
{props.values.batteryView.map((battery) => (
|
||||||
<Route
|
<Route
|
||||||
key={routes.detailed_view + i}
|
key={routes.detailed_view + battery.BatteryId}
|
||||||
path={routes.detailed_view + i}
|
path={routes.detailed_view + battery.BatteryId}
|
||||||
element={
|
element={
|
||||||
<DetailedBatteryView
|
<DetailedBatteryView
|
||||||
s3Credentials={props.s3Credentials}
|
s3Credentials={props.s3Credentials}
|
||||||
batteryData={props.values.batteryView[i]}
|
batteryData={findBatteryData(battery.BatteryId)}
|
||||||
></DetailedBatteryView>
|
></DetailedBatteryView>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -138,7 +148,7 @@ function BatteryView(props: BatteryViewProps) {
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{props.values.batteryView.map((battery) => (
|
{sortedBatteryView.map((battery) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
key={battery.BatteryId}
|
key={battery.BatteryId}
|
||||||
style={{
|
style={{
|
||||||
|
@ -153,12 +163,9 @@ function BatteryView(props: BatteryViewProps) {
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
style={{ color: 'black' }}
|
style={{ color: 'black' }}
|
||||||
to={
|
to={routes.detailed_view + battery.BatteryId.toString()}
|
||||||
routes.detailed_view +
|
|
||||||
(battery.BatteryId - 1).toString()
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{'Battery ' + battery.BatteryId}
|
{'Node ' + battery.BatteryId}
|
||||||
</Link>
|
</Link>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell
|
<TableCell
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { I_S3Credentials } from '../../../interfaces/S3Types';
|
import { I_S3Credentials } from '../../../interfaces/S3Types';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
|
@ -8,7 +8,8 @@ import {
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
TableContainer,
|
TableContainer,
|
||||||
TableRow
|
TableRow,
|
||||||
|
Typography
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Battery } from '../Log/graph.util';
|
import { Battery } from '../Log/graph.util';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
|
@ -38,6 +39,64 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [GreenisBlinking, setGreenisBlinking] = useState(
|
||||||
|
props.batteryData.GreenLeds.value === 'Blinking'
|
||||||
|
);
|
||||||
|
|
||||||
|
const [AmberisBlinking, setAmberisBlinking] = useState(
|
||||||
|
props.batteryData.AmberLeds.value === 'Blinking'
|
||||||
|
);
|
||||||
|
const [RedisBlinking, setRedisBlinking] = useState(
|
||||||
|
props.batteryData.RedLeds.value === 'Blinking'
|
||||||
|
);
|
||||||
|
|
||||||
|
const [BlueisBlinking, setBlueisBlinking] = useState(
|
||||||
|
props.batteryData.BlueLeds.value === 'Blinking'
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
if (props.batteryData.AmberLeds.value === 'Blinking') {
|
||||||
|
setAmberisBlinking((prevIsBlinking) => !prevIsBlinking);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.batteryData.RedLeds.value === 'Blinking') {
|
||||||
|
setRedisBlinking((prevIsBlinking) => !prevIsBlinking);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.batteryData.BlueLeds.value === 'Blinking') {
|
||||||
|
setBlueisBlinking((prevIsBlinking) => !prevIsBlinking);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.batteryData.GreenLeds.value === 'Blinking') {
|
||||||
|
setGreenisBlinking((prevIsBlinking) => !prevIsBlinking);
|
||||||
|
}
|
||||||
|
}, 500); // Blink every 500 milliseconds
|
||||||
|
|
||||||
|
// Cleanup the interval on component unmount
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const batteryStyle = {
|
||||||
|
borderRadius: '15px',
|
||||||
|
padding: '10px',
|
||||||
|
backgroundColor: 'lightgray',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: '150px',
|
||||||
|
marginTop: '30px'
|
||||||
|
};
|
||||||
|
|
||||||
|
const batteryStringStyle = {
|
||||||
|
flex: 1,
|
||||||
|
border: '1px solid #000',
|
||||||
|
height: '97%',
|
||||||
|
width: '30px',
|
||||||
|
borderRadius: '7px',
|
||||||
|
backgroundColor: '#bfbfbf'
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Grid container>
|
<Grid container>
|
||||||
|
@ -70,18 +129,149 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item md={2} xs={2}>
|
<Grid container>
|
||||||
|
<Grid item md={4.9} xs={4.9}></Grid>
|
||||||
|
<Grid item md={2.2} xs={2.2}>
|
||||||
|
<div style={batteryStyle}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...batteryStringStyle,
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.String1Active.value == 'True'
|
||||||
|
? '#32CD32'
|
||||||
|
: '#FF033E'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...batteryStringStyle,
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.String2Active.value == 'True'
|
||||||
|
? '#32CD32'
|
||||||
|
: '#FF033E'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...batteryStringStyle,
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.String3Active.value == 'True'
|
||||||
|
? '#32CD32'
|
||||||
|
: '#FF033E'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...batteryStringStyle,
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.String4Active.value == 'True'
|
||||||
|
? '#32CD32'
|
||||||
|
: '#FF033E'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
...batteryStringStyle,
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.String5Active.value == 'True'
|
||||||
|
? '#32CD32'
|
||||||
|
: '#FF033E'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
marginLeft: '10px',
|
||||||
|
marginTop: '-10px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.GreenLeds.value === 'On' ||
|
||||||
|
GreenisBlinking
|
||||||
|
? 'green'
|
||||||
|
: 'transparent'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
marginLeft: '10px',
|
||||||
|
marginTop: '10px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.AmberLeds.value === 'On' ||
|
||||||
|
AmberisBlinking
|
||||||
|
? 'orange'
|
||||||
|
: 'transparent'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
marginLeft: '10px',
|
||||||
|
marginTop: '10px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.BlueLeds.value === 'On' || BlueisBlinking
|
||||||
|
? '#00ccff'
|
||||||
|
: 'transparent'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
marginLeft: '10px',
|
||||||
|
marginTop: '10px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor:
|
||||||
|
props.batteryData.RedLeds.value === 'On' || RedisBlinking
|
||||||
|
? 'red'
|
||||||
|
: 'transparent'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item md={4.9} xs={4.9}></Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item md={3} xs={3}>
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
overflow: 'visible',
|
overflow: 'visible',
|
||||||
marginTop: '30px',
|
marginTop: '30px',
|
||||||
marginBottom: '30px',
|
marginBottom: '30px',
|
||||||
backgroundColor: 'red'
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
border: '2px solid #ccc',
|
||||||
|
borderRadius: '12px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
component="div"
|
||||||
|
sx={{
|
||||||
|
marginTop: '10px',
|
||||||
|
borderBottom: '1px solid #ccc',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Battery Information
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<TableContainer
|
<TableContainer
|
||||||
component={Paper}
|
component={Paper}
|
||||||
sx={{ marginTop: '20px', marginBottom: '20px', width: '100%' }}
|
sx={{ marginTop: '20px', width: '100%' }}
|
||||||
>
|
>
|
||||||
<Table size="medium" aria-label="a dense table">
|
<Table size="medium" aria-label="a dense table">
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
@ -217,28 +407,7 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
|
||||||
props.batteryData.HeatingCurrent.unit}
|
props.batteryData.HeatingCurrent.unit}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
component="th"
|
|
||||||
scope="row"
|
|
||||||
align="left"
|
|
||||||
sx={{ fontWeight: 'bold' }}
|
|
||||||
>
|
|
||||||
Heating Power
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
align="right"
|
|
||||||
sx={{
|
|
||||||
width: '6ch',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
paddingRight: '12px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.batteryData.HeatingPower.value +
|
|
||||||
' ' +
|
|
||||||
props.batteryData.HeatingPower.unit}
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell
|
<TableCell
|
||||||
component="th"
|
component="th"
|
||||||
|
@ -261,47 +430,40 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
|
||||||
props.batteryData.Soc.unit}
|
props.batteryData.Soc.unit}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
component="th"
|
|
||||||
scope="row"
|
|
||||||
align="left"
|
|
||||||
sx={{ fontWeight: 'bold' }}
|
|
||||||
>
|
|
||||||
SOCAh
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
align="right"
|
|
||||||
sx={{
|
|
||||||
width: '6ch',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
paddingRight: '12px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.batteryData.SOCAh.value +
|
|
||||||
' ' +
|
|
||||||
props.batteryData.SOCAh.unit}
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
||||||
<Grid item md={2.9} xs={2.9}>
|
<Grid item md={3} xs={3}>
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
overflow: 'visible',
|
overflow: 'visible',
|
||||||
marginTop: '30px',
|
marginTop: '30px',
|
||||||
marginLeft: '20px',
|
marginLeft: '20px',
|
||||||
marginBottom: '30px',
|
display: 'flex',
|
||||||
backgroundColor: 'red'
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
border: '2px solid #ccc',
|
||||||
|
borderRadius: '12px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
component="div"
|
||||||
|
sx={{
|
||||||
|
marginTop: '10px',
|
||||||
|
borderBottom: '1px solid #ccc',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Temperature
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<TableContainer
|
<TableContainer
|
||||||
component={Paper}
|
component={Paper}
|
||||||
sx={{ marginTop: '20px', marginBottom: '20px', width: '100%' }}
|
sx={{ marginTop: '20px', width: '100%' }}
|
||||||
>
|
>
|
||||||
<Table size="medium" aria-label="a dense table">
|
<Table size="medium" aria-label="a dense table">
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
@ -466,19 +628,33 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
||||||
<Grid item md={2.7} xs={2.7}>
|
<Grid item md={3} xs={3}>
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
overflow: 'visible',
|
overflow: 'visible',
|
||||||
marginTop: '30px',
|
marginTop: '30px',
|
||||||
marginLeft: '20px',
|
marginLeft: '20px',
|
||||||
marginBottom: '30px',
|
display: 'flex',
|
||||||
backgroundColor: 'red'
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
border: '2px solid #ccc',
|
||||||
|
borderRadius: '12px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
component="div"
|
||||||
|
sx={{
|
||||||
|
marginTop: '10px',
|
||||||
|
borderBottom: '1px solid #ccc',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Io Status
|
||||||
|
</Typography>
|
||||||
<TableContainer
|
<TableContainer
|
||||||
component={Paper}
|
component={Paper}
|
||||||
sx={{ marginTop: '20px', marginBottom: '20px', width: '100%' }}
|
sx={{ marginTop: '20px', width: '100%' }}
|
||||||
>
|
>
|
||||||
<Table size="medium" aria-label="a dense table">
|
<Table size="medium" aria-label="a dense table">
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
@ -643,19 +819,33 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
||||||
<Grid item md={2.9} xs={2.9}>
|
<Grid item md={3} xs={3}>
|
||||||
<Card
|
<Card
|
||||||
sx={{
|
sx={{
|
||||||
overflow: 'visible',
|
overflow: 'visible',
|
||||||
marginTop: '30px',
|
marginTop: '30px',
|
||||||
marginLeft: '20px',
|
marginLeft: '20px',
|
||||||
marginBottom: '30px',
|
display: 'flex',
|
||||||
backgroundColor: 'red'
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
border: '2px solid #ccc',
|
||||||
|
borderRadius: '12px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Typography
|
||||||
|
variant="h6"
|
||||||
|
component="div"
|
||||||
|
sx={{
|
||||||
|
marginTop: '10px',
|
||||||
|
borderBottom: '1px solid #ccc',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Specification
|
||||||
|
</Typography>
|
||||||
<TableContainer
|
<TableContainer
|
||||||
component={Paper}
|
component={Paper}
|
||||||
sx={{ marginTop: '20px', marginBottom: '20px', width: '100%' }}
|
sx={{ marginTop: '20px', width: '100%' }}
|
||||||
>
|
>
|
||||||
<Table size="medium" aria-label="a dense table">
|
<Table size="medium" aria-label="a dense table">
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
@ -819,151 +1009,109 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
|
||||||
<Grid item md={1.5} xs={1.5}>
|
|
||||||
<Card
|
{/*<Grid item md={1.5} xs={1.5}>*/}
|
||||||
sx={{
|
{/* <Card*/}
|
||||||
overflow: 'visible',
|
{/* sx={{*/}
|
||||||
marginTop: '30px',
|
{/* overflow: 'visible',*/}
|
||||||
marginLeft: '20px',
|
{/* marginTop: '30px',*/}
|
||||||
marginBottom: '30px',
|
{/* marginLeft: '20px',*/}
|
||||||
backgroundColor: 'red'
|
{/* marginBottom: '30px',*/}
|
||||||
}}
|
{/* backgroundColor: 'red'*/}
|
||||||
>
|
{/* }}*/}
|
||||||
<TableContainer
|
{/* >*/}
|
||||||
component={Paper}
|
{/* <TableContainer*/}
|
||||||
sx={{ marginTop: '20px', marginBottom: '20px', width: '100%' }}
|
{/* component={Paper}*/}
|
||||||
>
|
{/* sx={{ marginTop: '20px', marginBottom: '20px', width: '100%' }}*/}
|
||||||
<Table size="medium" aria-label="a dense table">
|
{/* >*/}
|
||||||
<TableBody>
|
{/* <Table size="medium" aria-label="a dense table">*/}
|
||||||
<TableRow>
|
{/* <TableBody>*/}
|
||||||
<TableCell
|
{/* <TableRow>*/}
|
||||||
component="th"
|
{/* <TableCell*/}
|
||||||
scope="row"
|
{/* component="th"*/}
|
||||||
align="left"
|
{/* scope="row"*/}
|
||||||
sx={{ fontWeight: 'bold' }}
|
{/* align="left"*/}
|
||||||
>
|
{/* sx={{ fontWeight: 'bold' }}*/}
|
||||||
Blue Led
|
{/* >*/}
|
||||||
</TableCell>
|
{/* Green Led*/}
|
||||||
<TableCell
|
{/* </TableCell>*/}
|
||||||
align="right"
|
{/* <TableCell*/}
|
||||||
sx={{
|
{/* align="right"*/}
|
||||||
width: '6ch',
|
{/* sx={{*/}
|
||||||
whiteSpace: 'nowrap',
|
{/* width: '6ch',*/}
|
||||||
paddingRight: '12px'
|
{/* whiteSpace: 'nowrap',*/}
|
||||||
}}
|
{/* paddingRight: '12px'*/}
|
||||||
>
|
{/* }}*/}
|
||||||
<div
|
{/* >*/}
|
||||||
style={{
|
{/* {props.batteryData.GreenLeds.value}*/}
|
||||||
width: '20px',
|
{/* </TableCell>*/}
|
||||||
height: '20px',
|
{/* </TableRow>*/}
|
||||||
marginLeft: '2px',
|
{/* <TableRow>*/}
|
||||||
borderRadius: '50%',
|
{/* <TableCell*/}
|
||||||
backgroundColor:
|
{/* component="th"*/}
|
||||||
props.batteryData.BlueLeds.value === 'On'
|
{/* scope="row"*/}
|
||||||
? '#00ccff'
|
{/* align="left"*/}
|
||||||
: 'transparent'
|
{/* sx={{ fontWeight: 'bold' }}*/}
|
||||||
}}
|
{/* >*/}
|
||||||
/>
|
{/* Amber Led*/}
|
||||||
</TableCell>
|
{/* </TableCell>*/}
|
||||||
</TableRow>
|
{/* <TableCell*/}
|
||||||
<TableRow>
|
{/* align="right"*/}
|
||||||
<TableCell
|
{/* sx={{*/}
|
||||||
component="th"
|
{/* width: '6ch',*/}
|
||||||
scope="row"
|
{/* whiteSpace: 'nowrap',*/}
|
||||||
align="left"
|
{/* paddingRight: '12px'*/}
|
||||||
sx={{ fontWeight: 'bold' }}
|
{/* }}*/}
|
||||||
>
|
{/* >*/}
|
||||||
Green Led
|
{/* {props.batteryData.AmberLeds.value}*/}
|
||||||
</TableCell>
|
{/* </TableCell>*/}
|
||||||
<TableCell
|
{/* </TableRow>*/}
|
||||||
align="right"
|
{/* <TableRow>*/}
|
||||||
sx={{
|
{/* <TableCell*/}
|
||||||
width: '6ch',
|
{/* component="th"*/}
|
||||||
whiteSpace: 'nowrap',
|
{/* scope="row"*/}
|
||||||
paddingRight: '12px'
|
{/* align="left"*/}
|
||||||
}}
|
{/* sx={{ fontWeight: 'bold' }}*/}
|
||||||
>
|
{/* >*/}
|
||||||
<div
|
{/* Blue Led*/}
|
||||||
style={{
|
{/* </TableCell>*/}
|
||||||
width: '20px',
|
{/* <TableCell*/}
|
||||||
height: '20px',
|
{/* align="right"*/}
|
||||||
marginLeft: '2px',
|
{/* sx={{*/}
|
||||||
borderRadius: '50%',
|
{/* width: '6ch',*/}
|
||||||
backgroundColor:
|
{/* whiteSpace: 'nowrap',*/}
|
||||||
props.batteryData.GreenLeds.value === 'On'
|
{/* paddingRight: '12px'*/}
|
||||||
? 'green'
|
{/* }}*/}
|
||||||
: 'transparent'
|
{/* >*/}
|
||||||
}}
|
{/* {props.batteryData.BlueLeds.value}*/}
|
||||||
/>
|
{/* </TableCell>*/}
|
||||||
</TableCell>
|
{/* </TableRow>*/}
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
{/* <TableRow>*/}
|
||||||
<TableCell
|
{/* <TableCell*/}
|
||||||
component="th"
|
{/* component="th"*/}
|
||||||
scope="row"
|
{/* scope="row"*/}
|
||||||
align="left"
|
{/* align="left"*/}
|
||||||
sx={{ fontWeight: 'bold' }}
|
{/* sx={{ fontWeight: 'bold' }}*/}
|
||||||
>
|
{/* >*/}
|
||||||
Red Led
|
{/* Red Led*/}
|
||||||
</TableCell>
|
{/* </TableCell>*/}
|
||||||
<TableCell
|
{/* <TableCell*/}
|
||||||
align="right"
|
{/* align="right"*/}
|
||||||
sx={{
|
{/* sx={{*/}
|
||||||
width: '6ch',
|
{/* width: '6ch',*/}
|
||||||
whiteSpace: 'nowrap',
|
{/* whiteSpace: 'nowrap',*/}
|
||||||
paddingRight: '12px'
|
{/* paddingRight: '12px'*/}
|
||||||
}}
|
{/* }}*/}
|
||||||
>
|
{/* >*/}
|
||||||
<div
|
{/* {props.batteryData.RedLeds.value}*/}
|
||||||
style={{
|
{/* </TableCell>*/}
|
||||||
width: '20px',
|
{/* </TableRow>*/}
|
||||||
height: '20px',
|
{/* </TableBody>*/}
|
||||||
marginLeft: '2px',
|
{/* </Table>*/}
|
||||||
borderRadius: '50%',
|
{/* </TableContainer>*/}
|
||||||
backgroundColor:
|
{/* </Card>*/}
|
||||||
props.batteryData.RedLeds.value === 'On'
|
{/*</Grid>*/}
|
||||||
? 'red'
|
|
||||||
: 'transparent'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
<TableRow>
|
|
||||||
<TableCell
|
|
||||||
component="th"
|
|
||||||
scope="row"
|
|
||||||
align="left"
|
|
||||||
sx={{ fontWeight: 'bold' }}
|
|
||||||
>
|
|
||||||
Amber Led
|
|
||||||
</TableCell>
|
|
||||||
<TableCell
|
|
||||||
align="right"
|
|
||||||
sx={{
|
|
||||||
width: '6ch',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
paddingRight: '12px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: '20px',
|
|
||||||
height: '20px',
|
|
||||||
marginLeft: '2px',
|
|
||||||
borderRadius: '50%',
|
|
||||||
backgroundColor:
|
|
||||||
props.batteryData.AmberLeds.value === 'On'
|
|
||||||
? 'orange'
|
|
||||||
: 'transparent'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</TableContainer>
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,22 @@ import {
|
||||||
Grid,
|
Grid,
|
||||||
IconButton,
|
IconButton,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
|
Modal,
|
||||||
Select,
|
Select,
|
||||||
TextField,
|
TextField,
|
||||||
|
Typography,
|
||||||
useTheme
|
useTheme
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
|
import { DateField } from '@mui/x-date-pickers/DateField';
|
||||||
import axiosConfig from '../../../Resources/axiosConfig';
|
import axiosConfig from '../../../Resources/axiosConfig';
|
||||||
import { Close as CloseIcon } from '@mui/icons-material';
|
import { Close as CloseIcon } from '@mui/icons-material';
|
||||||
import MenuItem from '@mui/material/MenuItem';
|
import MenuItem from '@mui/material/MenuItem';
|
||||||
|
import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';
|
||||||
|
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
interface ConfigurationProps {
|
interface ConfigurationProps {
|
||||||
values: TopologyValues;
|
values: TopologyValues;
|
||||||
|
@ -30,32 +36,11 @@ function Configuration(props: ConfigurationProps) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const forcedCalibrationChargeOptions = ['No', 'UntilEoc', 'Yes'];
|
const forcedCalibrationChargeOptions = [
|
||||||
|
'RepetitivelyEvery',
|
||||||
const [formValues, setFormValues] = useState<ConfigurationValues>({
|
'AdditionallyOnce',
|
||||||
minimumSoC: props.values.minimumSoC[0].value,
|
'ChargePermanently'
|
||||||
gridSetPoint: (props.values.gridSetPoint[0].value as number) / 1000,
|
];
|
||||||
forceCalibrationCharge: forcedCalibrationChargeOptions.indexOf(
|
|
||||||
props.values.calibrationChargeForced[0].value.toString()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
|
||||||
setLoading(true);
|
|
||||||
const res = await axiosConfig
|
|
||||||
.post(`/EditInstallationConfig?installationId=${props.id}`, formValues)
|
|
||||||
.catch((err) => {
|
|
||||||
if (err.response) {
|
|
||||||
setError(true);
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
setUpdated(true);
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const [errors, setErrors] = useState({
|
const [errors, setErrors] = useState({
|
||||||
minimumSoC: false,
|
minimumSoC: false,
|
||||||
|
@ -80,9 +65,62 @@ function Configuration(props: ConfigurationProps) {
|
||||||
] = useState<string>(
|
] = useState<string>(
|
||||||
props.values.calibrationChargeForced[0].value.toString()
|
props.values.calibrationChargeForced[0].value.toString()
|
||||||
);
|
);
|
||||||
//const forcedCalibrationChargeOptions = ['No', 'UntilEoc', 'Yes'];
|
const [isDateModalOpen, setIsDateModalOpen] = useState(false);
|
||||||
|
const [calibrationChargeDate, setCalibrationChargeDate] = useState();
|
||||||
|
const [isErrorDateModalOpen, setErrorDateModalOpen] = useState(false);
|
||||||
|
const [dateSelectionError, setDateSelectionError] = useState('');
|
||||||
|
const [dateFieldOpen, setDateFieldOpen] = useState(false);
|
||||||
|
|
||||||
|
const [formValues, setFormValues] = useState<ConfigurationValues>({
|
||||||
|
minimumSoC: props.values.minimumSoC[0].value,
|
||||||
|
gridSetPoint: (props.values.gridSetPoint[0].value as number) / 1000,
|
||||||
|
forceCalibrationCharge: forcedCalibrationChargeOptions.indexOf(
|
||||||
|
props.values.calibrationChargeForced[0].value.toString()
|
||||||
|
),
|
||||||
|
calibrationChargeDate: Date(props.values.calibrationChargeDate[0].value)
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
setLoading(true);
|
||||||
|
const res = await axiosConfig
|
||||||
|
.post(`/EditInstallationConfig?installationId=${props.id}`, formValues)
|
||||||
|
.catch((err) => {
|
||||||
|
if (err.response) {
|
||||||
|
setError(true);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
setUpdated(true);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
setIsDateModalOpen(false);
|
||||||
|
};
|
||||||
|
const handleOkOnErrorDateModal = () => {
|
||||||
|
setErrorDateModalOpen(false);
|
||||||
|
setIsDateModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
setIsDateModalOpen(false);
|
||||||
|
|
||||||
|
if (calibrationChargeDate.isBefore(dayjs())) {
|
||||||
|
setDateSelectionError('You must use a future date');
|
||||||
|
setErrorDateModalOpen(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDateFieldOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
const handleSelectedCalibrationChargeChange = (event) => {
|
const handleSelectedCalibrationChargeChange = (event) => {
|
||||||
|
if (event.target.value != 'ChargePermanently') {
|
||||||
|
setIsDateModalOpen(true);
|
||||||
|
}
|
||||||
setSelectedForcedCalibrationChargeOption(event.target.value);
|
setSelectedForcedCalibrationChargeOption(event.target.value);
|
||||||
|
|
||||||
setFormValues({
|
setFormValues({
|
||||||
|
@ -199,7 +237,6 @@ function Configuration(props: ConfigurationProps) {
|
||||||
open={openForcedCalibrationCharge}
|
open={openForcedCalibrationCharge}
|
||||||
onClose={handleCloseForcedCalibrationCharge}
|
onClose={handleCloseForcedCalibrationCharge}
|
||||||
onOpen={handleOpenForcedCalibrationCharge}
|
onOpen={handleOpenForcedCalibrationCharge}
|
||||||
//renderValue={selectedForcedCalibrationChargeOption}
|
|
||||||
>
|
>
|
||||||
{forcedCalibrationChargeOptions.map((option) => (
|
{forcedCalibrationChargeOptions.map((option) => (
|
||||||
<MenuItem key={option} value={option}>
|
<MenuItem key={option} value={option}>
|
||||||
|
@ -209,6 +246,127 @@ function Configuration(props: ConfigurationProps) {
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
|
{(dateFieldOpen || formValues.forceCalibrationCharge != 2) && (
|
||||||
|
<div>
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
|
<DateField
|
||||||
|
label="Calibration Charge Date"
|
||||||
|
value={calibrationChargeDate}
|
||||||
|
/>
|
||||||
|
</LocalizationProvider>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isErrorDateModalOpen && (
|
||||||
|
<Modal open={isErrorDateModalOpen} onClose={() => {}}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
width: 450,
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
borderRadius: 4,
|
||||||
|
boxShadow: 24,
|
||||||
|
p: 4,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography
|
||||||
|
variant="body1"
|
||||||
|
gutterBottom
|
||||||
|
sx={{ fontWeight: 'bold' }}
|
||||||
|
>
|
||||||
|
{dateSelectionError}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
marginTop: 2,
|
||||||
|
textTransform: 'none',
|
||||||
|
bgcolor: '#ffc04d',
|
||||||
|
color: '#111111',
|
||||||
|
'&:hover': { bgcolor: '#f7b34d' }
|
||||||
|
}}
|
||||||
|
onClick={handleOkOnErrorDateModal}
|
||||||
|
>
|
||||||
|
Ok
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isDateModalOpen && (
|
||||||
|
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||||
|
<Modal open={isDateModalOpen} onClose={() => {}}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
width: 450,
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
borderRadius: 4,
|
||||||
|
boxShadow: 24,
|
||||||
|
p: 4,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DateTimePicker
|
||||||
|
label="Select Calibration Charge Date"
|
||||||
|
value={calibrationChargeDate}
|
||||||
|
onChange={(newDate) =>
|
||||||
|
setCalibrationChargeDate(newDate)
|
||||||
|
}
|
||||||
|
sx={{
|
||||||
|
marginTop: 2
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginTop: 10
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
marginTop: 2,
|
||||||
|
textTransform: 'none',
|
||||||
|
bgcolor: '#ffc04d',
|
||||||
|
color: '#111111',
|
||||||
|
'&:hover': { bgcolor: '#f7b34d' }
|
||||||
|
}}
|
||||||
|
onClick={handleConfirm}
|
||||||
|
>
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
marginTop: 2,
|
||||||
|
marginLeft: 2,
|
||||||
|
textTransform: 'none',
|
||||||
|
bgcolor: '#ffc04d',
|
||||||
|
color: '#111111',
|
||||||
|
'&:hover': { bgcolor: '#f7b34d' }
|
||||||
|
}}
|
||||||
|
onClick={handleCancel}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
</Modal>
|
||||||
|
</LocalizationProvider>
|
||||||
|
)}
|
||||||
|
|
||||||
<div style={{ marginBottom: '5px' }}>
|
<div style={{ marginBottom: '5px' }}>
|
||||||
<TextField
|
<TextField
|
||||||
|
|
|
@ -32,6 +32,7 @@ export type ConfigurationValues = {
|
||||||
minimumSoC: string | number;
|
minimumSoC: string | number;
|
||||||
gridSetPoint: number;
|
gridSetPoint: number;
|
||||||
forceCalibrationCharge: number;
|
forceCalibrationCharge: number;
|
||||||
|
calibrationChargeDate: Date | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Battery {
|
export interface Battery {
|
||||||
|
@ -158,6 +159,7 @@ export type TopologyValues = {
|
||||||
DcDcNum: I_BoxDataValue[];
|
DcDcNum: I_BoxDataValue[];
|
||||||
calibrationChargeForced: I_BoxDataValue[];
|
calibrationChargeForced: I_BoxDataValue[];
|
||||||
mode: I_BoxDataValue[];
|
mode: I_BoxDataValue[];
|
||||||
|
calibrationChargeDate: I_BoxDataValue[];
|
||||||
|
|
||||||
batteryView: Battery[];
|
batteryView: Battery[];
|
||||||
};
|
};
|
||||||
|
@ -293,7 +295,8 @@ export const topologyPaths: TopologyPaths = {
|
||||||
maximumDischargePower: ['/Config/MaxBatteryDischargingCurrent'],
|
maximumDischargePower: ['/Config/MaxBatteryDischargingCurrent'],
|
||||||
DcDcNum: ['/DcDc/SystemControl/NumberOfConnectedSlaves'],
|
DcDcNum: ['/DcDc/SystemControl/NumberOfConnectedSlaves'],
|
||||||
calibrationChargeForced: ['/Config/ForceCalibrationCharge'],
|
calibrationChargeForced: ['/Config/ForceCalibrationCharge'],
|
||||||
mode: ['/EssControl/Mode']
|
mode: ['/EssControl/Mode'],
|
||||||
|
calibrationChargeDate: ['/EssControl/Date']
|
||||||
};
|
};
|
||||||
|
|
||||||
export const extractValues = (
|
export const extractValues = (
|
||||||
|
@ -307,19 +310,19 @@ export const extractValues = (
|
||||||
|
|
||||||
if (topologyKey === 'batteryView') {
|
if (topologyKey === 'batteryView') {
|
||||||
extractedValues[topologyKey] = [];
|
extractedValues[topologyKey] = [];
|
||||||
const numOfBatteries = timeSeriesData.value[
|
const battery_ids_from_csv = timeSeriesData.value[
|
||||||
'/Config/Devices/BatteryNodes'
|
'/Config/Devices/BatteryNodes'
|
||||||
].value
|
].value
|
||||||
.toString()
|
.toString()
|
||||||
.split(',').length;
|
.split(',');
|
||||||
|
|
||||||
let battery_id = 1;
|
let battery_index = 0;
|
||||||
let pathIndex = 0;
|
let pathIndex = 0;
|
||||||
|
|
||||||
while (pathIndex < paths.length) {
|
while (pathIndex < paths.length) {
|
||||||
let battery = {};
|
let battery = {};
|
||||||
let existingKeys = 0;
|
let existingKeys = 0;
|
||||||
battery[BatteryKeys[0]] = battery_id;
|
battery[BatteryKeys[0]] = battery_ids_from_csv[battery_index];
|
||||||
for (let i = 1; i < BatteryKeys.length; i++) {
|
for (let i = 1; i < BatteryKeys.length; i++) {
|
||||||
const path = paths[pathIndex];
|
const path = paths[pathIndex];
|
||||||
if (timeSeriesData.value.hasOwnProperty(path)) {
|
if (timeSeriesData.value.hasOwnProperty(path)) {
|
||||||
|
@ -337,7 +340,7 @@ export const extractValues = (
|
||||||
}
|
}
|
||||||
pathIndex++;
|
pathIndex++;
|
||||||
}
|
}
|
||||||
battery_id++;
|
battery_index++;
|
||||||
if (existingKeys > 0) {
|
if (existingKeys > 0) {
|
||||||
extractedValues[topologyKey].push(battery as Battery);
|
extractedValues[topologyKey].push(battery as Battery);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue