Merge remote-tracking branch 'origin/main'

This commit is contained in:
atef 2024-02-05 15:31:00 +01:00
commit b61ca9264e
5 changed files with 208 additions and 175 deletions

View File

@ -39,7 +39,10 @@ export function findPower(value) {
value = Math.abs(value); value = Math.abs(value);
// Calculate the power of 10 that's greater or equal to the absolute value // Calculate the power of 10 that's greater or equal to the absolute value
const exponent = Math.floor(Math.log10(value)); const exponent =
value < 1
? -(Math.floor(Math.abs(Math.log10(value))) + 1)
: Math.floor(Math.log10(value));
// Compute the nearest power of 10 // Compute the nearest power of 10
const nearestPowerOf10 = Math.pow(10, exponent); const nearestPowerOf10 = Math.pow(10, exponent);

View File

@ -18,7 +18,7 @@ function Footer() {
> >
<Box> <Box>
<Typography variant="subtitle1"> <Typography variant="subtitle1">
&copy; 2023 - InnovEnergy AG &copy; 2024 - InnovEnergy AG
</Typography> </Typography>
</Box> </Box>
<Typography <Typography

View File

@ -24,6 +24,9 @@ export const getChartOptions = (
dataLabels: { dataLabels: {
enabled: false enabled: false
}, },
fill: {
type: 'solid'
},
colors: ['#3498db', '#2ecc71', '#282828'], colors: ['#3498db', '#2ecc71', '#282828'],
xaxis: { xaxis: {
@ -210,7 +213,9 @@ export const getChartOptions = (
}, },
plotOptions: { plotOptions: {
bar: { bar: {
borderRadius: [10], //If min<0 and max>0, then we have 2 stacked bars, one with positive and one with negative values, so each one of them should have border radius. \
//Otherwise, we have a single bar or two stacked bars either with positive or negative values.
borderRadius: chartInfo.min <= 0 && chartInfo.max > 0 ? [10] : 10,
dataLabels: { dataLabels: {
position: 'top' position: 'top'
} }
@ -253,13 +258,29 @@ export const getChartOptions = (
: chartInfo.max <= 0 : chartInfo.max <= 0
? Math.ceil(chartInfo.min / findPower(chartInfo.min).value) * ? Math.ceil(chartInfo.min / findPower(chartInfo.min).value) *
findPower(chartInfo.min).value findPower(chartInfo.min).value
: Math.abs(chartInfo.min) < 1
? -Math.max(
Math.ceil(chartInfo.min / findPower(chartInfo.min).value) *
findPower(chartInfo.min).value,
Math.ceil(chartInfo.max / findPower(chartInfo.max).value) *
findPower(chartInfo.max).value
).toFixed(2)
: undefined, : undefined,
max: max:
chartInfo.min >= 0 chartInfo.min >= 0
? Math.ceil(chartInfo.max / findPower(chartInfo.max).value) * ? +(
findPower(chartInfo.max).value Math.ceil(chartInfo.max / findPower(chartInfo.max).value) *
findPower(chartInfo.max).value
).toFixed(2)
: chartInfo.max <= 0 : chartInfo.max <= 0
? 0 ? 0
: Math.abs(chartInfo.min) < 1
? +Math.max(
Math.ceil(chartInfo.min / findPower(chartInfo.min).value) *
findPower(chartInfo.min).value,
Math.ceil(chartInfo.max / findPower(chartInfo.max).value) *
findPower(chartInfo.max).value
).toFixed(2)
: undefined, : undefined,
title: { title: {
text: chartInfo.unit, text: chartInfo.unit,
@ -282,11 +303,9 @@ export const getChartOptions = (
tooltip: { tooltip: {
y: { y: {
formatter: function (val) { formatter: function (val) {
return ( return val < 1
formatPowerForGraph(val, chartInfo.magnitude).value.toFixed(2) + ? val.toFixed(3) + ' ' + chartInfo.unit
' ' + : val.toFixed(2) + ' ' + chartInfo.unit;
chartInfo.unit
);
} }
} }
} }

View File

@ -786,7 +786,12 @@ function Overview(props: OverviewProps) {
} }
} }
}} }}
series={[dailyDataArray[chartState].chartData.soc]} series={[
{
...dailyDataArray[chartState].chartData.soc,
color: '#69d2e7'
}
]}
type="area" type="area"
height={400} height={400}
/> />
@ -890,7 +895,12 @@ function Overview(props: OverviewProps) {
} }
} }
}} }}
series={[dailyDataArray[chartState].chartData.dcPower]} series={[
{
...dailyDataArray[chartState].chartData.dcPower,
color: '#69d2e7'
}
]}
type="area" type="area"
height={400} height={400}
/> />
@ -1004,7 +1014,11 @@ function Overview(props: OverviewProps) {
} }
}} }}
series={[ series={[
dailyDataArray[chartState].chartData.pvProduction {
...dailyDataArray[chartState].chartData
.pvProduction,
color: '#ff9900'
}
]} ]}
type="area" type="area"
height={400} height={400}
@ -1102,7 +1116,10 @@ function Overview(props: OverviewProps) {
} }
}} }}
series={[ series={[
dailyDataArray[chartState].chartData.gridPower {
...dailyDataArray[chartState].chartData.gridPower,
color: '#ff3333'
}
]} ]}
type="area" type="area"
height={400} height={400}
@ -1160,124 +1177,124 @@ function Overview(props: OverviewProps) {
</Grid> </Grid>
)} )}
{dailyData && currentUser.hasWriteAccess && ( {/*{dailyData && currentUser.hasWriteAccess && (*/}
<Grid {/* <Grid*/}
container {/* container*/}
direction="row" {/* direction="row"*/}
justifyContent="center" {/* justifyContent="center"*/}
alignItems="stretch" {/* alignItems="stretch"*/}
spacing={3} {/* spacing={3}*/}
> {/* >*/}
<Grid item md={6} xs={12}> {/* <Grid item md={6} xs={12}>*/}
<Card {/* <Card*/}
sx={{ {/* sx={{*/}
overflow: 'visible', {/* overflow: 'visible',*/}
marginTop: '30px', {/* marginTop: '30px',*/}
marginBottom: '30px' {/* marginBottom: '30px'*/}
}} {/* }}*/}
> {/* >*/}
<Box {/* <Box*/}
sx={{ {/* sx={{*/}
marginLeft: '20px' {/* marginLeft: '20px'*/}
}} {/* }}*/}
> {/* >*/}
<Box display="flex" alignItems="center"> {/* <Box display="flex" alignItems="center">*/}
<Box> {/* <Box>*/}
<Typography variant="subtitle1" noWrap> {/* <Typography variant="subtitle1" noWrap>*/}
<FormattedMessage {/* <FormattedMessage*/}
id="battery_temperature" {/* id="battery_temperature"*/}
defaultMessage="Battery Temperature" {/* defaultMessage="Battery Temperature"*/}
/> {/* />*/}
</Typography> {/* </Typography>*/}
</Box> {/* </Box>*/}
</Box> {/* </Box>*/}
<Box {/* <Box*/}
sx={{ {/* sx={{*/}
display: 'flex', {/* display: 'flex',*/}
alignItems: 'center', {/* alignItems: 'center',*/}
justifyContent: 'flex-start', {/* justifyContent: 'flex-start',*/}
pt: 3 {/* pt: 3*/}
}} {/* }}*/}
></Box> {/* ></Box>*/}
</Box> {/* </Box>*/}
<ReactApexChart {/* <ReactApexChart*/}
options={{ {/* options={{*/}
...getChartOptions( {/* ...getChartOptions(*/}
dailyDataArray[chartState].chartOverview {/* dailyDataArray[chartState].chartOverview*/}
.temperature, {/* .temperature,*/}
'daily', {/* 'daily',*/}
[] {/* []*/}
), {/* ),*/}
chart: { {/* chart: {*/}
events: { {/* events: {*/}
beforeZoom: handleBeforeZoom {/* beforeZoom: handleBeforeZoom*/}
} {/* }*/}
} {/* }*/}
}} {/* }}*/}
series={[ {/* series={[*/}
dailyDataArray[chartState].chartData.temperature {/* dailyDataArray[chartState].chartData.temperature*/}
]} {/* ]}*/}
type="area" {/* type="area"*/}
height={400} {/* height={400}*/}
/> {/* />*/}
</Card> {/* </Card>*/}
</Grid> {/* </Grid>*/}
<Grid item md={6} xs={12}> {/* <Grid item md={6} xs={12}>*/}
<Card {/* <Card*/}
sx={{ {/* sx={{*/}
overflow: 'visible', {/* overflow: 'visible',*/}
marginTop: '30px', {/* marginTop: '30px',*/}
marginBottom: '30px' {/* marginBottom: '30px'*/}
}} {/* }}*/}
> {/* >*/}
<Box {/* <Box*/}
sx={{ {/* sx={{*/}
marginLeft: '20px' {/* marginLeft: '20px'*/}
}} {/* }}*/}
> {/* >*/}
<Box display="flex" alignItems="center"> {/* <Box display="flex" alignItems="center">*/}
<Box> {/* <Box>*/}
<Typography variant="subtitle1" noWrap> {/* <Typography variant="subtitle1" noWrap>*/}
<FormattedMessage {/* <FormattedMessage*/}
id="dc_voltage" {/* id="dc_voltage"*/}
defaultMessage="DC Bus Voltage" {/* defaultMessage="DC Bus Voltage"*/}
/> {/* />*/}
</Typography> {/* </Typography>*/}
</Box> {/* </Box>*/}
</Box> {/* </Box>*/}
<Box {/* <Box*/}
sx={{ {/* sx={{*/}
display: 'flex', {/* display: 'flex',*/}
alignItems: 'center', {/* alignItems: 'center',*/}
justifyContent: 'flex-start', {/* justifyContent: 'flex-start',*/}
pt: 3 {/* pt: 3*/}
}} {/* }}*/}
></Box> {/* ></Box>*/}
</Box> {/* </Box>*/}
<ReactApexChart {/* <ReactApexChart*/}
options={{ {/* options={{*/}
...getChartOptions( {/* ...getChartOptions(*/}
dailyDataArray[chartState].chartOverview {/* dailyDataArray[chartState].chartOverview*/}
.dcBusVoltage, {/* .dcBusVoltage,*/}
'daily', {/* 'daily',*/}
[] {/* []*/}
), {/* ),*/}
chart: { {/* chart: {*/}
events: { {/* events: {*/}
beforeZoom: handleBeforeZoom {/* beforeZoom: handleBeforeZoom*/}
} {/* }*/}
} {/* }*/}
}} {/* }}*/}
series={[ {/* series={[*/}
dailyDataArray[chartState].chartData.dcBusVoltage {/* dailyDataArray[chartState].chartData.dcBusVoltage*/}
]} {/* ]}*/}
type="area" {/* type="area"*/}
height={400} {/* height={400}*/}
/> {/* />*/}
</Card> {/* </Card>*/}
</Grid> {/* </Grid>*/}
</Grid> {/* </Grid>*/}
)} {/*)}*/}
</Grid> </Grid>
)} )}
</Grid> </Grid>

