fixed batteryview, min_soc error msg, operating priority in configuration tab tailored to sinexcel and growatt; fixed routes warning

This commit is contained in:
Yinyin Liu 2025-11-04 08:31:34 +01:00
parent d91090965d
commit 7b4f4481a3
11 changed files with 139 additions and 55 deletions

View File

@ -168,7 +168,7 @@ function BatteryView(props: BatteryViewProps) {
<Grid container>
<Routes>
<Route
path={routes.mainstats + '*'}
path={routes.mainstats + '/*'}
element={
<MainStats
s3Credentials={props.s3Credentials}

View File

@ -166,7 +166,7 @@ function BatteryViewSalidomo(props: BatteryViewProps) {
<Grid container>
<Routes>
<Route
path={routes.mainstats + '*'}
path={routes.mainstats + '/*'}
element={
<MainStatsSalidomo
s3Credentials={props.s3Credentials}

View File

@ -34,14 +34,51 @@ function BatteryViewSodioHome(props: BatteryViewSodioHomeProps) {
const currentLocation = useLocation();
const navigate = useNavigate();
// const sortedBatteryView =
// props.values != null &&
// props.values?.AcDcGrowatt?.BatteriesRecords?.Batteries
// ? Object.entries(props.values.AcDcGrowatt.BatteriesRecords.Batteries)
// .map(([BatteryId, battery]) => {
// return { BatteryId, battery }; // Here we return an object with the id and device
// })
// .sort((a, b) => parseInt(b.BatteryId) - parseInt(a.BatteryId))
// : [];
const inverter = (props.values as any)?.InverterRecord;
const sortedBatteryView =
props.values != null &&
props.values?.AcDcGrowatt?.BatteriesRecords?.Batteries
? Object.entries(props.values.AcDcGrowatt.BatteriesRecords.Batteries)
.map(([BatteryId, battery]) => {
return { BatteryId, battery }; // Here we return an object with the id and device
})
.sort((a, b) => parseInt(b.BatteryId) - parseInt(a.BatteryId))
inverter
? [
{
BatteryId: '1',
battery: {
Voltage: inverter.Battery1Voltage,
Current: inverter.Battery1Current,
Power: inverter.Battery1Power,
Soc: inverter.Battery1Soc,
Soh: inverter.Battery1Soh,
// DailyDischargeEnergy: inverter.Battery1DailyDischargeEnergy,
// DailyChargeEnergy: inverter.Battery1DailyChargeEnergy,
}
},
{
BatteryId: '2',
battery: {
Voltage: inverter.Battery2Voltage,
Current: inverter.Battery2Current,
Power: inverter.Battery2Power,
Soc: inverter.Battery2Soc,
Soh: inverter.Battery2Soh,
// DailyDischargeEnergy: inverter.Battery2DailyDischargeEnergy,
// DailyChargeEnergy: inverter.Battery2DailyChargeEnergy,
}
}
]// filter out batteries where all numeric values are 0 or null/undefined
.filter(({ battery }) =>
Object.values(battery).some(
(v) => typeof v === 'number' && v !== 0
)
)
: [];
const [loading, setLoading] = useState(sortedBatteryView.length == 0);
@ -157,7 +194,7 @@ function BatteryViewSodioHome(props: BatteryViewSodioHomeProps) {
{/*<Grid container>*/}
{/* <Routes>*/}
{/* <Route*/}
{/* path={routes.mainstats + '*'}*/}
{/* path={routes.mainstats + '/*'}*/}
{/* element={*/}
{/* <MainStats*/}
{/* s3Credentials={props.s3Credentials}*/}
@ -224,8 +261,8 @@ function BatteryViewSodioHome(props: BatteryViewSodioHomeProps) {
<TableCell align="center">Current</TableCell>
<TableCell align="center">SoC</TableCell>
<TableCell align="center">SoH</TableCell>
<TableCell align="center">Daily Charge Energy</TableCell>
<TableCell align="center">Daily Discharge Energy</TableCell>
{/*<TableCell align="center">Daily Charge Energy</TableCell>*/}
{/*<TableCell align="center">Daily Discharge Energy</TableCell>*/}
</TableRow>
</TableHead>
<TableBody>
@ -298,26 +335,26 @@ function BatteryViewSodioHome(props: BatteryViewSodioHomeProps) {
>
{battery.Soh + ' %'}
</TableCell>
<TableCell
sx={{
width: '15%',
textAlign: 'center',
backgroundColor: '#32CD32',
color: 'inherit'
}}
>
{battery.DailyChargeEnergy + ' Wh'}
</TableCell>
<TableCell
sx={{
width: '15%',
textAlign: 'center',
backgroundColor: '#32CD32',
color: 'inherit'
}}
>
{battery.DailyDischargeEnergy + ' Wh'}
</TableCell>
{/*<TableCell*/}
{/* sx={{*/}
{/* width: '15%',*/}
{/* textAlign: 'center',*/}
{/* backgroundColor: '#32CD32',*/}
{/* color: 'inherit'*/}
{/* }}*/}
{/*>*/}
{/* {battery.DailyChargeEnergy + ' Wh'}*/}
{/*</TableCell>*/}
{/*<TableCell*/}
{/* sx={{*/}
{/* width: '15%',*/}
{/* textAlign: 'center',*/}
{/* backgroundColor: '#32CD32',*/}
{/* color: 'inherit'*/}
{/* }}*/}
{/*>*/}
{/* {battery.DailyDischargeEnergy + ' Wh'}*/}
{/*</TableCell>*/}
</TableRow>
))}
</TableBody>

View File

@ -416,7 +416,7 @@ function Installation(props: singleInstallationProps) {
/>
<Route
path={routes.batteryview + '*'}
path={routes.batteryview + '/*'}
element={
<BatteryView
values={values}
@ -428,7 +428,7 @@ function Installation(props: singleInstallationProps) {
></Route>
<Route
path={routes.pvview + '*'}
path={routes.pvview + '/*'}
element={
<PvView values={values} connected={connected}></PvView>
}

View File

@ -18,7 +18,7 @@ function InstallationSearch(props: installationSearchProps) {
return (
<Route
key={installation.id}
path={routes.installation + installation.id + '*'}
path={routes.installation + installation.id + '/*'}
element={
<Installation
key={installation.id}
@ -92,7 +92,7 @@ function InstallationSearch(props: installationSearchProps) {
// return (
// <Route
// key={installation.id}
// path={routes.installation + installation.id + '*'}
// path={routes.installation + installation.id + '/*'}
// element={
// <Installation
// key={installation.id}

View File

@ -361,7 +361,7 @@ function SalidomoInstallation(props: singleInstallationProps) {
/>
<Route
path={routes.batteryview + '*'}
path={routes.batteryview + '/*'}
element={
<BatteryViewSalidomo
values={values}

View File

@ -18,7 +18,7 @@ function InstallationSearch(props: installationSearchProps) {
return (
<Route
key={installation.id}
path={routes.installation + installation.id + '*'}
path={routes.installation + installation.id + '/*'}
element={
<SalidomoInstallation
key={installation.id}

View File

@ -444,7 +444,7 @@ function SodioHomeInstallation(props: singleInstallationProps) {
/>
<Route
path={routes.batteryview + '*'}
path={routes.batteryview + '/*'}
element={
<BatteryViewSodioHome
values={values}
@ -474,6 +474,7 @@ function SodioHomeInstallation(props: singleInstallationProps) {
<SodistoreHomeConfiguration
values={values}
id={props.current_installation.id}
installation={props.current_installation}
></SodistoreHomeConfiguration>
}
/>

View File

@ -83,7 +83,7 @@ function InstallationSearch(props: installationSearchProps) {
return (
<Route
key={installation.id}
path={routes.installation + installation.id + '*'}
path={routes.installation + installation.id + '/*'}
element={
<SodioHomeInstallation
key={installation.id}

View File

@ -24,10 +24,12 @@ import MenuItem from '@mui/material/MenuItem';
import axiosConfig from '../../../Resources/axiosConfig';
import { UserContext } from '../../../contexts/userContext';
import { ProductIdContext } from '../../../contexts/ProductIdContextProvider';
import { I_Installation } from 'src/interfaces/InstallationTypes';
interface SodistoreHomeConfigurationProps {
values: JSONRecordData;
id: number;
installation: I_Installation;
}
function SodistoreHomeConfiguration(props: SodistoreHomeConfigurationProps) {
@ -35,11 +37,22 @@ function SodistoreHomeConfiguration(props: SodistoreHomeConfigurationProps) {
return null;
}
const OperatingPriorityOptions = [
'LoadPriority',
'BatteryPriority',
'GridPriority'
];
const device = props.installation.device;
const OperatingPriorityOptions =
device === 3 // Growatt
? ['LoadPriority', 'BatteryPriority', 'GridPriority']
: device === 4 // Sinexcel
? [
'SpontaneousSelfUse',
'TimeChargeDischarge',
'TimeOfUsePowerPrice',
'DisasterStandby',
'ManualControl',
'PvPriorityCharging',
'PrioritySellElectricity'
]
: [];
const [errors, setErrors] = useState({
minimumSoC: false,
@ -114,17 +127,50 @@ function SodistoreHomeConfiguration(props: SodistoreHomeConfigurationProps) {
const { name, value } = e.target;
switch (name) {
case 'minimumSoC':
if (
/[^0-9.]/.test(value) ||
isNaN(parseFloat(value)) ||
parseFloat(value) > 100
) {
SetErrorForField(name, true);
// case 'minimumSoC':
// if (
// /[^0-9.]/.test(value) ||
// isNaN(parseFloat(value)) ||
// parseFloat(value) > 30 ||
// parseFloat(value) < 10
// ) {
// SetErrorForField(name, true);
// } else {
// SetErrorForField(name, false);
// }
// break;
case 'minimumSoC': {
const numValue = parseFloat(value);
// Check for invalid characters or non-numeric
if (/[^0-9.]/.test(value) || isNaN(numValue)) {
SetErrorForField(name, {
hasError: true,
message: 'Invalid number format',
});
break;
}
// Define device-based ranges
const minsocRanges = {
3: { min: 10, max: 30 },
4: { min: 5, max: 100 },
};
// Fallback range if device not listed
const { min, max } = minsocRanges[device] || { min: 10, max: 30 };
if (numValue < min || numValue > max) {
SetErrorForField(name, {
hasError: true,
message: `Value should be between ${min}-${max}%`,
});
} else {
SetErrorForField(name, false);
SetErrorForField(name, { hasError: false, message: '' });
}
break;
}
case 'gridSetPoint':
if (/[^0-9.]/.test(value) || isNaN(parseFloat(value))) {
SetErrorForField(name, true);
@ -238,7 +284,7 @@ function SodistoreHomeConfiguration(props: SodistoreHomeConfigurationProps) {
helperText={
errors.minimumSoC ? (
<span style={{ color: 'red' }}>
Value should be between 0-100%
Value should be between {device === 4 ? '5100' : '1030'}%
</span>
) : (
''

View File

@ -78,7 +78,7 @@ function InstallationTree() {
return (
<Route
key={installation.id}
path={routes.installation + installation.id + '*'}
path={routes.installation + installation.id + '/*'}
element={
installation.product == 0 || installation.product == 3 ? (
<Installation