added Last Week option in Overview for Sinexcel and corrected Unit of Loads and commented Last Week for Growatt

This commit is contained in:
Yinyin Liu 2026-03-11 14:17:40 +01:00
parent 591e273bc7
commit b4a296fd8a
4 changed files with 145 additions and 21 deletions

View File

@ -110,7 +110,8 @@ export const fetchDataJson = (
export const fetchAggregatedDataJson = ( export const fetchAggregatedDataJson = (
date: string, date: string,
s3Credentials?: I_S3Credentials s3Credentials?: I_S3Credentials,
product?: number
): Promise<FetchResult<any>> => { ): Promise<FetchResult<any>> => {
const s3Path = `${date}.json`; const s3Path = `${date}.json`;
@ -128,7 +129,12 @@ export const fetchAggregatedDataJson = (
if (r.status === 404) { if (r.status === 404) {
return Promise.resolve(FetchResult.notAvailable); return Promise.resolve(FetchResult.notAvailable);
} else if (r.status === 200) { } else if (r.status === 200) {
const jsontext = await r.text(); // Assuming the server returns the Base64 encoded ZIP file as text const jsontext = await r.text();
if (product === 2) {
return parseSinexcelAggregatedData(jsontext);
}
const contentEncoding = r.headers.get('content-type'); const contentEncoding = r.headers.get('content-type');
if (contentEncoding != 'application/base64; charset=utf-8') { if (contentEncoding != 'application/base64; charset=utf-8') {
@ -142,7 +148,6 @@ export const fetchAggregatedDataJson = (
const zip = await JSZip.loadAsync(byteArray); const zip = await JSZip.loadAsync(byteArray);
// Assuming the CSV file is named "data.csv" inside the ZIP archive // Assuming the CSV file is named "data.csv" inside the ZIP archive
const jsonContent = await zip.file('data.json').async('text'); const jsonContent = await zip.file('data.json').async('text');
//console.log(jsonContent);
return JSON.parse(jsonContent); return JSON.parse(jsonContent);
} else { } else {
return Promise.resolve(FetchResult.notAvailable); return Promise.resolve(FetchResult.notAvailable);
@ -154,6 +159,24 @@ export const fetchAggregatedDataJson = (
} }
}; };
const parseSinexcelAggregatedData = (jsontext: string): any => {
const lines = jsontext.trim().split('\n');
for (const line of lines) {
const entry = JSON.parse(line);
if (entry.Type === 'Daily') {
return {
PvPower: entry.DailySelfGeneratedElectricity ?? 0,
GridImportPower: entry.DailyElectricityPurchased ?? 0,
GridExportPower: -(entry.DailyElectricityFed ?? 0),
ChargingBatteryPower: entry.BatteryDailyChargeEnergy ?? 0,
DischargingBatteryPower: -(entry.BatteryDailyDischargeEnergy ?? 0),
LoadPowerConsumption: entry.DailyLoadPowerConsumption ?? 0
};
}
}
return FetchResult.notAvailable;
};
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -33,6 +33,7 @@ import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
interface OverviewProps { interface OverviewProps {
s3Credentials: I_S3Credentials; s3Credentials: I_S3Credentials;
id: number; id: number;
device?: number;
} }
const computeLast7Days = (): string[] => { const computeLast7Days = (): string[] => {
@ -210,11 +211,19 @@ function Overview(props: OverviewProps) {
}> = transformInputToAggregatedDataJson( }> = transformInputToAggregatedDataJson(
props.s3Credentials, props.s3Credentials,
dayjs().subtract(1, 'week'), dayjs().subtract(1, 'week'),
dayjs() dayjs(),
product
); );
resultPromise resultPromise
.then((result) => { .then((result) => {
if (result.dateList.length === 0) {
setDateSelectionError(intl.formatMessage({ id: 'noDataForDateRange' }));
setErrorDateModalOpen(true);
setLoading(false);
return;
}
const powerDifference = []; const powerDifference = [];
for ( for (
let i = 0; let i = 0;
@ -320,11 +329,19 @@ function Overview(props: OverviewProps) {
}> = transformInputToAggregatedDataJson( }> = transformInputToAggregatedDataJson(
props.s3Credentials, props.s3Credentials,
startDate, startDate,
endDate endDate,
product
); );
resultPromise resultPromise
.then((result) => { .then((result) => {
if (result.dateList.length === 0) {
setDateSelectionError(intl.formatMessage({ id: 'noDataForDateRange' }));
setErrorDateModalOpen(true);
setLoading(false);
return;
}
const powerDifference = []; const powerDifference = [];
for ( for (
@ -524,6 +541,7 @@ function Overview(props: OverviewProps) {
> >
<FormattedMessage id="24_hours" defaultMessage="24-hours" /> <FormattedMessage id="24_hours" defaultMessage="24-hours" />
</Button> </Button>
{props.device !== 3 && (
<Button <Button
variant="contained" variant="contained"
onClick={handleWeekData} onClick={handleWeekData}
@ -538,8 +556,8 @@ function Overview(props: OverviewProps) {
> >
<FormattedMessage id="lastweek" defaultMessage="Last week" /> <FormattedMessage id="lastweek" defaultMessage="Last week" />
</Button> </Button>
)}
{/*{aggregatedData && (*/}
<Button <Button
variant="contained" variant="contained"
onClick={handleSetDate} onClick={handleSetDate}
@ -554,7 +572,6 @@ function Overview(props: OverviewProps) {
> >
<FormattedMessage id="set_date" defaultMessage="Set Date" /> <FormattedMessage id="set_date" defaultMessage="Set Date" />
</Button> </Button>
{/*)}*/}
</Grid> </Grid>
<Grid <Grid
@ -766,7 +783,7 @@ function Overview(props: OverviewProps) {
{ {
...aggregatedDataArray[aggregatedChartState] ...aggregatedDataArray[aggregatedChartState]
.chartData.gridExportPower, .chartData.gridExportPower,
color: '#ff3333', color: '#2e7d32',
type: 'bar' type: 'bar'
}, },
{ {
@ -775,13 +792,13 @@ function Overview(props: OverviewProps) {
type: 'bar', type: 'bar',
color: '#ff9900' color: '#ff9900'
}, },
{ ...(product !== 2 ? [{
name: 'Net Energy', name: 'Net Energy',
color: '#ff3333', color: '#e65100',
type: 'line', type: 'line',
data: aggregatedDataArray[aggregatedChartState] data: aggregatedDataArray[aggregatedChartState]
.netbalance .netbalance
} }] : [])
]} ]}
height={400} height={400}
type={'bar'} type={'bar'}
@ -798,6 +815,7 @@ function Overview(props: OverviewProps) {
alignItems="stretch" alignItems="stretch"
spacing={3} spacing={3}
> >
{!(aggregatedData && product === 2) && (
<Grid item md={6} xs={12}> <Grid item md={6} xs={12}>
<Card <Card
sx={{ sx={{
@ -889,7 +907,8 @@ function Overview(props: OverviewProps) {
)} )}
</Card> </Card>
</Grid> </Grid>
<Grid item md={6} xs={12}> )}
<Grid item md={(aggregatedData && product === 2) ? 12 : 6} xs={12}>
<Card <Card
sx={{ sx={{
overflow: 'visible', overflow: 'visible',
@ -957,11 +976,14 @@ function Overview(props: OverviewProps) {
<ReactApexChart <ReactApexChart
options={{ options={{
...getChartOptions( ...getChartOptions(
aggregatedDataArray[aggregatedChartState] product === 2
? aggregatedDataArray[aggregatedChartState]
.chartOverview.dcPowerWithoutHeating
: aggregatedDataArray[aggregatedChartState]
.chartOverview.dcPower, .chartOverview.dcPower,
'weekly', 'weekly',
aggregatedDataArray[aggregatedChartState].datelist, aggregatedDataArray[aggregatedChartState].datelist,
false product === 2
) )
}} }}
series={[ series={[
@ -970,11 +992,11 @@ function Overview(props: OverviewProps) {
.chartData.dcChargingPower, .chartData.dcChargingPower,
color: '#008FFB' color: '#008FFB'
}, },
{ ...(product !== 2 ? [{
...aggregatedDataArray[aggregatedChartState] ...aggregatedDataArray[aggregatedChartState]
.chartData.heatingPower, .chartData.heatingPower,
color: '#ff9900' color: '#ff9900'
}, }] : []),
{ {
...aggregatedDataArray[aggregatedChartState] ...aggregatedDataArray[aggregatedChartState]
.chartData.dcDischargingPower, .chartData.dcDischargingPower,
@ -1345,6 +1367,63 @@ function Overview(props: OverviewProps) {
</Grid> </Grid>
</Grid> </Grid>
{aggregatedData && product === 2 && (
<Grid
container
direction="row"
justifyContent="center"
alignItems="stretch"
spacing={3}
>
<Grid item md={12} xs={12}>
<Card
sx={{
overflow: 'visible',
marginTop: '30px',
marginBottom: '30px'
}}
>
<Box
sx={{
marginLeft: '20px'
}}
>
<Box display="flex" alignItems="center">
<Box>
<Typography variant="subtitle1" noWrap>
<FormattedMessage
id="ac_load_aggregated"
defaultMessage="AC Load Energy"
/>
</Typography>
</Box>
</Box>
</Box>
<ReactApexChart
options={{
...getChartOptions(
aggregatedDataArray[aggregatedChartState]
.chartOverview.ACLoad,
'weekly',
aggregatedDataArray[aggregatedChartState].datelist,
true
)
}}
series={[
{
...aggregatedDataArray[aggregatedChartState]
.chartData.acLoad,
color: '#ff9900'
}
]}
type="bar"
height={400}
/>
</Card>
</Grid>
</Grid>
)}
{dailyData && ( {dailyData && (
<Grid <Grid
container container

View File

@ -593,6 +593,7 @@ function SodioHomeInstallation(props: singleInstallationProps) {
<Overview <Overview
s3Credentials={s3Credentials} s3Credentials={s3Credentials}
id={props.current_installation.id} id={props.current_installation.id}
device={props.current_installation.device}
/> />
} }
/> />

View File

@ -41,6 +41,7 @@ export interface chartAggregatedDataInterface {
gridImportPower: { name: string; data: number[] }; gridImportPower: { name: string; data: number[] };
gridExportPower: { name: string; data: number[] }; gridExportPower: { name: string; data: number[] };
heatingPower: { name: string; data: number[] }; heatingPower: { name: string; data: number[] };
acLoad: { name: string; data: number[] };
} }
export interface chartDataInterface { export interface chartDataInterface {
@ -604,6 +605,10 @@ export const transformInputToDailyDataJson = async (
'(' + prefixes[chartOverview['pvProduction'].magnitude] + 'W' + ')'; '(' + prefixes[chartOverview['pvProduction'].magnitude] + 'W' + ')';
chartOverview.dcBusVoltage.unit = chartOverview.dcBusVoltage.unit =
'(' + prefixes[chartOverview['dcBusVoltage'].magnitude] + 'V' + ')'; '(' + prefixes[chartOverview['dcBusVoltage'].magnitude] + 'V' + ')';
chartOverview.ACLoad.unit =
'(' + prefixes[chartOverview['ACLoad'].magnitude] + 'W' + ')';
chartOverview.DCLoad.unit =
'(' + prefixes[chartOverview['DCLoad'].magnitude] + 'W' + ')';
chartOverview.overview = { chartOverview.overview = {
magnitude: Math.max( magnitude: Math.max(
@ -655,7 +660,8 @@ const fetchJsonDataForOneTime = async (
export const transformInputToAggregatedDataJson = async ( export const transformInputToAggregatedDataJson = async (
s3Credentials: I_S3Credentials, s3Credentials: I_S3Credentials,
start_date: dayjs.Dayjs, start_date: dayjs.Dayjs,
end_date: dayjs.Dayjs end_date: dayjs.Dayjs,
product?: number
): Promise<{ ): Promise<{
chartAggregatedData: chartAggregatedDataInterface; chartAggregatedData: chartAggregatedDataInterface;
chartOverview: overviewInterface; chartOverview: overviewInterface;
@ -676,7 +682,8 @@ export const transformInputToAggregatedDataJson = async (
'ChargingBatteryPower', 'ChargingBatteryPower',
'GridImportPower', 'GridImportPower',
'GridExportPower', 'GridExportPower',
'HeatingPower' 'HeatingPower',
'LoadPowerConsumption'
]; ];
const categories = [ const categories = [
@ -698,7 +705,8 @@ export const transformInputToAggregatedDataJson = async (
heatingPower: { name: 'Heating Energy', data: [] }, heatingPower: { name: 'Heating Energy', data: [] },
dcDischargingPower: { name: 'Discharging Battery Energy', data: [] }, dcDischargingPower: { name: 'Discharging Battery Energy', data: [] },
gridImportPower: { name: 'Grid Import Energy', data: [] }, gridImportPower: { name: 'Grid Import Energy', data: [] },
gridExportPower: { name: 'Grid Export Energy', data: [] } gridExportPower: { name: 'Grid Export Energy', data: [] },
acLoad: { name: 'AC Load', data: [] }
}; };
const chartOverview: overviewInterface = { const chartOverview: overviewInterface = {
@ -727,8 +735,11 @@ export const transformInputToAggregatedDataJson = async (
const timestampPromises = []; const timestampPromises = [];
while (currentDay.isBefore(end_date)) { while (currentDay.isBefore(end_date)) {
const dateFormat = product === 2
? currentDay.format('DDMMYYYY')
: currentDay.format('YYYY-MM-DD');
timestampPromises.push( timestampPromises.push(
fetchAggregatedDataJson(currentDay.format('YYYY-MM-DD'), s3Credentials) fetchAggregatedDataJson(dateFormat, s3Credentials, product)
); );
currentDay = currentDay.add(1, 'day'); currentDay = currentDay.add(1, 'day');
} }
@ -857,6 +868,16 @@ export const transformInputToAggregatedDataJson = async (
max: overviewData['GridImportPower'].max max: overviewData['GridImportPower'].max
}; };
path = 'LoadPowerConsumption';
chartAggregatedData.acLoad.data = data[path];
chartOverview.ACLoad = {
magnitude: overviewData['LoadPowerConsumption'].magnitude,
unit: '(kWh)',
min: overviewData['LoadPowerConsumption'].min,
max: overviewData['LoadPowerConsumption'].max
};
chartOverview.overview = { chartOverview.overview = {
magnitude: 0, magnitude: 0,
unit: '(kWh)', unit: '(kWh)',