View File

@ -93,6 +93,8 @@ export const transformInputToDailyData = async (
}; };
}); });
let adjustedTimestampArray = [];
let startTimestampToNum = Number(startTimestamp); let startTimestampToNum = Number(startTimestamp);
if (startTimestampToNum % 2 != 0) { if (startTimestampToNum % 2 != 0) {
startTimestampToNum += 1; startTimestampToNum += 1;
@ -100,22 +102,32 @@ export const transformInputToDailyData = async (
let startUnixTime = UnixTime.fromTicks(startTimestampToNum); let startUnixTime = UnixTime.fromTicks(startTimestampToNum);
let diff = endTimestamp.ticks - startUnixTime.ticks; let diff = endTimestamp.ticks - startUnixTime.ticks;
const timestampPromises = [];
while (startUnixTime < endTimestamp) { while (startUnixTime < endTimestamp) {
let result = await Promise.resolve(fetchData(startUnixTime, s3Credentials)); timestampPromises.push(fetchData(startUnixTime, s3Credentials));
startUnixTime = UnixTime.fromTicks(startUnixTime.ticks + diff / 100);
if (startUnixTime.ticks % 2 !== 0) {
startUnixTime = UnixTime.fromTicks(startUnixTime.ticks + 1);
}
const adjustedTimestamp = new Date(startUnixTime.ticks * 1000);
adjustedTimestamp.setHours(adjustedTimestamp.getHours() + 1);
adjustedTimestampArray.push(adjustedTimestamp);
}
const results = await Promise.all(timestampPromises);
for (let i = 0; i < results.length; i++) {
const result = results[i];
if ( if (
result === FetchResult.notAvailable || result === FetchResult.notAvailable ||
result === FetchResult.tryLater result === FetchResult.tryLater
) { ) {
// Handle not available or try later case // Handle not available or try later case
} else { } else {
//console.log('Received data:', result);
// eslint-disable-next-line @typescript-eslint/no-loop-func // eslint-disable-next-line @typescript-eslint/no-loop-func
pathsToSearch.forEach((path) => { pathsToSearch.forEach((path) => {
const timestamp = startUnixTime.ticks * 1000;
const adjustedTimestamp = new Date(timestamp);
adjustedTimestamp.setHours(adjustedTimestamp.getHours() + 1);
if (result[path]) { if (result[path]) {
const value = result[path]; const value = result[path];
@ -127,21 +139,13 @@ export const transformInputToDailyData = async (
overviewData[path].max = value.value; overviewData[path].max = value.value;
} }
data[path].push([adjustedTimestamp, value.value]); data[path].push([adjustedTimestampArray[i], value.value]);
} else { } else {
//data[path].push([adjustedTimestamp, null]); //data[path].push([adjustedTimestamp, null]);
} }
}); });
} }
startUnixTime = UnixTime.fromTicks(startUnixTime.ticks + diff / 100);
if (startUnixTime.ticks % 2 != 0) {
startUnixTime = UnixTime.fromTicks(startUnixTime.ticks + 1);
}
console.log('Try next timestamp: ', startUnixTime);
} }
pathsToSearch.forEach((path) => { pathsToSearch.forEach((path) => {
let value = Math.max( let value = Math.max(
Math.abs(overviewData[path].max), Math.abs(overviewData[path].max),
@ -234,9 +238,6 @@ export const transformInputToDailyData = async (
) )
}; };
console.log('min = ', chartOverview.overview.min);
console.log('max = ', chartOverview.overview.max);
return { return {
chartData: chartData, chartData: chartData,
chartOverview: chartOverview chartOverview: chartOverview
@ -302,31 +303,25 @@ export const transformInputToAggregatedData = async (
}; };
}); });
let fake_data = [ const timestampPromises = [];
'temp0',
'temp1',
'temp2',
'temp3',
'temp4',
'temp5',
'temp6'
];
while (currentDay.isBefore(currentDate)) { while (currentDay.isBefore(currentDate)) {
//for (let i = 0; i < 7; i++) { timestampPromises.push(
// console.log('Current day:', currentDay.format('YYYY-MM-DD'));
let result = await Promise.resolve(
fetchDailyData(currentDay.format('YYYY-MM-DD'), s3Credentials) fetchDailyData(currentDay.format('YYYY-MM-DD'), s3Credentials)
//fetchDailyData(fake_data[i], s3Credentials)
); );
currentDay = currentDay.add(1, 'day');
}
const results = await Promise.all(timestampPromises);
for (let i = 0; i < results.length; i++) {
const result = results[i];
if ( if (
result === FetchResult.notAvailable || result === FetchResult.notAvailable ||
result === FetchResult.tryLater result === FetchResult.tryLater
) { ) {
// Handle not available or try later case // Handle not available or try later case
} else { } else {
console.log('Received data:', result);
dateList.push(currentDay.format('DD-MM')); dateList.push(currentDay.format('DD-MM'));
pathsToSearch.forEach((path) => { pathsToSearch.forEach((path) => {
if (result[path]) { if (result[path]) {
@ -337,12 +332,13 @@ export const transformInputToAggregatedData = async (
if (result[path].value > overviewData[path].max) { if (result[path].value > overviewData[path].max) {
overviewData[path].max = result[path].value; overviewData[path].max = result[path].value;
} }
if (path === '/SumGridExportPower' && result[path].value < 0.1) {
result[path].value = 0.3;
}
data[path].push(result[path].value as number); data[path].push(result[path].value as number);
} }
}); });
} }
// Add one day to move to the next day
currentDay = currentDay.add(1, 'day');
} }
pathsToSearch.forEach((path) => { pathsToSearch.forEach((path) => {
@ -419,14 +415,12 @@ export const transformInputToAggregatedData = async (
overviewData['/SumGridExportPower'].magnitude overviewData['/SumGridExportPower'].magnitude
), ),
unit: '(kWh)', unit: '(kWh)',
min: Math.min( min:
overviewData['/SumGridImportPower'].min, overviewData['/SumGridImportPower'].min +
overviewData['/SumGridExportPower'].min overviewData['/SumGridExportPower'].min,
), max:
max: Math.max( overviewData['/SumGridImportPower'].max +
overviewData['/SumGridImportPower'].max,
overviewData['/SumGridExportPower'].max overviewData['/SumGridExportPower'].max
)
}; };
chartOverview.overview = { chartOverview.overview = {