{
if (
Object.hasOwnProperty.call(chartData[category].data, devicePath) &&
diff --git a/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx b/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx
index 40298e60b..2ce5bef64 100644
--- a/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx
+++ b/typescript/frontend-marios2/src/content/dashboards/Configuration/Configuration.tsx
@@ -18,7 +18,6 @@ import {
import React, { useState } from 'react';
import { FormattedMessage } from 'react-intl';
import Button from '@mui/material/Button';
-import { DateField } from '@mui/x-date-pickers/DateField';
import axiosConfig from '../../../Resources/axiosConfig';
import { Close as CloseIcon } from '@mui/icons-material';
import MenuItem from '@mui/material/MenuItem';
@@ -57,6 +56,8 @@ function Configuration(props: ConfigurationProps) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [updated, setUpdated] = useState(false);
+ const [dateSelectionError, setDateSelectionError] = useState('');
+ const [isErrorDateModalOpen, setErrorDateModalOpen] = useState(false);
const [openForcedCalibrationCharge, setOpenForcedCalibrationCharge] =
useState(false);
const [
@@ -65,19 +66,13 @@ function Configuration(props: ConfigurationProps) {
] = useState(
props.values.calibrationChargeForced[0].value.toString()
);
- 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({
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)
+ calibrationChargeDate: null
});
const handleSubmit = async (e) => {
@@ -97,30 +92,24 @@ function Configuration(props: ConfigurationProps) {
}
};
- 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');
+ const handleConfirm = (newDate) => {
+ if (newDate.isBefore(dayjs())) {
+ setDateSelectionError('You must specify a future date');
setErrorDateModalOpen(true);
return;
}
- setDateFieldOpen(true);
+ setFormValues({
+ ...formValues,
+ ['calibrationChargeDate']: newDate.toDate()
+ });
};
const handleSelectedCalibrationChargeChange = (event) => {
- if (event.target.value != 'ChargePermanently') {
- setIsDateModalOpen(true);
- }
setSelectedForcedCalibrationChargeOption(event.target.value);
setFormValues({
@@ -181,6 +170,47 @@ function Configuration(props: ConfigurationProps) {
alignItems="stretch"
spacing={3}
>
+ {isErrorDateModalOpen && (
+ {}}>
+
+
+ {dateSelectionError}
+
+
+
+
+
+ )}
- {(dateFieldOpen || formValues.forceCalibrationCharge != 2) && (
+ {formValues.forceCalibrationCharge != 2 && (
-
)}
- {isErrorDateModalOpen && (
-
{}}>
-
-
- {dateSelectionError}
-
-
-
-
-
- )}
-
- {isDateModalOpen && (
-
- {}}>
-
-
- setCalibrationChargeDate(newDate)
- }
- sx={{
- marginTop: 2
- }}
- />
-
-
-
-
-
-
-
-
-
- )}
-
)}
- {error && (
-
- An error has occurred
- setError(false)} // Set error state to false on click
- sx={{ marginLeft: '4px' }}
- >
-
-
-
- )}
+
{updated && (
key: [{unit:'',value:''},{unit:'',value:''},...]
+//battery_view: [ {"Battery_id": 2,'FwVersion': {'unit':,'value':}},
+// {"Battery_id": 4,'FwVersion': {'unit':,'value':}}
+//]
+//For batteries, we follow a different approach. We define a key battery_view that is of type Battery[]
+
export const extractValues = (
timeSeriesData: DataPoint
): TopologyValues | null => {
const extractedValues: TopologyValues = {} as TopologyValues;
for (const topologyKey of Object.keys(topologyPaths)) {
+ //Each topologykey may have more than one paths (for example inverter)
const paths = topologyPaths[topologyKey];
let topologyValues: { unit: string; value: string | number }[] = [];
if (topologyKey === 'batteryView') {
extractedValues[topologyKey] = [];
- const battery_ids_from_csv = timeSeriesData.value[
+ const node_ids_from_csv = timeSeriesData.value[
'/Config/Devices/BatteryNodes'
].value
.toString()
@@ -322,7 +338,11 @@ export const extractValues = (
while (pathIndex < paths.length) {
let battery = {};
let existingKeys = 0;
- battery[BatteryKeys[0]] = battery_ids_from_csv[battery_index];
+
+ //We prepare a battery object for each node. We extract the nodes from the '/Config/Devices/BatteryNodes' path. For example, nodes can be [2,4,5,6] (one is missing)
+ //BatteryKeys[0] is the battery id. We set the battery id to the corresponding node id.
+ battery[BatteryKeys[0]] = node_ids_from_csv[battery_index];
+ //Then, search all the remaining battery keys
for (let i = 1; i < BatteryKeys.length; i++) {
const path = paths[pathIndex];
if (timeSeriesData.value.hasOwnProperty(path)) {
diff --git a/typescript/frontend-marios2/src/interfaces/Chart.tsx b/typescript/frontend-marios2/src/interfaces/Chart.tsx
index 804c0d475..d253827e7 100644
--- a/typescript/frontend-marios2/src/interfaces/Chart.tsx
+++ b/typescript/frontend-marios2/src/interfaces/Chart.tsx
@@ -61,6 +61,17 @@ export interface BatteryOverviewInterface {
Current: chartInfoInterface;
}
+// We use this function in order to retrieve data for main stats.
+//The data is of the following form:
+//'Soc' : {name:'Soc',data:[
+// 'Node1': {name:'Node1', data: [[timestamp,value],[timestamp,value]]},
+// 'Node2': {name:'Node2', data: [[timestamp,value],[timestamp,value]]},
+// ]},
+//'Temperature' : {name:'Temperature',data:[
+// 'Node1': {name:'Node1', data: [[timestamp,value],[timestamp,value]]},
+// 'Node2': {name:'Node2', data: [[timestamp,value],[timestamp,value]]},
+// ]}
+
export const transformInputToBatteryViewData = async (
s3Credentials: I_S3Credentials,
startTimestamp: UnixTime,
@@ -94,18 +105,7 @@ export const transformInputToBatteryViewData = async (
'/Battery/Devices/10/'
];
- const pathsToSave = [
- 'Battery1',
- 'Battery2',
- 'Battery3',
- 'Battery4',
- 'Battery5',
- 'Battery6',
- 'Battery7',
- 'Battery8',
- 'Battery9',
- 'Battery10'
- ];
+ const pathsToSave = [];
const chartData: BatteryDataInterface = {
Soc: { name: 'State Of Charge', data: [] },
@@ -123,20 +123,7 @@ export const transformInputToBatteryViewData = async (
Current: { magnitude: 0, unit: '', min: 0, max: 0 }
};
- categories.forEach((category) => {
- chartData[category].data = [];
- pathsToSave.forEach((path) => {
- chartData[category].data[path] = { name: path, data: [] };
- });
-
- chartOverview[category] = {
- magnitude: 0,
- unit: '',
- min: MAX_NUMBER,
- max: -MAX_NUMBER
- };
- });
-
+ let initialiation = true;
let adjustedTimestampArray = [];
let startTimestampToNum = Number(startTimestamp);
@@ -160,6 +147,7 @@ export const transformInputToBatteryViewData = async (
adjustedTimestampArray.push(adjustedTimestamp);
}
+ //Wait until fetching all the data
const results = await Promise.all(timestampPromises);
for (let i = 0; i < results.length; i++) {
@@ -170,6 +158,32 @@ export const transformInputToBatteryViewData = async (
) {
// Handle not available or try later case
} else {
+ const battery_nodes = result['/Config/Devices/BatteryNodes'].value
+ .toString()
+ .split(',');
+
+ //Initialize the chartData structure based on the node names extracted from the first result
+ if (initialiation) {
+ initialiation = false;
+
+ battery_nodes.forEach((node) => {
+ pathsToSave.push('Node' + node);
+ });
+ categories.forEach((category) => {
+ chartData[category].data = [];
+ pathsToSave.forEach((path) => {
+ chartData[category].data[path] = { name: path, data: [] };
+ });
+
+ chartOverview[category] = {
+ magnitude: 0,
+ unit: '',
+ min: MAX_NUMBER,
+ max: -MAX_NUMBER
+ };
+ });
+ }
+
for (
let category_index = 0;
category_index < pathCategories.length;