Compare commits

..

No commits in common. "cee72bebe636281853d425e0ce6c59f46395881c" and "453768c7090a0721cba2c0d8ae1a1fac82f9aae8" have entirely different histories.

22 changed files with 381 additions and 543 deletions

View File

@ -16,8 +16,7 @@ dotnet publish \
-r linux-x64
echo -e "\n============================ Deploy ============================\n"
ip_addresses=("10.2.3.115" "10.2.3.104" "10.2.4.33" "10.2.4.32" "10.2.4.36" "10.2.4.35" "10.2.4.154" "10.2.4.113" "10.2.4.29")
ip_addresses=("10.2.3.115" "10.2.3.104" "10.2.4.33" "10.2.4.32" "10.2.4.36" "10.2.4.35" "10.2.4.154" "10.2.4.113" "10.2.4.29" "10.2.4.211")
for ip_address in "${ip_addresses[@]}"; do
rsync -v \

View File

@ -197,17 +197,16 @@ public static class Controller
(calibrationChargeForced == CalibrationChargeType.RepetitivelyEvery && repetitiveCalibrationRequired);
Console.WriteLine("Next Repetitive calibration charge date is "+statusRecord.Config.DayAndTimeForRepetitiveCalibration);
Console.WriteLine("Next Additional calibration charge date is "+statusRecord.Config.DayAndTimeForAdditionalCalibration);
//Console.WriteLine("Time now is "+DateTime.Now);
if (statusRecord.Battery is not null)
{
if (calibrationChargeForced == CalibrationChargeType.AdditionallyOnce && statusRecord.Battery.Eoc )
{
statusRecord.Config.ForceCalibrationChargeState = CalibrationChargeType.RepetitivelyEvery;
//_hasAdditionalCalibrationChargeChecked = false;
_hasAdditionalCalibrationChargeChecked = false;
}
else if (calibrationChargeForced == CalibrationChargeType.RepetitivelyEvery && statusRecord.Battery.Eoc && _hasRepetitiveCalibrationChargeChecked)
else if (calibrationChargeForced == CalibrationChargeType.RepetitivelyEvery && statusRecord.Battery.Eoc )
{
statusRecord.Config.DayAndTimeForRepetitiveCalibration = statusRecord.Config.DayAndTimeForRepetitiveCalibration.AddDays(7);
_hasRepetitiveCalibrationChargeChecked = false;
@ -218,41 +217,30 @@ public static class Controller
private static Boolean RepetitiveCalibrationDateHasBeenPassed(DateTime calibrationChargeDate)
{
// if (!_hasRepetitiveCalibrationChargeChecked)
// {
// if (DateTime.Now >= calibrationChargeDate )
// {
// _hasRepetitiveCalibrationChargeChecked = true;
// return true;
// }
// return false;
// }
// return true;
if (DateTime.Now >= calibrationChargeDate )
if (!_hasRepetitiveCalibrationChargeChecked)
{
_hasRepetitiveCalibrationChargeChecked = true;
return true;
if (DateTime.Now >= calibrationChargeDate )
{
_hasRepetitiveCalibrationChargeChecked = true;
return true;
}
return false;
}
return false;
return true;
}
private static Boolean AdditionalCalibrationDateHasBeenPassed(DateTime calibrationChargeDate)
{
// if (!_hasAdditionalCalibrationChargeChecked)
// {
if (!_hasAdditionalCalibrationChargeChecked)
{
if (DateTime.Now >= calibrationChargeDate )
{
//_hasAdditionalCalibrationChargeChecked = true;
_hasAdditionalCalibrationChargeChecked = true;
return true;
}
return false;
// }
// return true;
}
return true;
}

View File

@ -11,7 +11,6 @@ public static class MiddlewareAgent
{
public static UdpClient UdpListener = null!;
private static IPAddress? _controllerIpAddress;
private static EndPoint? _endPoint;
public static void InitializeCommunicationToMiddleware()
{
@ -22,11 +21,11 @@ public static class MiddlewareAgent
}
const Int32 udpPort = 9000;
_endPoint = new IPEndPoint(_controllerIpAddress, udpPort);
var endPoint = new IPEndPoint(_controllerIpAddress, udpPort);
UdpListener = new UdpClient();
UdpListener.Client.Blocking = false;
UdpListener.Client.Bind(_endPoint);
UdpListener.Client.Bind(endPoint);
}
private static IPAddress FindVpnIp()
@ -55,7 +54,6 @@ public static class MiddlewareAgent
{
if (UdpListener.Available > 0)
{
IPEndPoint? serverEndpoint = null;
var replyMessage = "ACK";
@ -74,13 +72,6 @@ public static class MiddlewareAgent
return config;
}
if (!_endPoint.Equals((IPEndPoint)UdpListener.Client.LocalEndPoint))
{
Console.WriteLine("UDP address has changed, rebinding...");
InitializeCommunicationToMiddleware();
}
return null;
}

View File

@ -1,4 +1,4 @@
#undef Amax
#define Amax
#undef GridLimit
using System.Reactive.Linq;

View File

@ -31,7 +31,6 @@ interface BatteryViewProps {
values: TopologyValues;
s3Credentials: I_S3Credentials;
installationId: number;
productNum: number;
}
function BatteryView(props: BatteryViewProps) {
@ -158,7 +157,6 @@ function BatteryView(props: BatteryViewProps) {
s3Credentials={props.s3Credentials}
batteryData={findBatteryData(battery.BatteryId)}
installationId={props.installationId}
productNum={props.productNum}
></DetailedBatteryView>
}
/>
@ -274,83 +272,72 @@ function BatteryView(props: BatteryViewProps) {
battery.AverageTemperature.unit}
</TableCell>
{props.productNum === 0 && (
<>
<TableCell
style={{
width: '20%',
textAlign: 'center',
padding: '8px',
fontWeight:
battery.Warnings.value !== ''
? 'bold'
: 'inherit',
backgroundColor:
battery.Warnings.value === ''
? 'inherit'
: '#ff9900',
color:
battery.Warnings.value != '' ? 'black' : 'inherit'
}}
<TableCell
style={{
width: '20%',
textAlign: 'center',
padding: '8px',
fontWeight:
battery.Warnings.value !== '' ? 'bold' : 'inherit',
backgroundColor:
battery.Warnings.value === '' ? 'inherit' : '#ff9900',
color:
battery.Warnings.value != '' ? 'black' : 'inherit'
}}
>
{battery.Warnings.value === '' ? (
'None'
) : battery.Warnings.value.toString().split('-').length >
1 ? (
<Link
style={{ color: 'black' }}
to={
currentLocation.pathname.substring(
0,
currentLocation.pathname.lastIndexOf('/') + 1
) +
routes.log +
'?open=warning'
}
>
{battery.Warnings.value === '' ? (
'None'
) : battery.Warnings.value.toString().split('-')
.length > 1 ? (
<Link
style={{ color: 'black' }}
to={
currentLocation.pathname.substring(
0,
currentLocation.pathname.lastIndexOf('/') + 1
) +
routes.log +
'?open=warning'
}
>
Multiple Warnings
</Link>
) : (
battery.Warnings.value
)}
</TableCell>
<TableCell
sx={{
width: '20%',
textAlign: 'center',
fontWeight:
battery.Alarms.value !== '' ? 'bold' : 'inherit',
backgroundColor:
battery.Alarms.value === ''
? 'inherit'
: '#FF033E',
color:
battery.Alarms.value != '' ? 'black' : 'inherit'
}}
Multiple Warnings
</Link>
) : (
battery.Warnings.value
)}
</TableCell>
<TableCell
sx={{
width: '20%',
textAlign: 'center',
fontWeight:
battery.Alarms.value !== '' ? 'bold' : 'inherit',
backgroundColor:
battery.Alarms.value === '' ? 'inherit' : '#FF033E',
color: battery.Alarms.value != '' ? 'black' : 'inherit'
}}
>
{battery.Alarms.value === '' ? (
'None'
) : battery.Alarms.value.toString().split('-').length >
1 ? (
<Link
style={{ color: 'black' }}
to={
currentLocation.pathname.substring(
0,
currentLocation.pathname.lastIndexOf('/') + 1
) +
routes.log +
'?open=error'
}
>
{battery.Alarms.value === '' ? (
'None'
) : battery.Alarms.value.toString().split('-')
.length > 1 ? (
<Link
style={{ color: 'black' }}
to={
currentLocation.pathname.substring(
0,
currentLocation.pathname.lastIndexOf('/') + 1
) +
routes.log +
'?open=error'
}
>
Multiple Alarms
</Link>
) : (
battery.Alarms.value
)}
</TableCell>
</>
)}
Multiple Alarms
</Link>
) : (
battery.Alarms.value
)}
</TableCell>
</TableRow>
))}
</TableBody>

