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 = (
date: string,
s3Credentials?: I_S3Credentials
s3Credentials?: I_S3Credentials,
product?: number
): Promise<FetchResult<any>> => {
const s3Path = `${date}.json`;
@ -128,7 +129,12 @@ export const fetchAggregatedDataJson = (
if (r.status === 404) {
return Promise.resolve(FetchResult.notAvailable);
} 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');
if (contentEncoding != 'application/base64; charset=utf-8') {
@ -142,7 +148,6 @@ export const fetchAggregatedDataJson = (
const zip = await JSZip.loadAsync(byteArray);
// Assuming the CSV file is named "data.csv" inside the ZIP archive
const jsonContent = await zip.file('data.json').async('text');
//console.log(jsonContent);
return JSON.parse(jsonContent);
} else {
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 {
s3Credentials: I_S3Credentials;
id: number;
device?: number;
}
const computeLast7Days = (): string[] => {
@ -210,11 +211,19 @@ function Overview(props: OverviewProps) {
}> = transformInputToAggregatedDataJson(
props.s3Credentials,
dayjs().subtract(1, 'week'),
dayjs()
dayjs(),
product
);
resultPromise
.then((result) => {
if (result.dateList.length === 0) {
setDateSelectionError(intl.formatMessage({ id: 'noDataForDateRange' }));
setErrorDateModalOpen(true);
setLoading(false);
return;
}
const powerDifference = [];
for (
let i = 0;
@ -320,11 +329,19 @@ function Overview(props: OverviewProps) {
}> = transformInputToAggregatedDataJson(
props.s3Credentials,
startDate,
endDate
endDate,
product
);
resultPromise
.then((result) => {
if (result.dateList.length === 0) {
setDateSelectionError(intl.formatMessage({ id: 'noDataForDateRange' }));
setErrorDateModalOpen(true);
setLoading(false);
return;
}
const powerDifference = [];
for (
@ -524,6 +541,7 @@ function Overview(props: OverviewProps) {
>
<FormattedMessage id="24_hours" defaultMessage="24-hours" />
</Button>
{props.device !== 3 && (
<Button
variant="contained"
onClick={handleWeekData}
@ -538,8 +556,8 @@ function Overview(props: OverviewProps) {
>
<FormattedMessage id="lastweek" defaultMessage="Last week" />
</Button>
)}
{/*{aggregatedData && (*/}
<Button
variant="contained"
onClick={handleSetDate}
@ -554,7 +572,6 @@ function Overview(props: OverviewProps) {
>
<FormattedMessage id="set_date" defaultMessage="Set Date" />
</Button>
{/*)}*/}
</Grid>
<Grid
@ -766,7 +783,7 @@ function Overview(props: OverviewProps) {
{
...aggregatedDataArray[aggregatedChartState]
.chartData.gridExportPower,
color: '#ff3333',
color: '#2e7d32',
type: 'bar'
},
{
@ -775,13 +792,13 @@ function Overview(props: OverviewProps) {
type: 'bar',
color: '#ff9900'
},
{
...(product !== 2 ? [{
name: 'Net Energy',
color: '#ff3333',
color: '#e65100',
type: 'line',
data: aggregatedDataArray[aggregatedChartState]
.netbalance
}
}] : [])
]}
height={400}
type={'bar'}
@ -798,6 +815,7 @@ function Overview(props: OverviewProps) {
alignItems="stretch"
spacing={3}
>
{!(aggregatedData && product === 2) && (
<Grid item md={6} xs={12}>
<Card
sx={{
@ -889,7 +907,8 @@ function Overview(props: OverviewProps) {
)}
</Card>
</Grid>
<Grid item md={6} xs={12}>
)}
<Grid item md={(aggregatedData && product === 2) ? 12 : 6} xs={12}>
<Card
sx={{
overflow: 'visible',
@ -957,11 +976,14 @@ function Overview(props: OverviewProps) {
<ReactApexChart
options={{
...getChartOptions(
aggregatedDataArray[aggregatedChartState]
.chartOverview.dcPower,
product === 2
? aggregatedDataArray[aggregatedChartState]
.chartOverview.dcPowerWithoutHeating
: aggregatedDataArray[aggregatedChartState]
.chartOverview.dcPower,
'weekly',
aggregatedDataArray[aggregatedChartState].datelist,
false
product === 2
)
}}
series={[
@ -970,11 +992,11 @@ function Overview(props: OverviewProps) {
.chartData.dcChargingPower,
color: '#008FFB'
},
{
...(product !== 2 ? [{
...aggregatedDataArray[aggregatedChartState]
.chartData.heatingPower,
color: '#ff9900'
},
}] : []),
{
...aggregatedDataArray[aggregatedChartState]
.chartData.dcDischargingPower,
@ -1345,6 +1367,63 @@ function Overview(props: OverviewProps) {
</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 && (
<Grid
container

View File

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

View File

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