added Overview Page without last week button for SodistoreHome
This commit is contained in:
parent
2895b11efc
commit
1b6d5a5916
|
|
@ -194,9 +194,13 @@ public class Controller : ControllerBase
|
|||
|
||||
while (startTimestamp <= endTimestamp)
|
||||
{
|
||||
string bucketPath = installation.Product==(int)ProductType.Salimax || installation.Product==(int)ProductType.SodiStoreMax?
|
||||
"s3://"+installation.S3BucketId + "-3e5b3069-214a-43ee-8d85-57d72000c19d/"+startTimestamp :
|
||||
"s3://"+installation.S3BucketId + "-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e/"+startTimestamp;
|
||||
string bucketPath;
|
||||
if (installation.Product == (int)ProductType.Salimax || installation.Product == (int)ProductType.SodiStoreMax)
|
||||
bucketPath = "s3://" + installation.S3BucketId + "-3e5b3069-214a-43ee-8d85-57d72000c19d/" + startTimestamp;
|
||||
else if (installation.Product == (int)ProductType.SodioHome)
|
||||
bucketPath = "s3://" + installation.S3BucketId + "-e7b9a240-3c5d-4d2e-a019-6d8b1f7b73fa/" + startTimestamp;
|
||||
else
|
||||
bucketPath = "s3://" + installation.S3BucketId + "-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e/" + startTimestamp;
|
||||
Console.WriteLine("Fetching data for "+startTimestamp);
|
||||
|
||||
try
|
||||
|
|
|
|||
|
|
@ -118,6 +118,12 @@ function Overview(props: OverviewProps) {
|
|||
|
||||
resultPromise
|
||||
.then((result) => {
|
||||
if (result.chartData.soc.data.length === 0) {
|
||||
setDateSelectionError('No data available for the selected date range. Please choose a more recent date.');
|
||||
setErrorDateModalOpen(true);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
setDailyDataArray((prevData) =>
|
||||
prevData.concat({
|
||||
chartData: result.chartData,
|
||||
|
|
@ -281,6 +287,12 @@ function Overview(props: OverviewProps) {
|
|||
|
||||
resultPromise
|
||||
.then((result) => {
|
||||
if (result.chartData.soc.data.length === 0) {
|
||||
setDateSelectionError('No data available for the selected date range. Please choose a more recent date.');
|
||||
setErrorDateModalOpen(true);
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
setDailyDataArray((prevData) =>
|
||||
prevData.concat({
|
||||
chartData: result.chartData,
|
||||
|
|
@ -511,6 +523,7 @@ function Overview(props: OverviewProps) {
|
|||
>
|
||||
<FormattedMessage id="24_hours" defaultMessage="24-hours" />
|
||||
</Button>
|
||||
{product !== 2 && (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleWeekData}
|
||||
|
|
@ -525,6 +538,7 @@ function Overview(props: OverviewProps) {
|
|||
>
|
||||
<FormattedMessage id="lastweek" defaultMessage="Last week" />
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/*{aggregatedData && (*/}
|
||||
<Button
|
||||
|
|
@ -1013,7 +1027,7 @@ function Overview(props: OverviewProps) {
|
|||
alignItems="stretch"
|
||||
spacing={3}
|
||||
>
|
||||
<Grid item md={6} xs={12}>
|
||||
<Grid item md={product === 2 ? 12 : 6} xs={12}>
|
||||
<Card
|
||||
sx={{
|
||||
overflow: 'visible',
|
||||
|
|
@ -1074,6 +1088,7 @@ function Overview(props: OverviewProps) {
|
|||
/>
|
||||
</Card>
|
||||
</Grid>
|
||||
{product !== 2 && (
|
||||
<Grid item md={6} xs={12}>
|
||||
<Card
|
||||
sx={{
|
||||
|
|
@ -1136,6 +1151,7 @@ function Overview(props: OverviewProps) {
|
|||
/>
|
||||
</Card>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
|
|
@ -1336,7 +1352,7 @@ function Overview(props: OverviewProps) {
|
|||
alignItems="stretch"
|
||||
spacing={3}
|
||||
>
|
||||
<Grid item md={6} xs={12}>
|
||||
<Grid item md={product === 2 ? 12 : 6} xs={12}>
|
||||
<Card
|
||||
sx={{
|
||||
overflow: 'visible',
|
||||
|
|
@ -1397,6 +1413,7 @@ function Overview(props: OverviewProps) {
|
|||
/>
|
||||
</Card>
|
||||
</Grid>
|
||||
{product !== 2 && (
|
||||
<Grid item md={6} xs={12}>
|
||||
<Card
|
||||
sx={{
|
||||
|
|
@ -1458,6 +1475,7 @@ function Overview(props: OverviewProps) {
|
|||
/>
|
||||
</Card>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import { FetchResult } from '../../../dataCache/dataCache';
|
|||
import BatteryViewSodioHome from '../BatteryView/BatteryViewSodioHome';
|
||||
import SodistoreHomeConfiguration from './SodistoreHomeConfiguration';
|
||||
import TopologySodistoreHome from '../Topology/TopologySodistoreHome';
|
||||
import Overview from '../Overview/overview';
|
||||
|
||||
interface singleInstallationProps {
|
||||
current_installation?: I_Installation;
|
||||
|
|
@ -541,6 +542,16 @@ function SodioHomeInstallation(props: singleInstallationProps) {
|
|||
/>
|
||||
)}
|
||||
|
||||
<Route
|
||||
path={routes.overview}
|
||||
element={
|
||||
<Overview
|
||||
s3Credentials={s3Credentials}
|
||||
id={props.current_installation.id}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path={'*'}
|
||||
element={<Navigate to={routes.live}></Navigate>}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ function SodioHomeInstallationTabs(props: SodioHomeInstallationTabsProps) {
|
|||
const { currentUser } = context;
|
||||
const tabList = [
|
||||
'live',
|
||||
'overview',
|
||||
'batteryview',
|
||||
'information',
|
||||
'manage',
|
||||
'overview',
|
||||
'log',
|
||||
'history',
|
||||
'configuration'
|
||||
|
|
@ -100,6 +100,10 @@ function SodioHomeInstallationTabs(props: SodioHomeInstallationTabsProps) {
|
|||
value: 'live',
|
||||
label: <FormattedMessage id="live" defaultMessage="Live" />
|
||||
},
|
||||
{
|
||||
value: 'overview',
|
||||
label: <FormattedMessage id="overview" defaultMessage="Overview" />
|
||||
},
|
||||
{
|
||||
value: 'batteryview',
|
||||
label: (
|
||||
|
|
@ -109,10 +113,6 @@ function SodioHomeInstallationTabs(props: SodioHomeInstallationTabsProps) {
|
|||
/>
|
||||
)
|
||||
},
|
||||
// {
|
||||
// value: 'overview',
|
||||
// label: <FormattedMessage id="overview" defaultMessage="Overview" />
|
||||
// },
|
||||
{
|
||||
value: 'log',
|
||||
label: <FormattedMessage id="log" defaultMessage="Log" />
|
||||
|
|
@ -159,11 +159,10 @@ function SodioHomeInstallationTabs(props: SodioHomeInstallationTabsProps) {
|
|||
value: 'live',
|
||||
label: <FormattedMessage id="live" defaultMessage="Live" />
|
||||
},
|
||||
// {
|
||||
// value: 'overview',
|
||||
// label: <FormattedMessage id="overview" defaultMessage="Overview" />
|
||||
// },
|
||||
|
||||
{
|
||||
value: 'overview',
|
||||
label: <FormattedMessage id="overview" defaultMessage="Overview" />
|
||||
},
|
||||
{
|
||||
value: 'information',
|
||||
label: (
|
||||
|
|
@ -190,6 +189,10 @@ function SodioHomeInstallationTabs(props: SodioHomeInstallationTabsProps) {
|
|||
value: 'live',
|
||||
label: <FormattedMessage id="live" defaultMessage="Live" />
|
||||
},
|
||||
{
|
||||
value: 'overview',
|
||||
label: <FormattedMessage id="overview" defaultMessage="Overview" />
|
||||
},
|
||||
{
|
||||
value: 'batteryview',
|
||||
label: (
|
||||
|
|
@ -199,10 +202,6 @@ function SodioHomeInstallationTabs(props: SodioHomeInstallationTabsProps) {
|
|||
/>
|
||||
)
|
||||
},
|
||||
// {
|
||||
// value: 'overview',
|
||||
// label: <FormattedMessage id="overview" defaultMessage="Overview" />
|
||||
// },
|
||||
{
|
||||
value: 'log',
|
||||
label: <FormattedMessage id="log" defaultMessage="Log" />
|
||||
|
|
|
|||
|
|
@ -310,15 +310,25 @@ export const transformInputToDailyDataJson = async (
|
|||
const prefixes = ['', 'k', 'M', 'G', 'T'];
|
||||
|
||||
const MAX_NUMBER = 9999999;
|
||||
const pathsToSearch = [
|
||||
// For SodioHome (product=2), paths are placeholders — actual extraction uses
|
||||
// custom fallback logic to handle differences between Growatt and Sinexcel.
|
||||
// Growatt has: Battery1AmbientTemperature, GridPower, PvPower
|
||||
// Sinexcel has: Battery1Temperature, TotalGridPower (meter may be offline), PvPower1-4
|
||||
const pathsToSearch = product == 2
|
||||
? [
|
||||
'SODIOHOME_SOC',
|
||||
'SODIOHOME_TEMPERATURE',
|
||||
'SODIOHOME_BATTERY_POWER',
|
||||
'SODIOHOME_GRID_POWER',
|
||||
'SODIOHOME_PV_POWER',
|
||||
null, // dcBusVoltage not available for SodioHome
|
||||
'SODIOHOME_CONSUMPTION',
|
||||
null // DCLoad not available for SodioHome
|
||||
]
|
||||
: [
|
||||
'Battery.Soc',
|
||||
product == 0 ? 'Battery.Temperature' : 'Battery.TemperatureCell1',
|
||||
|
||||
//'Battery.Temperature' for salimax,
|
||||
//'Battery.TemperatureCell1',
|
||||
product == 0 ? 'Battery.Dc.Power' : 'Battery.Power',
|
||||
//'Battery.Dc.Power' for salimax,
|
||||
// 'Battery.Power',
|
||||
'GridMeter.Ac.Power.Active',
|
||||
'PvOnDc',
|
||||
'DcDc.Dc.Link.Voltage',
|
||||
|
|
@ -419,14 +429,55 @@ export const transformInputToDailyDataJson = async (
|
|||
let category_index = 0;
|
||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||
pathsToSearch.forEach((path) => {
|
||||
if (get(result, path) !== undefined) {
|
||||
if (path === null) {
|
||||
// Skip unavailable fields (e.g. dcBusVoltage, DCLoad for SodioHome)
|
||||
category_index++;
|
||||
return;
|
||||
}
|
||||
|
||||
let value: number | undefined = undefined;
|
||||
|
||||
if (category_index === 4) {
|
||||
// Custom logic for 'PvOnDc.Dc.Power'
|
||||
if (product === 2) {
|
||||
// SodioHome: custom extraction with fallbacks for Growatt/Sinexcel
|
||||
const inv = result?.InverterRecord;
|
||||
if (inv) {
|
||||
switch (category_index) {
|
||||
case 0: // soc
|
||||
value = inv.Battery1Soc;
|
||||
break;
|
||||
case 1: // temperature
|
||||
// Growatt: Battery1AmbientTemperature, Sinexcel: Battery1Temperature
|
||||
value = inv.Battery1AmbientTemperature ?? inv.Battery1Temperature;
|
||||
break;
|
||||
case 2: // battery power
|
||||
value = inv.Battery1Power;
|
||||
break;
|
||||
case 3: // grid power
|
||||
// Growatt: GridPower (always valid), Sinexcel: GridPower may be 0 when
|
||||
// electric meter is offline, TotalGridPower is the reliable fallback
|
||||
value = inv.TotalGridPower ?? inv.GridPower;
|
||||
break;
|
||||
case 4: // pv production
|
||||
// Growatt: PvPower (aggregated), Sinexcel: PvTotalPower or sum PvPower1-4
|
||||
value =
|
||||
inv.PvPower ??
|
||||
inv.PvTotalPower ??
|
||||
['PvPower1', 'PvPower2', 'PvPower3', 'PvPower4']
|
||||
.map((key) => inv[key] ?? 0)
|
||||
.reduce((sum, val) => sum + val, 0);
|
||||
break;
|
||||
case 6: // consumption
|
||||
value = inv.ConsumptionPower;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (category_index === 4) {
|
||||
// Salimax/Salidomo: Custom logic for 'PvOnDc.Dc.Power'
|
||||
if (get(result, path) !== undefined) {
|
||||
value = Object.values(
|
||||
result.PvOnDc as Record<string, { Dc?: { Power?: number } }>
|
||||
).reduce((sum, device) => sum + (device.Dc?.Power || 0), 0);
|
||||
}
|
||||
} else if (get(result, path) !== undefined) {
|
||||
// Default path-based extraction
|
||||
value = path
|
||||
|
|
@ -449,7 +500,7 @@ export const transformInputToDailyDataJson = async (
|
|||
value
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
category_index++;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue