Closed annetill closed 8 months ago
No merge of Miora's PR, @colinepiloquet starts a new PR but keep the name of Miora for the new files.
After some further discussion with @annetill and @geofjamg, we agreed on the following:
List<OperationalLimitsGroup> operationalLimitsGroups
String defaultOperationalLimitsGroupId
operationalLimitsGroups1
, operationalLimitsGroups2
, and therefore one active group per side: defaultOperationalLimitsGroup1
, defaultOperationalLimitsGroup2
OperationalLimitsGroup
has several fields:
String id
CurrentLimits
ActivePowerLimits
ApparentPowerLimits
Optional<X>
branch.newCurrentLimits1()
does not need to take an id as argument, it's added in the default groupEDIT: replace active
keyword in group by default
keyword
@annetill @geofjamg don't hesitate to correct me if I didn't transcribe correctly our discussion
Trying to be more precise:
branch.newCurrentLimits1()
, we add a currentLimits to the OperationalLimitsGroup
corresponding to defaultOperationalLimitsGroupId1
. Of course if there is already one we override it.
branch.newOperationalLimitsGroup1(id)
we cannot give a null id as it is reserved for the basic use case.branch.newOperationalLimitsGroup1(id)
.newCurrentLimits()
.setPermanentLimit()
.beginTemporaryLimit().(...)
.add();
vs
branch.getOperationalLimitsGroup1(id).ifPresent(olg ->
olg.newCurrentLimits()
.setPermanentLimit()
.beginTemporaryLimit().(...)
.add());
If there is no API to remove a group do I remove a group when there is no more limits inside? Also do we want an API to cancel default group of limits without having to remove all its limits? (see TODO in test)
@pjeanmarie:
I think it is best to keep the OperationalLimitsGroup
when it is empty, and to add methods removing an OperationalLimitsGroup
from its id in lines/transformers/... .
For instance, if someone wants to remove the currentLimits and change the apparentPowerLimits of a group, calling removeCurrentLimits(...)
then setApparentPowerLimits(...)
may have a different behaviour depending on the content of the activePowerLimits (if there are no apparentPowerLimits and no activePowerLimits, the setApparentPowerLimits(...)
won't work).
Maybe we could add an isEmpty
method in OperationalLimitsGroup
to check if the operationalLimitsGroup should be removed (and change the return type of the removeXxxLimits
methods to boolean, to indicate whether the resulting group is empty or not).
When removing a whole OperationalLimitsGroup, if it was the default one, defaultLimitsId
should be set to null.
And you're right, it is interesting to expose cancelDefaultOperationalLimitsGroup()
methods.
@olperr1 Based on spec given by @flo-dup , this is proposition of change in iidm: Example with Line:
<xs:complexType name="Line">
<xs:complexContent>
<xs:extension base="iidm:Branch">
<xs:sequence>
<xs:element name="activePowerLimits1" type="iidm:LoadingLimit" minOccurs="0"/>
<xs:element name="apparentPowerLimits1" type="iidm:LoadingLimit" minOccurs="0"/>
<xs:element name="currentLimits1" type="iidm:LoadingLimit" minOccurs="0"/>
<xs:element name="activePowerLimits2" type="iidm:LoadingLimit" minOccurs="0"/>
<xs:element name="apparentPowerLimits2" type="iidm:LoadingLimit" minOccurs="0"/>
<xs:element name="currentLimits2" type="iidm:LoadingLimit" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="r" use="required" type="xs:double"/>
<xs:attribute name="x" use="required" type="xs:double"/>
<xs:attribute name="g1" use="required" type="xs:double"/>
<xs:attribute name="g2" use="required" type="xs:double"/>
<xs:attribute name="b1" use="required" type="xs:double"/>
<xs:attribute name="b2" use="required" type="xs:double"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
after:
<xs:complexType name="Line">
<xs:complexContent>
<xs:extension base="iidm:Branch">
<xs:sequence>
<xs:element name="operationalLimitsGroups1" type="iidm:LoadingLimitGroups" minOccurs="0"/>
<xs:element name="operationalLimitsGroups2" type="iidm:LoadingLimitGroups" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="r" use="required" type="xs:double"/>
<xs:attribute name="x" use="required" type="xs:double"/>
<xs:attribute name="g1" use="required" type="xs:double"/>
<xs:attribute name="g2" use="required" type="xs:double"/>
<xs:attribute name="b1" use="required" type="xs:double"/>
<xs:attribute name="b2" use="required" type="xs:double"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
with:
<xs:complexType name="LoadingLimitGroup">
<xs:sequence>
<xs:element name="activePowerLimits" type="iidm:LoadingLimit" minOccurs="0"/>
<xs:element name="apparentPowerLimits" type="iidm:LoadingLimit" minOccurs="0"/>
<xs:element name="currentLimits" type="iidm:LoadingLimit" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="id" use="required" type="xs:string"/>
</xs:complexType>
<xs:complexType name="LoadingLimitGroups">
<xs:sequence>
<xs:element name="operationalLimitsGroup" type="iidm:LoadingLimitGroup" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="defaultOperationalLimitsGroupId" use="optional" type="xs:string"/>
</xs:complexType>
(NB. I added an element operationalLimitsGroups to associate the defaultOperationalLimitsGroupId to its list of operationalLimitsGroup instead of having separatly defaultOperationalLimitsGroupId1 and defaultOperationalLimitsGroupId2 with the 2 lists but I can change that)
A feature.
For a line or a transformer, we have only one group (permanent limit + temporary limits for two sides) of each limit type (current, active power and apparent power) available in the core model, such as:
By definition, as we have only one group, it means that it is the active one. By active, we mean the one that has to be considered by the analysis tools (security analysis for example).
In some studies (network development) or operational context (CGMES), we can have a set of operational limits. The season can be important to consider, the day vs the night, and many other factor that can lead to store a set of limits and not one, and let the user chooses the active set.
OperationalLimitSet
, one for current, one for active power and one for apparent power. The design looks nice in Miora's PR (see below), excepted thatactivated
must be changed forenabled
to define the active limit set.This leads to a new version of IIDM (1.12).
Note that we must think about additional information in
CurrentLimits
, but not in that PR:A type can be added to a group. This type will described if the group is linked to an automaton/actions, or if it is only for supervision.
An enum to distinguish protections from study limits.
What is the expected behavior?
What is the motivation / use case for changing the behavior?
Please tell us about your environment:
Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, spectrum, etc)
(if a question doesn't apply, you can delete it)