View File

@ -25,7 +25,6 @@ interface DetailedBatteryViewProps {
s3Credentials: I_S3Credentials;
batteryData: Battery;
installationId: number;
productNum: number;
}
function DetailedBatteryView(props: DetailedBatteryViewProps) {
@ -274,24 +273,22 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
<ArrowBackIcon />
</IconButton>
{props.productNum === 0 && (
<Button
variant="contained"
onClick={handleUpdateFirmware}
sx={{
marginTop: '20px',
marginLeft: '20px',
backgroundColor: '#ffc04d',
color: '#000000',
'&:hover': { bgcolor: '#f7b34d' }
}}
>
<FormattedMessage
id="update_firmware"
defaultMessage="Update Firmware"
/>
</Button>
)}
<Button
variant="contained"
onClick={handleUpdateFirmware}
sx={{
marginTop: '20px',
marginLeft: '20px',
backgroundColor: '#ffc04d',
color: '#000000',
'&:hover': { bgcolor: '#f7b34d' }
}}
>
<FormattedMessage
id="update_firmware"
defaultMessage="Update Firmware"
/>
</Button>
</Grid>
</Grid>
<Grid container>
@ -313,8 +310,7 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
style={{
...batteryStringStyle,
backgroundColor:
props.batteryData.String1Active.value == 'True' ||
props.batteryData.String4Active.value == 0
props.batteryData.String1Active.value == 'True'
? '#32CD32'
: '#FF033E'
}}
@ -323,8 +319,7 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
style={{
...batteryStringStyle,
backgroundColor:
props.batteryData.String2Active.value == 'True' ||
props.batteryData.String4Active.value == 0
props.batteryData.String2Active.value == 'True'
? '#32CD32'
: '#FF033E'
}}
@ -333,8 +328,7 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
style={{
...batteryStringStyle,
backgroundColor:
props.batteryData.String3Active.value == 'True' ||
props.batteryData.String4Active.value == 0
props.batteryData.String3Active.value == 'True'
? '#32CD32'
: '#FF033E'
}}
@ -343,8 +337,7 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
style={{
...batteryStringStyle,
backgroundColor:
props.batteryData.String4Active.value == 'True' ||
props.batteryData.String4Active.value == 0
props.batteryData.String4Active.value == 'True'
? '#32CD32'
: '#FF033E'
}}
@ -353,8 +346,7 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
style={{
...batteryStringStyle,
backgroundColor:
props.batteryData.String5Active.value == 'True' ||
props.batteryData.String4Active.value == 0
props.batteryData.String5Active.value == 'True'
? '#32CD32'
: '#FF033E'
}}
@ -522,7 +514,6 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
props.batteryData.Power.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
@ -618,200 +609,196 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
</Card>
</Grid>
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
{props.productNum === 0 && (
<>
<Grid item md={3} xs={3}>
<Card
sx={{
overflow: 'visible',
marginTop: '30px',
marginLeft: '20px',
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'
}}
>
Temperature
</Typography>
<Grid item md={3} xs={3}>
<Card
sx={{
overflow: 'visible',
marginTop: '30px',
marginLeft: '20px',
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'
}}
>
Temperature
</Typography>
<TableContainer
component={Paper}
sx={{ marginTop: '20px', width: '100%' }}
>
<Table size="medium" aria-label="a dense table">
<TableBody>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Heating
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.HeatingTemperature.value +
' ' +
props.batteryData.HeatingTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Board Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.BoardTemperature.value +
' ' +
props.batteryData.BoardTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Center Cells Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.AverageTemperature.value +
' ' +
props.batteryData.AverageTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Left Cells Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.LeftCellsTemperature.value +
' ' +
props.batteryData.LeftCellsTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Right Cells Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.RightCellsTemperature.value +
' ' +
props.batteryData.RightCellsTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Average Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.AverageTemperature.value +
' ' +
props.batteryData.AverageTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
State
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.StateTemperature.value +
' ' +
props.batteryData.StateTemperature.unit}
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</Card>
</Grid>
</>
)}
<TableContainer
component={Paper}
sx={{ marginTop: '20px', width: '100%' }}
>
<Table size="medium" aria-label="a dense table">
<TableBody>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Heating
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.HeatingTemperature.value +
' ' +
props.batteryData.HeatingTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Board Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.BoardTemperature.value +
' ' +
props.batteryData.BoardTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Center Cells Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.AverageTemperature.value +
' ' +
props.batteryData.AverageTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Left Cells Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.LeftCellsTemperature.value +
' ' +
props.batteryData.LeftCellsTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Right Cells Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.RightCellsTemperature.value +
' ' +
props.batteryData.RightCellsTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Average Temperature
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.AverageTemperature.value +
' ' +
props.batteryData.AverageTemperature.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
State
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.StateTemperature.value +
' ' +
props.batteryData.StateTemperature.unit}
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</Card>
</Grid>
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
<Grid item md={3} xs={3}>
@ -820,7 +807,6 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
overflow: 'visible',
marginTop: '30px',
marginLeft: '20px',
marginBottom: '20px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
@ -1006,7 +992,6 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
</Grid>
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
<Grid item md={3} xs={3}>
<Card
sx={{
@ -1059,7 +1044,6 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
props.batteryData.Eoc.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
@ -1082,7 +1066,6 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
props.batteryData.SerialNumber.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
@ -1127,30 +1110,28 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
props.batteryData.TimeSinceTOC.unit}
</TableCell>
</TableRow>
{props.productNum === 0 && (
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Calibration Charge Requested
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.CalibrationChargeRequested.value +
' ' +
props.batteryData.CalibrationChargeRequested.unit}
</TableCell>
</TableRow>
)}
<TableRow>
<TableCell
component="th"
scope="row"
align="left"
sx={{ fontWeight: 'bold' }}
>
Calibration Charge Requested
</TableCell>
<TableCell
align="right"
sx={{
width: '6ch',
whiteSpace: 'nowrap',
paddingRight: '12px'
}}
>
{props.batteryData.CalibrationChargeRequested.value +
' ' +
props.batteryData.CalibrationChargeRequested.unit}
</TableCell>
</TableRow>
<TableRow>
<TableCell
component="th"
@ -1200,7 +1181,6 @@ function DetailedBatteryView(props: DetailedBatteryViewProps) {
</TableContainer>
</Card>
</Grid>
{/*----------------------------------------------------------------------------------------------------------------------------------*/}
{/*<Grid item md={1.5} xs={1.5}>*/}

View File

@ -43,7 +43,7 @@ function Configuration(props: ConfigurationProps) {
const CalibrationChargeOptions = [
'Repetitive Calibration',
'Additional Calibration',
'Force Permanent Calibration Now'
'Force Calibration Now'
];
const CalibrationChargeOptionsController = [
@ -93,11 +93,13 @@ function Configuration(props: ConfigurationProps) {
CalibrationChargeOptionsController.indexOf(
props.values.calibrationChargeState[0].value.toString()
) == 0
? dayjs(props.values.repetitiveCalibrationChargeDate[0].value)
// .add(localOffset, 'minute')
? dayjs
.utc(props.values.repetitiveCalibrationChargeDate[0].value)
.add(localOffset, 'minute')
.toDate()
: dayjs(props.values.additionalCalibrationChargeDate[0].value)
// .add(localOffset, 'minute')
: dayjs
.utc(props.values.additionalCalibrationChargeDate[0].value)
.add(localOffset, 'minute')
.toDate()
});
@ -122,19 +124,14 @@ function Configuration(props: ConfigurationProps) {
setErrorDateModalOpen(true);
return;
} else {
// console.log('asked for', dayjs(formValues.calibrationChargeDate));
//console.log('asked for', dayjs(formValues.calibrationChargeDate));
const configurationToSend: ConfigurationValues = {
minimumSoC: formValues.minimumSoC,
gridSetPoint: formValues.gridSetPoint,
CalibrationChargeState: formValues.CalibrationChargeState,
calibrationChargeDate: dayjs
.utc(formValues.calibrationChargeDate)
.add(localOffset, 'minute')
.toDate()
calibrationChargeDate: dayjs(formValues.calibrationChargeDate).toDate()
};
// console.log('will send ', dayjs(formValues.calibrationChargeDate));
setLoading(true);
const res = await axiosConfig
.post(
@ -160,11 +157,9 @@ function Configuration(props: ConfigurationProps) {
};
const handleConfirm = (newDate) => {
//console.log('non adapted day is ', newDate);
//console.log('adapted day is ', dayjs.utc(newDate).toDate());
setFormValues({
...formValues,
['calibrationChargeDate']: dayjs(newDate).toDate()
['calibrationChargeDate']: dayjs.utc(newDate).toDate()
});
};
@ -175,7 +170,6 @@ function Configuration(props: ConfigurationProps) {
if (difference < 0) {
difference += 7;
}
const adjustedDate = currentDate.add(difference, 'day');
setFormValues({
...formValues,
@ -191,11 +185,13 @@ function Configuration(props: ConfigurationProps) {
),
['calibrationChargeDate']:
CalibrationChargeOptions.indexOf(event.target.value) == 0
? dayjs(props.values.repetitiveCalibrationChargeDate[0].value)
// .add(localOffset, 'minute')
? dayjs
.utc(props.values.repetitiveCalibrationChargeDate[0].value)
.add(localOffset, 'minute')
.toDate()
: dayjs(props.values.additionalCalibrationChargeDate[0].value)
// .add(localOffset, 'minute')
: dayjs
.utc(props.values.additionalCalibrationChargeDate[0].value)
.add(localOffset, 'minute')
.toDate()
});
};
@ -353,7 +349,7 @@ function Configuration(props: ConfigurationProps) {
format="DD/MM/YYYY HH:mm"
ampm={false}
label="Select Next Calibration Charge Date"
value={dayjs(formValues.calibrationChargeDate)}
value={dayjs.utc(formValues.calibrationChargeDate)}
onChange={handleConfirm}
sx={{
marginTop: 2
@ -401,8 +397,8 @@ function Configuration(props: ConfigurationProps) {
<TimePicker
ampm={false}
label="Calibration Charge Hour"
value={dayjs(formValues.calibrationChargeDate)}
onChange={(newTime) => handleConfirm(dayjs(newTime))}
value={dayjs.utc(formValues.calibrationChargeDate)}
onChange={handleConfirm}
/>
</LocalizationProvider>
</div>

View File

@ -307,7 +307,7 @@ function Information(props: InformationProps) {
label="S3 Bucket Name"
name="s3writesecretkey"
value={
formValues.s3BucketId +
formValues.id +
'-3e5b3069-214a-43ee-8d85-57d72000c19d'
}
variant="outlined"

View File

@ -37,7 +37,7 @@ function InformationSalidomo(props: InformationSalidomoProps) {
const { currentUser } = context;
const theme = useTheme();
const [formValues, setFormValues] = useState(props.values);
const requiredFields = ['installationName', 'region', 'location', 'country'];
const requiredFields = ['name', 'region', 'location', 'country'];
const [openModalDeleteInstallation, setOpenModalDeleteInstallation] =
useState(false);
const navigate = useNavigate();
@ -194,7 +194,7 @@ function InformationSalidomo(props: InformationSalidomoProps) {
/>
}
name="installationName"
value={formValues.installationName}
value={formValues.name}
onChange={handleChange}
variant="outlined"
fullWidth
@ -280,8 +280,7 @@ function InformationSalidomo(props: InformationSalidomoProps) {
label="S3 Bucket Name"
name="s3writesecretkey"
value={
formValues.s3BucketId +
'-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e'
formValues.id + '-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e'
}
variant="outlined"
fullWidth

View File

@ -102,11 +102,11 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
<TableBody>
{props.installations.map((installation) => {
const isInstallationSelected =
installation.s3BucketId === selectedInstallation;
installation.id === selectedInstallation;
const status = getStatus(installation.id);
const rowStyles =
isRowHovered === installation.s3BucketId
isRowHovered === installation.id
? {
cursor: 'pointer',
backgroundColor: theme.colors.primary.lighter
@ -116,15 +116,13 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
return (
<TableRow
hover
key={installation.s3BucketId}
key={installation.id}
selected={isInstallationSelected}
style={rowStyles}
onClick={() =>
handleSelectOneInstallation(installation.s3BucketId)
}
onMouseEnter={() =>
handleRowMouseEnter(installation.s3BucketId)
handleSelectOneInstallation(installation.id)
}
onMouseEnter={() => handleRowMouseEnter(installation.id)}
onMouseLeave={() => handleRowMouseLeave()}
>
<TableCell>

View File

@ -1,11 +1,5 @@
import React, { useContext, useEffect, useState } from 'react';
import {
Card,
CircularProgress,
Container,
Grid,
Typography
} from '@mui/material';
import { Card, CircularProgress, Grid, Typography } from '@mui/material';
import { I_Installation } from 'src/interfaces/InstallationTypes';
import { UserContext } from 'src/contexts/userContext';
import AccessContextProvider from 'src/contexts/AccessContextProvider';
@ -45,14 +39,6 @@ function Installation(props: singleInstallationProps) {
const [currentTab, setCurrentTab] = useState<string>(undefined);
const [values, setValues] = useState<TopologyValues | null>(null);
const status = getStatus(props.current_installation.id);
const [
failedToCommunicateWithInstallation,
setFailedToCommunicateWithInstallation
] = useState(0);
const [
openModalUnableToCommunicateWIthInstallation,
setOpenModalUnableToCommunicateWIthInstallation
] = useState(false);
if (props.current_installation == undefined) {
return null;
@ -62,15 +48,14 @@ function Installation(props: singleInstallationProps) {
s3Region: props.current_installation.s3Region,
s3Provider: props.current_installation.s3Provider,
s3Key: props.current_installation.s3Key,
s3Secret: props.current_installation.s3Secret,
s3BucketId: props.current_installation.s3BucketId
s3Secret: props.current_installation.s3Secret
};
const s3Bucket =
props.current_installation.product === 0
? props.current_installation.s3BucketId.toString() +
? props.current_installation.id.toString() +
'-3e5b3069-214a-43ee-8d85-57d72000c19d'
: props.current_installation.s3BucketId.toString() +
: props.current_installation.id.toString() +
'-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e';
const s3Credentials = { s3Bucket, ...S3data };
@ -82,8 +67,6 @@ function Installation(props: singleInstallationProps) {
const res = await fetchData(now, s3Credentials);
if (res != FetchResult.notAvailable && res != FetchResult.tryLater) {
setFailedToCommunicateWithInstallation(0);
setOpenModalUnableToCommunicateWIthInstallation(false);
setValues(
extractValues({
time: now,
@ -91,13 +74,6 @@ function Installation(props: singleInstallationProps) {
})
);
return true;
} else {
setFailedToCommunicateWithInstallation((prevCount) => {
if (prevCount + 1 >= 3) {
setOpenModalUnableToCommunicateWIthInstallation(true);
}
return prevCount + 1;
});
}
} catch (err) {
return false;
@ -123,12 +99,6 @@ function Installation(props: singleInstallationProps) {
setCurrentTab(path[path.length - 1]);
}, [location]);
useEffect(() => {
if (status === -1) {
setOpenModalUnableToCommunicateWIthInstallation(true);
}
}, [status]);
useEffect(() => {
if (
currentTab == 'live' ||
@ -148,7 +118,7 @@ function Installation(props: singleInstallationProps) {
fetchDataOnlyOneTime();
}
// Cleanup function to cancel interval
// Cleanup function to cancel interval and update isMounted when unmounted
return () => {
if (
currentTab == 'live' ||
@ -160,10 +130,6 @@ function Installation(props: singleInstallationProps) {
}
}, [currentTab, location]);
const UnableToCommunicateModalHandleOk = () => {
setOpenModalUnableToCommunicateWIthInstallation(false);
};
return (
<>
<Grid item xs={12} md={12}>
@ -298,31 +264,6 @@ function Installation(props: singleInstallationProps) {
alignItems="stretch"
spacing={0}
>
{openModalUnableToCommunicateWIthInstallation && (
<Container
maxWidth="xl"
sx={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
height: '70vh'
}}
>
<CircularProgress size={60} style={{ color: '#ffc04d' }} />
<Typography
variant="body2"
style={{ color: 'black', fontWeight: 'bold' }}
mt={2}
>
Unable to communicate with the installation
</Typography>
<Typography variant="body2" style={{ color: 'black' }}>
Please wait or refresh the page
</Typography>
</Container>
)}
<Routes>
<Route
path={routes.information}
@ -342,7 +283,6 @@ function Installation(props: singleInstallationProps) {
values={values}
s3Credentials={s3Credentials}
installationId={props.current_installation.id}
productNum={props.current_installation.product}
></BatteryView>
}
></Route>

View File

@ -63,11 +63,11 @@ function InstallationSearch(props: installationSearchProps) {
{filteredData.map((installation) => {
return (
<Route
key={installation.s3BucketId}
path={routes.installation + installation.s3BucketId + '*'}
key={installation.id}
path={routes.installation + installation.id + '*'}
element={
<Installation
key={installation.s3BucketId}
key={installation.id}
current_installation={installation}
type="installation"
></Installation>

View File

@ -25,7 +25,6 @@ function installationForm(props: installationFormProps) {
const theme = useTheme();
const [open, setOpen] = useState(true);
const [formValues, setFormValues] = useState<Partial<I_Installation>>({
installationName: '',
name: '',
region: '',
location: '',
@ -33,14 +32,7 @@ function installationForm(props: installationFormProps) {
vpnIp: '',
orderNumbers: ''
});
const requiredFields = [
'installationName',
'name',
'region',
'location',
'country',
'vpnIp'
];
const requiredFields = ['name', 'region', 'location', 'country', 'vpnIp'];
const tokencontext = useContext(TokenContext);
const { removeToken } = tokencontext;
@ -113,21 +105,6 @@ function installationForm(props: installationFormProps) {
noValidate
autoComplete="off"
>
<div>
<TextField
label={
<FormattedMessage
id="installationName"
defaultMessage="Installation Name"
/>
}
name="installationName"
value={formValues.installationName}
onChange={handleChange}
required
error={formValues.installationName === ''}
/>
</div>
<div>
<TextField
label={
@ -143,7 +120,6 @@ function installationForm(props: installationFormProps) {
error={formValues.name === ''}
/>
</div>
<div>
<TextField
label={<FormattedMessage id="region" defaultMessage="Region" />}

View File

@ -174,6 +174,7 @@ const batteryPaths = [
'/Battery/Devices/%id%/Dc/Voltage',
'/Battery/Devices/%id%/Soc',
'/Battery/Devices/%id%/Temperatures/Cells/Average',
//'/Log/SalimaxWarnings/Battery/%id%',
'/Battery/Devices/%id%/Warnings',
'/Battery/Devices/%id%/Alarms',
@ -318,8 +319,6 @@ export const extractValues = (
): TopologyValues | null => {
const extractedValues: TopologyValues = {} as TopologyValues;
// console.log('timeSeriesData=', timeSeriesData);
for (const topologyKey of Object.keys(topologyPaths)) {
//Each topologykey may have more than one paths (for example inverter)
const paths = topologyPaths[topologyKey];

View File

@ -100,11 +100,11 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
<TableBody>
{props.installations.map((installation) => {
const isInstallationSelected =
installation.s3BucketId === selectedInstallation;
installation.id === selectedInstallation;
const status = getStatus(installation.id);
const rowStyles =
isRowHovered === installation.s3BucketId
isRowHovered === installation.id
? {
cursor: 'pointer',
backgroundColor: theme.colors.primary.lighter
@ -114,15 +114,13 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
return (
<TableRow
hover
key={installation.s3BucketId}
key={installation.id}
selected={isInstallationSelected}
style={rowStyles}
onClick={() =>
handleSelectOneInstallation(installation.s3BucketId)
}
onMouseEnter={() =>
handleRowMouseEnter(installation.s3BucketId)
handleSelectOneInstallation(installation.id)
}
onMouseEnter={() => handleRowMouseEnter(installation.id)}
onMouseLeave={() => handleRowMouseLeave()}
>
<TableCell>
@ -134,7 +132,7 @@ const FlatInstallationView = (props: FlatInstallationViewProps) => {
noWrap
sx={{ marginTop: '10px', fontSize: 'small' }}
>
{installation.installationName}
{installation.name}
</Typography>
</TableCell>

View File

@ -10,6 +10,7 @@ import {
} from 'src/content/dashboards/Log/graph.util';
import { WebSocketContext } from 'src/contexts/WebSocketContextProvider';
import { FormattedMessage } from 'react-intl';
import Overview from '../Overview/overview';
import { fetchData } from 'src/content/dashboards/Installations/fetchData';
import { Navigate, Route, Routes, useLocation } from 'react-router-dom';
import routes from '../../../Resources/routes.json';
@ -40,12 +41,11 @@ function Installation(props: singleInstallationProps) {
s3Region: props.current_installation.s3Region,
s3Provider: props.current_installation.s3Provider,
s3Key: props.current_installation.s3Key,
s3Secret: props.current_installation.s3Secret,
s3BucketId: props.current_installation.s3BucketId
s3Secret: props.current_installation.s3Secret
};
const s3Bucket =
props.current_installation.s3BucketId.toString() +
props.current_installation.id.toString() +
'-' +
'c0436b6a-d276-4cd8-9c44-1eae86cf5d0e';
@ -182,10 +182,13 @@ function Installation(props: singleInstallationProps) {
values={values}
s3Credentials={s3Credentials}
installationId={props.current_installation.id}
productNum={props.current_installation.product}
></BatteryView>
}
></Route>
<Route
path={routes.overview}
element={<Overview s3Credentials={s3Credentials}></Overview>}
/>
<Route
path={'*'}

View File

@ -107,11 +107,11 @@ function InstallationSearch(props: installationSearchProps) {
{filteredData.map((installation) => {
return (
<Route
key={installation.s3BucketId}
path={routes.installation + installation.s3BucketId + '*'}
key={installation.id}
path={routes.installation + installation.id + '*'}
element={
<Installation
key={installation.s3BucketId}
key={installation.id}
current_installation={installation}
type="installation"
></Installation>

View File

@ -23,20 +23,14 @@ function SalidomonstallationForm(props: SalidomoInstallationFormProps) {
const theme = useTheme();
const [open, setOpen] = useState(true);
const [formValues, setFormValues] = useState<Partial<I_Installation>>({
installationName: '',
name: '',
region: '',
location: '',
country: '',
vpnIp: '',
vrmLink: ''
});
const requiredFields = [
'installationName',
'location',
'country',
'vpnIp',
'vrmLink'
];
const requiredFields = ['name', 'location', 'country', 'vpnIp', 'vrmLink'];
const installationContext = useContext(InstallationsContext);
const { createInstallation, loading, setLoading, error, setError } =
installationContext;
@ -114,11 +108,11 @@ function SalidomonstallationForm(props: SalidomoInstallationFormProps) {
defaultMessage="Installation Name"
/>
}
name="installationName"
value={formValues.installationName}
name="name"
value={formValues.name}
onChange={handleChange}
required
error={formValues.installationName === ''}
error={formValues.name === ''}
/>
</div>
<div>

View File

@ -52,7 +52,7 @@ function CustomTreeItem(props: CustomTreeItemProps) {
routes.installations +
routes.tree +
routes.installation +
installation.s3BucketId +
installation.id +
'/' +
routes.live,
{

View File

@ -28,11 +28,7 @@ function InstallationTree() {
subnode != node &&
subnode.parentId == node.id && (
<TreeNode
key={
subnode.type == 'Installation'
? subnode.s3BucketId.toString() + subnode.type
: subnode.id.toString() + subnode.type
}
key={subnode.id.toString() + subnode.type}
node={subnode}
parent_id={node.id}
/>
@ -62,11 +58,7 @@ function InstallationTree() {
{foldersAndInstallations.map((node, index) => {
return (
<TreeNode
key={
node.type == 'Installation'
? node.s3BucketId.toString() + node.type
: node.id.toString() + node.type
}
key={node.id.toString() + node.type}
node={node}
parent_id={'0'}
/>
@ -80,11 +72,11 @@ function InstallationTree() {
if (installation.type == 'Installation') {
return (
<Route
key={installation.s3BucketId}
path={routes.installation + installation.s3BucketId + '*'}
key={installation.id}
path={routes.installation + installation.id + '*'}
element={
<Installation
key={installation.s3BucketId}
key={installation.id}
current_installation={installation}
type="installation"
></Installation>

View File

@ -25,6 +25,5 @@ export interface I_Folder {
information: string;
parentId: number;
type: string;
s3BucketId: number;
children?: (I_Installation | I_Folder)[];
}

View File

@ -3,8 +3,7 @@ export interface I_S3Credentials {
s3Provider: string;
s3Key: string;
s3Secret: string;
s3Bucket: string;
s3BucketId: number;
s3Bucket?: string;
}
export interface ErrorMessage {