diff --git a/src/components/parameters/short-circuit/columns-definition.ts b/src/components/parameters/short-circuit/columns-definition.ts
new file mode 100644
index 00000000..b95fd81a
--- /dev/null
+++ b/src/components/parameters/short-circuit/columns-definition.ts
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2025, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+import { ElementType, EquipmentType } from '../../../utils';
+
+export const SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE = 'active';
+export const SHORT_CIRCUIT_ICC_MATERIAL_TYPE = 'type';
+export const SHORT_CIRCUIT_ICC_MATERIAL_ALPHA = 'alpha';
+export const SHORT_CIRCUIT_ICC_MATERIAL_USMIN = 'usMin';
+export const SHORT_CIRCUIT_ICC_MATERIAL_USMAX = 'usMax';
+export const SHORT_CIRCUIT_ICC_MATERIAL_U0 = 'u0';
+export const SHORT_CIRCUIT_ICC_CLUSTER_ACTIVE = SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE;
+export const SHORT_CIRCUIT_ICC_CLUSTER_FILTERS = 'filters';
+export const SHORT_CIRCUIT_ICC_CLUSTER_TYPE = SHORT_CIRCUIT_ICC_MATERIAL_TYPE;
+export const SHORT_CIRCUIT_ICC_CLUSTER_ALPHA = SHORT_CIRCUIT_ICC_MATERIAL_ALPHA;
+export const SHORT_CIRCUIT_ICC_CLUSTER_USMIN = SHORT_CIRCUIT_ICC_MATERIAL_USMIN;
+export const SHORT_CIRCUIT_ICC_CLUSTER_USMAX = SHORT_CIRCUIT_ICC_MATERIAL_USMAX;
+export const SHORT_CIRCUIT_ICC_CLUSTER_U0 = SHORT_CIRCUIT_ICC_MATERIAL_U0;
+
+export interface IccCommonIColumnsDef {
+ label: React.ReactNode;
+ dataKey: string;
+ tooltip: React.ReactNode;
+ width?: string;
+}
+
+export interface IccMaterialIColumnsDef extends IccCommonIColumnsDef {}
+export interface IccClusterIColumnsDef extends IccCommonIColumnsDef {
+ equipmentTypes?: EquipmentType[];
+ elementType?: string;
+ titleId?: string;
+ initialValue?: any;
+}
+
+export const COLUMNS_DEFINITIONS_ICC_MATERIALS: IccMaterialIColumnsDef[] = [
+ {
+ label: 'ShortCircuitIccActive',
+ dataKey: SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE,
+ tooltip: 'ShortCircuitIccMaterialActiveTooltip',
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccMaterialType',
+ dataKey: SHORT_CIRCUIT_ICC_MATERIAL_TYPE,
+ tooltip: 'ShortCircuitIccMaterialTypeTooltip',
+ },
+ {
+ label: 'ShortCircuitIccAlpha',
+ dataKey: SHORT_CIRCUIT_ICC_MATERIAL_ALPHA,
+ tooltip: 'ShortCircuitIccAlphaTooltip',
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccUsmin',
+ dataKey: SHORT_CIRCUIT_ICC_MATERIAL_USMIN,
+ tooltip: 'ShortCircuitIccUsminTooltip',
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccUsmax',
+ dataKey: SHORT_CIRCUIT_ICC_MATERIAL_USMAX,
+ tooltip: 'ShortCircuitIccUsmaxTooltip',
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccU0',
+ dataKey: SHORT_CIRCUIT_ICC_MATERIAL_U0,
+ tooltip: 'ShortCircuitIccU0Tooltip',
+ width: '8%',
+ },
+];
+
+export const COLUMNS_DEFINITIONS_ICC_CLUSTERS: IccClusterIColumnsDef[] = [
+ {
+ label: 'ShortCircuitIccActive',
+ dataKey: SHORT_CIRCUIT_ICC_CLUSTER_ACTIVE,
+ tooltip: 'ShortCircuitIccClusterActiveTooltip',
+ initialValue: false,
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccClusterFilters',
+ dataKey: SHORT_CIRCUIT_ICC_CLUSTER_FILTERS,
+ tooltip: 'ShortCircuitIccClusterFiltersTooltip',
+ equipmentTypes: [EquipmentType.GENERATOR, EquipmentType.BATTERY],
+ elementType: ElementType.FILTER,
+ titleId: 'FiltersListsSelection',
+ initialValue: [],
+ },
+ {
+ label: 'ShortCircuitIccClusterType',
+ dataKey: SHORT_CIRCUIT_ICC_CLUSTER_TYPE,
+ tooltip: 'ShortCircuitIccClusterTypeTooltip',
+ titleId: 'ShortCircuitIccClusterTypeListsSelection',
+ initialValue: [],
+ width: '15%',
+ },
+ {
+ label: 'ShortCircuitIccAlpha',
+ dataKey: SHORT_CIRCUIT_ICC_CLUSTER_ALPHA,
+ tooltip: 'ShortCircuitIccAlphaTooltip',
+ initialValue: 1,
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccUsmin',
+ dataKey: SHORT_CIRCUIT_ICC_CLUSTER_USMIN,
+ tooltip: 'ShortCircuitIccUsminTooltip',
+ initialValue: 0,
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccUsmax',
+ dataKey: SHORT_CIRCUIT_ICC_CLUSTER_USMAX,
+ tooltip: 'ShortCircuitIccUsmaxTooltip',
+ initialValue: 100,
+ width: '8%',
+ },
+ {
+ label: 'ShortCircuitIccU0',
+ dataKey: SHORT_CIRCUIT_ICC_CLUSTER_U0,
+ tooltip: 'ShortCircuitIccU0Tooltip',
+ initialValue: 100,
+ width: '8%',
+ },
+];
diff --git a/src/components/parameters/short-circuit/constants.ts b/src/components/parameters/short-circuit/constants.ts
index acf455af..29277b18 100644
--- a/src/components/parameters/short-circuit/constants.ts
+++ b/src/components/parameters/short-circuit/constants.ts
@@ -31,6 +31,8 @@ export const SHORT_CIRCUIT_VOLTAGE_RANGES = 'voltageRanges';
export const SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER = 'onlyStartedGeneratorsInCalculationCluster';
export const SHORT_CIRCUIT_MODEL_POWER_ELECTRONICS = 'modelPowerElectronics';
export const SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS = 'powerElectronicsMaterials';
+export const SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTER = 'powerElectronicsCluster'; // TODO REMOVE WHEN fixed in powsybl
+export const SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS = 'powerElectronicsClusters';
export const intlPredefinedParametersOptions = () => [
{
diff --git a/src/components/parameters/short-circuit/short-circuit-fields.tsx b/src/components/parameters/short-circuit/short-circuit-fields.tsx
index e411a763..b75e88cd 100644
--- a/src/components/parameters/short-circuit/short-circuit-fields.tsx
+++ b/src/components/parameters/short-circuit/short-circuit-fields.tsx
@@ -27,6 +27,7 @@ import {
SHORT_CIRCUIT_WITH_NEUTRAL_POSITION,
SHORT_CIRCUIT_WITH_SHUNT_COMPENSATORS,
SHORT_CIRCUIT_WITH_VSC_CONVERTER_STATIONS,
+ SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS,
} from './constants';
import { VoltageTable } from './short-circuit-voltage-table';
import GridItem from '../../grid/grid-item';
@@ -35,7 +36,8 @@ import { CheckboxInput, FieldLabel, MuiSelectInput, RadioInput, SwitchInput } fr
import type { SxStyle } from '../../../utils/styles';
import { COMMON_PARAMETERS, SPECIFIC_PARAMETERS } from '../common';
import { ShortCircuitIccMaterialTable } from './short-circuit-icc-material-table';
-import { COLUMNS_DEFINITIONS_ICC_MATERIALS } from './short-circuit-icc-material-table-columns-definition';
+import { COLUMNS_DEFINITIONS_ICC_CLUSTERS, COLUMNS_DEFINITIONS_ICC_MATERIALS } from './columns-definition';
+import { ShortCircuitIccClusterTable } from './short-circuit-icc-cluster-table';
export interface ShortCircuitFieldsProps {
resetAll: (predefinedParams: PredefinedParameters) => void;
@@ -47,12 +49,26 @@ export enum Status {
ERROR = 'ERROR',
}
-const columnsDef = COLUMNS_DEFINITIONS_ICC_MATERIALS.map((col) => ({
+const iccMaterialsColumnsDef = COLUMNS_DEFINITIONS_ICC_MATERIALS.map((col) => ({
...col,
label: ,
tooltip: ,
}));
+const iccClustersColumnsDef = COLUMNS_DEFINITIONS_ICC_CLUSTERS.map((col) => ({
+ ...col,
+ label: ,
+ tooltip: ,
+}));
+
+function createRows() {
+ const rowData: { [key: string]: any } = {};
+ iccClustersColumnsDef.forEach((column) => {
+ rowData[column.dataKey] = column.initialValue;
+ });
+ return rowData;
+}
+
export function ShortCircuitFields({ resetAll, isDeveloperMode = true }: Readonly) {
const [status, setStatus] = useState(Status.SUCCESS);
const watchInitialVoltageProfileMode = useWatch({
@@ -286,8 +302,12 @@ export function ShortCircuitFields({ resetAll, isDeveloperMode = true }: Readonl
+
>
)}
diff --git a/src/components/parameters/short-circuit/short-circuit-icc-cluster-table-cell.tsx b/src/components/parameters/short-circuit/short-circuit-icc-cluster-table-cell.tsx
new file mode 100644
index 00000000..2f3093fa
--- /dev/null
+++ b/src/components/parameters/short-circuit/short-circuit-icc-cluster-table-cell.tsx
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2025, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+import { TableCell } from '@mui/material';
+import { DirectoryItemsInput, FloatInput, SelectInput, SwitchInput } from '../../inputs';
+import {
+ IccClusterIColumnsDef,
+ SHORT_CIRCUIT_ICC_CLUSTER_ACTIVE,
+ SHORT_CIRCUIT_ICC_CLUSTER_FILTERS,
+ SHORT_CIRCUIT_ICC_CLUSTER_TYPE,
+} from './columns-definition';
+
+export function ShortCircuitIccClusterTableCell({
+ formName,
+ rowIndex,
+ column,
+ inputsDisabled,
+}: Readonly<{
+ formName: string;
+ rowIndex: number;
+ column: IccClusterIColumnsDef;
+ inputsDisabled?: boolean;
+}>) {
+ return (
+
+ {column.dataKey === SHORT_CIRCUIT_ICC_CLUSTER_ACTIVE && (
+
+ )}
+ {column.dataKey === SHORT_CIRCUIT_ICC_CLUSTER_FILTERS && (
+
+ )}
+ {column.dataKey === SHORT_CIRCUIT_ICC_CLUSTER_TYPE && (
+
+ )}
+ {column.dataKey !== SHORT_CIRCUIT_ICC_CLUSTER_ACTIVE &&
+ column.dataKey !== SHORT_CIRCUIT_ICC_CLUSTER_FILTERS &&
+ column.dataKey !== SHORT_CIRCUIT_ICC_CLUSTER_TYPE && (
+
+ )}
+
+ );
+}
diff --git a/src/components/parameters/short-circuit/short-circuit-icc-cluster-table-row.tsx b/src/components/parameters/short-circuit/short-circuit-icc-cluster-table-row.tsx
new file mode 100644
index 00000000..73ed7368
--- /dev/null
+++ b/src/components/parameters/short-circuit/short-circuit-icc-cluster-table-row.tsx
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2025, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+import { IconButton, TableCell, TableRow, Tooltip } from '@mui/material';
+import { Delete as DeleteIcon } from '@mui/icons-material';
+import { useWatch } from 'react-hook-form';
+import { useState } from 'react';
+import { FormattedMessage } from 'react-intl';
+import { IccClusterIColumnsDef, SHORT_CIRCUIT_ICC_CLUSTER_ACTIVE } from './columns-definition';
+import { ShortCircuitIccClusterTableCell } from './short-circuit-icc-cluster-table-cell';
+
+interface ShortCircuitIccClusterTableRowProps {
+ formName: string;
+ columnsDefinition: IccClusterIColumnsDef[];
+ index: number;
+ onDeleteButton: (index: number) => void;
+}
+
+export function ShortCircuitIccClusterTableRow({
+ formName,
+ columnsDefinition,
+ index,
+ onDeleteButton,
+}: Readonly) {
+ const [isHover, setIsHover] = useState(false);
+ const watchRowActive = useWatch({
+ name: `${formName}[${index}].${SHORT_CIRCUIT_ICC_CLUSTER_ACTIVE}`,
+ });
+
+ return (
+ setIsHover(true)} onMouseLeave={() => setIsHover(false)}>
+ {columnsDefinition.map((column: IccClusterIColumnsDef) => (
+
+ ))}
+
+ {isHover && (
+ }>
+ onDeleteButton(index)}>
+
+
+
+ )}
+
+
+ );
+}
diff --git a/src/components/parameters/short-circuit/short-circuit-icc-cluster-table.tsx b/src/components/parameters/short-circuit/short-circuit-icc-cluster-table.tsx
new file mode 100644
index 00000000..35087fea
--- /dev/null
+++ b/src/components/parameters/short-circuit/short-circuit-icc-cluster-table.tsx
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2025, RTE (http://www.rte-france.com)
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+import {
+ IconButton,
+ Table,
+ TableBody,
+ TableCell,
+ TableContainer,
+ TableHead,
+ TableRow,
+ Theme,
+ Tooltip,
+} from '@mui/material';
+import { AddCircle as AddCircleIcon } from '@mui/icons-material';
+import { useFieldArray } from 'react-hook-form';
+import { FormattedMessage } from 'react-intl';
+import { useCallback } from 'react';
+import { IccClusterIColumnsDef } from './columns-definition';
+import { ShortCircuitIccClusterTableRow } from './short-circuit-icc-cluster-table-row';
+
+interface ShortCircuitIccClusterTableProps {
+ columnsDefinition: IccClusterIColumnsDef[];
+ formName: string;
+ createRows: () => unknown;
+}
+
+const styles = {
+ tableContainer: (theme: Theme) => ({
+ width: '100%',
+ border: 'solid 0px rgba(0,0,0,0.1)',
+ marginBottom: theme.spacing(4),
+ }),
+ table: {
+ minWidth: '80em',
+ tableLayout: 'fixed',
+ },
+};
+
+export function ShortCircuitIccClusterTable({
+ formName,
+ columnsDefinition,
+ createRows,
+}: Readonly) {
+ const {
+ fields: rows,
+ append,
+ remove,
+ } = useFieldArray({
+ name: formName,
+ });
+
+ const handleAddRowsButton = useCallback(() => {
+ append(createRows());
+ }, [append, createRows]);
+
+ const handleDeleteButton = useCallback(
+ (index: number) => {
+ remove(index);
+ },
+ [remove]
+ );
+
+ return (
+
+
+
+
+ {columnsDefinition.map((column) => (
+
+
+ {column.label}
+
+
+ ))}
+
+ }>
+
+
+
+
+
+
+
+
+
+
+ {rows.map((row, index) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/parameters/short-circuit/short-circuit-icc-material-table-cell.tsx b/src/components/parameters/short-circuit/short-circuit-icc-material-table-cell.tsx
index 9fb1df2f..a8c04f6c 100644
--- a/src/components/parameters/short-circuit/short-circuit-icc-material-table-cell.tsx
+++ b/src/components/parameters/short-circuit/short-circuit-icc-material-table-cell.tsx
@@ -10,7 +10,7 @@ import {
IccMaterialIColumnsDef,
SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE,
SHORT_CIRCUIT_ICC_MATERIAL_TYPE,
-} from './short-circuit-icc-material-table-columns-definition';
+} from './columns-definition';
export function ShortCircuitIccMaterialTableCell({
formName,
@@ -24,9 +24,9 @@ export function ShortCircuitIccMaterialTableCell({
inputsDisabled?: boolean;
}>) {
return (
-
+
{column.dataKey === SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE && (
-
+
)}
{column.dataKey === SHORT_CIRCUIT_ICC_MATERIAL_TYPE && (
diff --git a/src/components/parameters/short-circuit/short-circuit-icc-material-table-columns-definition.ts b/src/components/parameters/short-circuit/short-circuit-icc-material-table-columns-definition.ts
deleted file mode 100644
index 39e74796..00000000
--- a/src/components/parameters/short-circuit/short-circuit-icc-material-table-columns-definition.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright (c) 2025, RTE (http://www.rte-france.com)
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-export const SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE = 'active';
-export const SHORT_CIRCUIT_ICC_MATERIAL_TYPE = 'type';
-export const SHORT_CIRCUIT_ICC_MATERIAL_ALPHA = 'alpha';
-export const SHORT_CIRCUIT_ICC_MATERIAL_USMIN = 'usMin';
-export const SHORT_CIRCUIT_ICC_MATERIAL_USMAX = 'usMax';
-export const SHORT_CIRCUIT_ICC_MATERIAL_U0 = 'u0';
-
-export interface IccMaterialIColumnsDef {
- label: React.ReactNode;
- dataKey: string;
- tooltip: React.ReactNode;
-}
-
-export const COLUMNS_DEFINITIONS_ICC_MATERIALS: IccMaterialIColumnsDef[] = [
- {
- label: 'ShortCircuitIccMaterialActivate',
- dataKey: SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE,
- tooltip: 'ShortCircuitIccMaterialActivateTooltip',
- },
- {
- label: 'ShortCircuitIccMaterialType',
- dataKey: SHORT_CIRCUIT_ICC_MATERIAL_TYPE,
- tooltip: 'ShortCircuitIccMaterialTypeTooltip',
- },
- {
- label: 'ShortCircuitIccMaterialAlpha',
- dataKey: SHORT_CIRCUIT_ICC_MATERIAL_ALPHA,
- tooltip: 'ShortCircuitIccMaterialAlphaTooltip',
- },
- {
- label: 'ShortCircuitIccMaterialUsmin',
- dataKey: SHORT_CIRCUIT_ICC_MATERIAL_USMIN,
- tooltip: 'ShortCircuitIccMaterialUsminTooltip',
- },
- {
- label: 'ShortCircuitIccMaterialUsmax',
- dataKey: SHORT_CIRCUIT_ICC_MATERIAL_USMAX,
- tooltip: 'ShortCircuitIccMaterialUsmaxTooltip',
- },
- {
- label: 'ShortCircuitIccMaterialU0',
- dataKey: SHORT_CIRCUIT_ICC_MATERIAL_U0,
- tooltip: 'ShortCircuitIccMaterialU0Tooltip',
- },
-];
diff --git a/src/components/parameters/short-circuit/short-circuit-icc-material-table-row.tsx b/src/components/parameters/short-circuit/short-circuit-icc-material-table-row.tsx
index 3950d3bf..43e4cebc 100644
--- a/src/components/parameters/short-circuit/short-circuit-icc-material-table-row.tsx
+++ b/src/components/parameters/short-circuit/short-circuit-icc-material-table-row.tsx
@@ -6,10 +6,7 @@
*/
import { TableRow } from '@mui/material';
import { useWatch } from 'react-hook-form';
-import {
- IccMaterialIColumnsDef,
- SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE,
-} from './short-circuit-icc-material-table-columns-definition';
+import { IccMaterialIColumnsDef, SHORT_CIRCUIT_ICC_MATERIAL_ACTIVE } from './columns-definition';
import { ShortCircuitIccMaterialTableCell } from './short-circuit-icc-material-table-cell';
interface ShortCircuitIccMaterialTableRowProps {
diff --git a/src/components/parameters/short-circuit/short-circuit-icc-material-table.tsx b/src/components/parameters/short-circuit/short-circuit-icc-material-table.tsx
index d52e99f1..31a7c65c 100644
--- a/src/components/parameters/short-circuit/short-circuit-icc-material-table.tsx
+++ b/src/components/parameters/short-circuit/short-circuit-icc-material-table.tsx
@@ -5,48 +5,50 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tooltip } from '@mui/material';
+import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Theme, Tooltip } from '@mui/material';
import { useFieldArray } from 'react-hook-form';
-import { IccMaterialIColumnsDef } from './short-circuit-icc-material-table-columns-definition';
+import { IccMaterialIColumnsDef } from './columns-definition';
import { ShortCircuitIccMaterialTableRow } from './short-circuit-icc-material-table-row';
interface ShortCircuitIccMaterialTableProps {
columnsDefinition: IccMaterialIColumnsDef[];
- tableHeight: number;
formName: string;
}
+const styles = {
+ tableContainer: (theme: Theme) => ({
+ width: '100%',
+ border: 'solid 0px rgba(0,0,0,0.1)',
+ marginBottom: theme.spacing(4),
+ }),
+ table: {
+ minWidth: '80em',
+ tableLayout: 'fixed',
+ },
+};
+
export function ShortCircuitIccMaterialTable({
formName,
columnsDefinition,
- tableHeight,
}: Readonly) {
const { fields: rows } = useFieldArray({
name: formName,
});
return (
-
-
+
+
{columnsDefinition.map((column) => (
-
+
{column.label}
))}
+
+ {/* empty cell for alignment with delete button column in cluster table */}
diff --git a/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts b/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts
index ca5d1bd5..7b5134d6 100644
--- a/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts
+++ b/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts
@@ -8,6 +8,8 @@
import {
InitialVoltage,
SHORT_CIRCUIT_INITIAL_VOLTAGE_PROFILE_MODE,
+ SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTER,
+ SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS,
SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS,
SHORT_CIRCUIT_WITH_FEEDER_RESULT,
SHORT_CIRCUIT_WITH_LOADS,
@@ -17,15 +19,22 @@ import {
} from './constants';
import yup from '../../../utils/yupConfig';
import { COMMON_PARAMETERS, SPECIFIC_PARAMETERS } from '../common';
-import { type SpecificParameterInfos, type SpecificParametersValues } from '../../../utils';
+import { ID, snackWithFallback, type SpecificParameterInfos, type SpecificParametersValues } from '../../../utils';
-import type { PowerElectronicsMaterial } from './short-circuit-parameters.type';
+import {
+ FilterPOJO,
+ FormPowerElectronicsCluster,
+ type PowerElectronicsCluster,
+ type PowerElectronicsMaterial,
+} from './short-circuit-parameters.type';
import {
formatSpecificParameters,
getAllSpecificParametersValues,
getDefaultSpecificParamsValues,
getSpecificParametersFormSchema,
} from '../common/utils';
+import { NAME } from '../../inputs';
+import { SnackInputs } from '../../../hooks';
export const getCommonShortCircuitParametersFormSchema = () => {
return yup.object().shape({
@@ -68,6 +77,32 @@ export const getSpecificShortCircuitParametersFormSchema = (
.required()
: undefined;
+ const powerElectronicsClustersParam = specificParametersDescriptionForProvider?.find(
+ (specificParam) => specificParam.name === SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTER
+ );
+
+ const powerElectronicsClustersSchema = powerElectronicsClustersParam
+ ? yup
+ .array()
+ .of(
+ yup.object().shape({
+ active: yup.boolean().required(),
+ alpha: yup.number().required(),
+ u0: yup.number().required(),
+ usMin: yup.number().required(),
+ usMax: yup.number().required(),
+ filters: yup.array().of(
+ yup.object().shape({
+ [ID]: yup.string().required(),
+ [NAME]: yup.string().required(),
+ })
+ ),
+ type: yup.string().oneOf(['WIND', 'SOLAR', 'HVDC']).required(),
+ })
+ )
+ .required()
+ : undefined;
+
// try to extract existing SPECIFIC_PARAMETERS fields from defaultSchema (if present)
const existingSpecificSchema = (defaultSchema as any).fields?.[SPECIFIC_PARAMETERS] as
| yup.ObjectSchema
@@ -79,6 +114,9 @@ export const getSpecificShortCircuitParametersFormSchema = (
...(powerElectronicsMaterialsSchema
? { [SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS]: powerElectronicsMaterialsSchema }
: {}),
+ ...(powerElectronicsClustersSchema
+ ? { [SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS]: powerElectronicsClustersSchema }
+ : {}),
};
const overrideSchema = yup.object().shape({
@@ -89,18 +127,36 @@ export const getSpecificShortCircuitParametersFormSchema = (
return defaultSchema.concat(overrideSchema);
};
-const parsepowerElectronicsMaterialsParamString = (paramString: string): PowerElectronicsMaterial[] => {
+const parsePowerElectronicsMaterialsParamString = (
+ paramString: string,
+ snackError: (message: SnackInputs) => void
+): PowerElectronicsMaterial[] => {
// Attempt to parse the string into an array of PowerElectronicsMaterial objects
try {
return JSON.parse(paramString);
} catch (error) {
console.error('Error parsing power electronics materials parameter string:', error);
+ snackWithFallback(snackError, error, { headerId: 'ShortCircuitPowerElectronicsMaterialsParamParsingError' });
+ return [];
+ }
+};
+
+const parsePowerElectronicsClustersParamString = (
+ paramString: string,
+ snackError: (message: SnackInputs) => void
+): (PowerElectronicsCluster & { active: boolean })[] => {
+ // Attempt to parse the string into an array of PowerElectronicsCluster objects
+ try {
+ return JSON.parse(paramString);
+ } catch (error) {
+ snackWithFallback(snackError, error, { headerId: 'ShortCircuitPowerElectronicsClustersParamParsingError' });
return [];
}
};
export const getDefaultShortCircuitSpecificParamsValues = (
- specificParametersDescriptionForProvider: SpecificParameterInfos[]
+ specificParametersDescriptionForProvider: SpecificParameterInfos[],
+ snackError: (message: SnackInputs) => void
): SpecificParametersValues => {
const defaultValues: SpecificParametersValues = getDefaultSpecificParamsValues(
specificParametersDescriptionForProvider
@@ -109,8 +165,9 @@ export const getDefaultShortCircuitSpecificParamsValues = (
(specificParam) => specificParam.name === SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS
);
if (powerElectronicsMaterialsParam) {
- const electronicsMaterialsArray: PowerElectronicsMaterial[] = parsepowerElectronicsMaterialsParamString(
- powerElectronicsMaterialsParam.defaultValue
+ const electronicsMaterialsArray: PowerElectronicsMaterial[] = parsePowerElectronicsMaterialsParamString(
+ powerElectronicsMaterialsParam.defaultValue,
+ snackError
);
defaultValues[SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS] = electronicsMaterialsArray.map((material) => ({
@@ -118,6 +175,12 @@ export const getDefaultShortCircuitSpecificParamsValues = (
active: false,
}));
}
+ const powerElectronicsClustersParam = specificParametersDescriptionForProvider.find(
+ (specificParam) => specificParam.name === SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTER
+ );
+ if (powerElectronicsClustersParam) {
+ defaultValues[SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS] = []; // there is no default params for clusters for now
+ }
return defaultValues;
};
@@ -127,7 +190,9 @@ export const getShortCircuitSpecificParametersValues = (
): SpecificParametersValues => {
const powerElectronicsMaterialsParam: (PowerElectronicsMaterial & { active: boolean })[] =
formData[SPECIFIC_PARAMETERS][SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS];
- if (powerElectronicsMaterialsParam) {
+ const powerElectronicsClustersParam: (FormPowerElectronicsCluster & { active: boolean })[] =
+ formData[SPECIFIC_PARAMETERS][SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS];
+ if (powerElectronicsMaterialsParam && powerElectronicsClustersParam) {
// create pretty JSON
return {
...getAllSpecificParametersValues(formData, _specificParametersValues),
@@ -139,6 +204,17 @@ export const getShortCircuitSpecificParametersValues = (
return rest;
})
),
+ [SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS]: JSON.stringify(
+ powerElectronicsClustersParam.map((sParam) => {
+ const { filters, ...rest } = sParam;
+ const lightFilters = // keep only id and name in filters for backend
+ filters?.map((filter) => ({
+ filterId: filter[ID],
+ filterName: filter.name,
+ })) ?? [];
+ return { ...rest, filters: lightFilters };
+ })
+ ),
};
}
return getAllSpecificParametersValues(formData, _specificParametersValues);
@@ -146,22 +222,45 @@ export const getShortCircuitSpecificParametersValues = (
const formatElectronicsMaterialsParamString = (
defaultValues: PowerElectronicsMaterial[],
- specificParamValue: string
+ specificParamValue: string,
+ snackError: (message: SnackInputs) => void
) => {
- const electronicsMaterialsArrayInParams: PowerElectronicsMaterial[] =
- parsepowerElectronicsMaterialsParamString(specificParamValue);
+ const electronicsMaterialsArrayInParams: PowerElectronicsMaterial[] = parsePowerElectronicsMaterialsParamString(
+ specificParamValue,
+ snackError
+ );
return defaultValues.map((material) => {
const foundInParams = electronicsMaterialsArrayInParams.find((m) => m.type === material.type);
return foundInParams ? { ...foundInParams, active: true } : { ...material, active: false };
});
};
+const formatElectronicsClustersParamString = (
+ defaultValues: PowerElectronicsCluster[],
+ specificParamValue: string,
+ snackError: (message: SnackInputs) => void
+) => {
+ const electronicsClustersArrayInParams: (PowerElectronicsCluster & { active: boolean })[] =
+ parsePowerElectronicsClustersParamString(specificParamValue, snackError);
+ return electronicsClustersArrayInParams.map((cluster) => {
+ const { filters, ...rest } = cluster;
+ return {
+ ...rest,
+ filters: filters.map((filter) => ({
+ [ID]: filter.filterId,
+ [NAME]: filter.filterName, // from back to front -> {id: uuid, name: string}
+ })),
+ };
+ });
+};
+
export const formatShortCircuitSpecificParameters = (
specificParametersDescriptionForProvider: SpecificParameterInfos[],
- specificParamsList: SpecificParametersValues
+ specificParamsList: SpecificParametersValues,
+ snackError: (message: SnackInputs) => void
): SpecificParametersValues => {
if (!specificParamsList) {
- return getDefaultShortCircuitSpecificParamsValues(specificParametersDescriptionForProvider);
+ return getDefaultShortCircuitSpecificParamsValues(specificParametersDescriptionForProvider, snackError);
}
// reuse generic formatter for specific params
@@ -174,8 +273,11 @@ export const formatShortCircuitSpecificParameters = (
if (powerParam) {
if (Object.hasOwn(specificParamsList, SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS)) {
formatted[SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS] = formatElectronicsMaterialsParamString(
- getDefaultShortCircuitSpecificParamsValues([powerParam])?.[SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS],
- specificParamsList[SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS] as string
+ getDefaultShortCircuitSpecificParamsValues([powerParam], snackError)?.[
+ SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS
+ ],
+ specificParamsList[SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS] as string,
+ snackError
);
} else {
formatted[SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS] = getDefaultSpecificParamsValues([powerParam])?.[
@@ -183,5 +285,25 @@ export const formatShortCircuitSpecificParameters = (
];
}
}
+
+ // handle special power-electronics-clusters case by overriding the generic result
+ const powerElectronicsClustersParam = specificParametersDescriptionForProvider.find(
+ (p) => p.name === SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTER
+ );
+ if (powerElectronicsClustersParam) {
+ if (Object.hasOwn(specificParamsList, SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS)) {
+ formatted[SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS] = formatElectronicsClustersParamString(
+ getDefaultShortCircuitSpecificParamsValues([powerElectronicsClustersParam], snackError)?.[
+ SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS
+ ],
+ specificParamsList[SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS] as string,
+ snackError
+ );
+ } else {
+ formatted[SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS] = getDefaultSpecificParamsValues([
+ powerElectronicsClustersParam,
+ ])?.[SHORT_CIRCUIT_POWER_ELECTRONICS_CLUSTERS];
+ }
+ }
return formatted;
};
diff --git a/src/components/parameters/short-circuit/short-circuit-parameters.type.ts b/src/components/parameters/short-circuit/short-circuit-parameters.type.ts
index fcbb664f..f7cde42b 100644
--- a/src/components/parameters/short-circuit/short-circuit-parameters.type.ts
+++ b/src/components/parameters/short-circuit/short-circuit-parameters.type.ts
@@ -4,7 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-import { SpecificParametersPerProvider } from '../../../utils';
+import { UUID } from 'node:crypto';
+import { FilterIdentifier, SpecificParametersPerProvider } from '../../../utils';
import { InitialVoltage, PredefinedParameters } from './constants';
export interface VoltageRange {
@@ -22,6 +23,26 @@ export interface PowerElectronicsMaterial {
type: 'WIND' | 'SOLAR' | 'HVDC';
}
+export type FilterPOJO = {
+ id: UUID;
+ name: string;
+};
+
+export interface FormPowerElectronicsCluster {
+ alpha: number;
+ u0: number;
+ usMin: number;
+ usMax: number;
+ filters: FilterPOJO[];
+}
+export interface PowerElectronicsCluster {
+ alpha: number;
+ u0: number;
+ usMin: number;
+ usMax: number;
+ filters: FilterIdentifier[];
+}
+
export interface ShortCircuitParametersDto {
withFeederResult: boolean;
withLoads: boolean;
diff --git a/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts b/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts
index e6790877..48d9a676 100644
--- a/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts
+++ b/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts
@@ -78,9 +78,9 @@ export const useShortCircuitParametersForm = ({
const specificParametersDefaultValues = useMemo(() => {
return {
- ...getDefaultShortCircuitSpecificParamsValues(specificParametersDescriptionForProvider),
+ ...getDefaultShortCircuitSpecificParamsValues(specificParametersDescriptionForProvider, snackError),
};
- }, [specificParametersDescriptionForProvider]);
+ }, [snackError, specificParametersDescriptionForProvider]);
const formSchema = useMemo(() => {
return yup
@@ -205,13 +205,14 @@ export const useShortCircuitParametersForm = ({
[SPECIFIC_PARAMETERS]: {
...formatShortCircuitSpecificParameters(
specificParametersDescriptionForProvider,
- specificParamsListForCurrentProvider
+ specificParamsListForCurrentProvider,
+ snackError
),
},
};
return values;
},
- [provider, specificParametersDescriptionForProvider]
+ [provider, snackError, specificParametersDescriptionForProvider]
);
const onValidationError = useCallback((_errors: FieldErrors) => {
diff --git a/src/translations/en/parameters.ts b/src/translations/en/parameters.ts
index 0a9b4165..30473e7e 100644
--- a/src/translations/en/parameters.ts
+++ b/src/translations/en/parameters.ts
@@ -121,18 +121,28 @@ export const parametersEn = {
ShortCircuitStartedGeneratorsMode: 'Generators started',
ShortCircuitPowerElectronicsSection: 'Modeling of power electronics connected equipment',
ShortCircuitModelPowerElectronics: 'Consider following Icc characteristics',
- ShortCircuitIccMaterialActivate: 'Activate',
- ShortCircuitIccMaterialActivateTooltip: 'Activate or deactivate this material characteristic',
+ ShortCircuitIccActive: 'Activate',
+ ShortCircuitIccMaterialActiveTooltip: 'Activate or deactivate this material characteristic',
ShortCircuitIccMaterialType: 'Material',
ShortCircuitIccMaterialTypeTooltip: 'Type of power electronics equipment',
- ShortCircuitIccMaterialAlpha: 'Alpha',
- ShortCircuitIccMaterialAlphaTooltip: 'Exponent of the voltage dependency of the Icc',
- ShortCircuitIccMaterialUsmin: 'Usmin (%)',
- ShortCircuitIccMaterialUsminTooltip: 'Minimum voltage for the Icc calculation',
- ShortCircuitIccMaterialUsmax: 'Usmax (%)',
- ShortCircuitIccMaterialUsmaxTooltip: 'Maximum voltage for the Icc calculation',
- ShortCircuitIccMaterialU0: 'U0 (%)',
- ShortCircuitIccMaterialU0Tooltip: 'Voltage level at which the Icc is nominal',
+ ShortCircuitPowerElectronicsMaterialsParamParsingError:
+ 'An error occurred while parsing the power electronics materials parameters',
+ ShortCircuitIccClusterActiveTooltip: 'Activate or deactivate this cluster characteristic',
+ ShortCircuitIccClusterFilters: 'Filters',
+ ShortCircuitIccClusterFiltersTooltip: 'Select the filters to be included in this cluster',
+ ShortCircuitIccClusterType: 'Cluster type',
+ ShortCircuitIccClusterTypeTooltip: 'Select the types of equipment to be included in this cluster',
+ ShortCircuitIccClusterTypeListsSelection: 'Type',
+ ShortCircuitPowerElectronicsClustersParamParsingError:
+ 'An error occurred while parsing the power electronics clusters parameters',
+ ShortCircuitIccAlpha: 'Alpha',
+ ShortCircuitIccAlphaTooltip: 'Exponent of the voltage dependency of the Icc',
+ ShortCircuitIccUsmin: 'Usmin (%)',
+ ShortCircuitIccUsminTooltip: 'Minimum voltage for the Icc calculation',
+ ShortCircuitIccUsmax: 'Usmax (%)',
+ ShortCircuitIccUsmaxTooltip: 'Maximum voltage for the Icc calculation',
+ ShortCircuitIccU0: 'U0 (%)',
+ ShortCircuitIccU0Tooltip: 'Voltage level at which the Icc is nominal',
ShortCircuitWindLabel: 'Wind',
ShortCircuitSolarLabel: 'Solar',
ShortCircuitHvdcLabel: 'HVDC',
diff --git a/src/translations/fr/parameters.ts b/src/translations/fr/parameters.ts
index 5abde27e..c3061bea 100644
--- a/src/translations/fr/parameters.ts
+++ b/src/translations/fr/parameters.ts
@@ -125,19 +125,29 @@ export const parametersFr = {
ShortCircuitStartedGeneratorsMode: 'Démarrage des groupes',
ShortCircuitPowerElectronicsSection: "Modélisation des équipements raccordés par de l'électronique de puissance",
ShortCircuitModelPowerElectronics: "Prise en compte des caractéristiques d'Icc suivantes",
- ShortCircuitIccMaterialActivate: 'Actif',
- ShortCircuitIccMaterialActivateTooltip:
+ ShortCircuitIccActive: 'Actif',
+ ShortCircuitIccMaterialActiveTooltip:
"Activer la modélisation des équipements raccordés par de l'électronique de puissance",
ShortCircuitIccMaterialType: 'Matériel',
ShortCircuitIccMaterialTypeTooltip: "Type d'équipement raccordé par de l'électronique de puissance",
- ShortCircuitIccMaterialAlpha: 'Alpha',
- ShortCircuitIccMaterialAlphaTooltip: 'Coefficient de pente de la caractéristique Icc',
- ShortCircuitIccMaterialUsmin: 'Usmin (%)',
- ShortCircuitIccMaterialUsminTooltip: 'Tension minimale pour le calcul de Icc',
- ShortCircuitIccMaterialUsmax: 'Usmax (%)',
- ShortCircuitIccMaterialUsmaxTooltip: 'Tension maximale pour le calcul de Icc',
- ShortCircuitIccMaterialU0: 'U0 (%)',
- ShortCircuitIccMaterialU0Tooltip: 'Tension de référence pour le calcul de Icc',
+ ShortCircuitPowerElectronicsMaterialsParamParsingError:
+ "Une erreur est survenue lors de l'analyse des paramètres des matériaux d'électronique de puissance",
+ ShortCircuitIccClusterActiveTooltip: "Activer la modélisation des clusters d'électronique de puissance",
+ ShortCircuitIccClusterFilters: 'Filtres',
+ ShortCircuitIccClusterFiltersTooltip: 'Filtres de sélection des clusters',
+ ShortCircuitIccClusterType: 'Type de cluster',
+ ShortCircuitIccClusterTypeTooltip: "Sélectionner les types d'équipements à inclure dans ce cluster",
+ ShortCircuitIccClusterTypeListsSelection: 'Type',
+ ShortCircuitPowerElectronicsClustersParamParsingError:
+ "Une erreur est survenue lors de l'analyse des paramètres des clusters d'électronique de puissance",
+ ShortCircuitIccAlpha: 'Alpha',
+ ShortCircuitIccAlphaTooltip: 'Coefficient de pente de la caractéristique Icc',
+ ShortCircuitIccUsmin: 'Usmin (%)',
+ ShortCircuitIccUsminTooltip: 'Tension minimale pour le calcul de Icc',
+ ShortCircuitIccUsmax: 'Usmax (%)',
+ ShortCircuitIccUsmaxTooltip: 'Tension maximale pour le calcul de Icc',
+ ShortCircuitIccU0: 'U0 (%)',
+ ShortCircuitIccU0Tooltip: 'Tension de référence pour le calcul de Icc',
ShortCircuitWindLabel: 'Éolien',
ShortCircuitSolarLabel: 'Solaire',
ShortCircuitHvdcLabel: 'HVDC',