Skip to content

Commit

Permalink
all
Browse files Browse the repository at this point in the history
  • Loading branch information
samirromdhani committed Jan 24, 2025
1 parent 4dc58ba commit e28e8e1
Show file tree
Hide file tree
Showing 23 changed files with 687 additions and 1,767 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.api.LnEditor;
import org.lfenergy.compas.sct.commons.domain.*;
import org.lfenergy.compas.sct.commons.dto.SclReportItem;
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceActivation;
import org.lfenergy.compas.sct.commons.scl.ln.LnId;
import org.lfenergy.compas.sct.commons.util.ActiveStatus;
import org.lfenergy.compas.sct.commons.util.PrivateUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.lfenergy.compas.sct.commons.util.CommonConstants.MOD_DO_NAME;
import static org.lfenergy.compas.sct.commons.util.CommonConstants.STVAL_DA_NAME;
import static org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceActivation.LNODE_STATUS_PRIVATE_TYPE;
import static org.lfenergy.compas.sct.commons.util.CommonConstants.*;
import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newVal;

@Slf4j
Expand Down Expand Up @@ -146,6 +152,59 @@ public void updateOrCreateDOAndDAInstances(TAnyLN tAnyLN, DoLinkedToDa doLinkedT
});
}

/**
* Activate used LDevice and Deactivate unused LDevice in {@link TLNode <em><b>TLNode </b></em>}
*
* @param scd SCL file for which LDevice should be activated or deactivated
* @return list of encountered errors
*/
public List<SclReportItem> updateLDeviceStatus(SCL scd, SubstationService substationService, LdeviceService ldeviceService, DataTypeTemplatesService dataTypeTemplatesService) {
List<SclReportItem> sclReportItems = new ArrayList<>();
LDeviceActivation lDeviceActivation = new LDeviceActivation(substationService.getLNodes(scd));
scd.getIED().forEach(tied -> ldeviceService.getLdevices(tied)
.forEach(tlDevice -> getAnylns(tlDevice)
.forEach(tln -> {
String xpath = "/SCL/IED[@name=%s]/AccessPoint/Server/LDevice[@inst=%s]/LN[class=%s]".formatted(tied.getName(), tlDevice.getInst(), LnId.from(tln).lnClass());
DoLinkedToDaFilter doLinkedToDaFilter = DoLinkedToDaFilter.from(BEHAVIOUR_DO_NAME, STVAL_DA_NAME);
Optional<DoLinkedToDa> optionalBehStVal = dataTypeTemplatesService.getFilteredDoLinkedToDa(scd.getDataTypeTemplates(), tln.getLnType(), doLinkedToDaFilter).findFirst();
if (optionalBehStVal.isEmpty()) {
sclReportItems.add(SclReportItem.error(xpath, "The LDevice doesn't have a DO @name='Beh'"));
return;
}

Optional<ActiveStatus> optionalModStVal = getDaiModStValValue(tln);
if (optionalModStVal.isEmpty()) {
sclReportItems.add(SclReportItem.error(xpath, "The LDevice doesn't have a DO @name='Mod'"));
return;
}

Optional<String> lNodeStatus = PrivateUtils.extractStringPrivate(tln, LNODE_STATUS_PRIVATE_TYPE);
if (lNodeStatus.isEmpty()) {
sclReportItems.add(SclReportItem.error(xpath, "The LN doesn't have a Private "+LNODE_STATUS_PRIVATE_TYPE));
return;
}

Set<String> enumValues = dataTypeTemplatesService.getEnumValues(scd.getDataTypeTemplates(), tln.getLnType(), doLinkedToDaFilter).collect(Collectors.toSet());
lDeviceActivation.checkLDeviceActivationStatus(tied.getName(), tlDevice.getInst(), lNodeStatus.get(), enumValues, sclReportItems);
if(lDeviceActivation.isUpdatable()){
update(tln, optionalModStVal.get().getValue(), lDeviceActivation.getNewVal());
}
})));
return sclReportItems;
}

private void update(TAnyLN tAnyLN, String modStValValue, String modStValNewVal) {
if (!modStValValue.equals(modStValNewVal)) {
DataObject dataObject = new DataObject();
dataObject.setDoName(MOD_DO_NAME);
DataAttribute dataAttribute = new DataAttribute();
dataAttribute.setDaName(STVAL_DA_NAME);
dataAttribute.setDaiValues(List.of(new DaVal(null, modStValNewVal)));
DoLinkedToDa doLinkedToDa = new DoLinkedToDa(dataObject, dataAttribute);
updateOrCreateDOAndDAInstances(tAnyLN, doLinkedToDa);
}
}

public void completeFromDAInstance(TIED tied, String ldInst, TAnyLN anyLN, DoLinkedToDa doLinkedToDa) {
getDOAndDAInstances(anyLN, doLinkedToDa.toFilter())
.ifPresent(tdai -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.api.SclEditor;
import org.lfenergy.compas.sct.commons.dto.*;
Expand Down Expand Up @@ -187,19 +186,6 @@ public void importSTDElementsInSCD(SCL scd, List<SCL> stds) throws ScdException
});
}

@Override
public List<SclReportItem> updateLDeviceStatus(SCL scd) {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
SubstationAdapter substationAdapter = sclRootAdapter.getSubstationAdapter();
final List<Pair<String, String>> iedNameLdInstList = substationAdapter.getIedAndLDeviceNamesForLN0FromLNode();
return sclRootAdapter.streamIEDAdapters()
.flatMap(IEDAdapter::streamLDeviceAdapters)
.map(LDeviceAdapter::getLN0Adapter)
.map(ln0Adapter -> ln0Adapter.updateLDeviceStatus(iedNameLdInstList))
.flatMap(Optional::stream)
.toList();
}

@Override
public List<SclReportItem> updateDoInRef(SCL scd) {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.scl2007b4.model.TBay;
import org.lfenergy.compas.scl2007b4.model.TSubstation;
import org.lfenergy.compas.scl2007b4.model.TVoltageLevel;
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.api.SubstationEditor;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.sstation.BayAdapter;
import org.lfenergy.compas.sct.commons.scl.sstation.VoltageLevelAdapter;

import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
public class SubstationService implements SubstationEditor {
Expand Down Expand Up @@ -42,6 +45,21 @@ public void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdExceptio
}
}

/**
* Gets a pair of IedName and LDevice inst from Substation LNodes for LN0 type object
* @return a pair of Ied name and LDevice inst attributes
*/
public List<TLNode> getLNodes(SCL scd) {
return scd.getSubstation().getFirst()
.getVoltageLevel().stream()
.flatMap(tVoltageLevel -> tVoltageLevel.getBay().stream())
.flatMap(tBay -> tBay.getFunction().stream())
.flatMap(tFunction -> tFunction.getLNode().stream())
.filter(tlNode -> tlNode.getLnClass().contains(TLLN0Enum.LLN_0.value()))
.toList();
}


/**
* Creates new VoltageLevel section or updates VoltageLevel contents
* @param scd SCL contain Substation in which VoltageLevel should be created/updated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import lombok.NonNull;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.scl2007b4.model.TLNode;
import org.lfenergy.compas.sct.commons.dto.*;
import org.lfenergy.compas.sct.commons.exception.ScdException;

Expand Down Expand Up @@ -137,13 +136,6 @@ public interface SclEditor {
*/
void importSTDElementsInSCD(SCL scd, List<SCL> stds) throws ScdException;

/**
* Activate used LDevice and Deactivate unused LDevice in {@link TLNode <em><b>TLNode </b></em>}
*
* @param scd SCL file for which LDevice should be activated or deactivated
* @return list of encountered errors
*/
List<SclReportItem> updateLDeviceStatus(SCL scd);

/**
* Update DAIs of DO InRef in all LN0 of the SCD using matching ExtRef information.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.TCompasLDeviceStatus;
import org.lfenergy.compas.scl2007b4.model.TLNode;
import org.lfenergy.compas.sct.commons.dto.SclReportItem;
import org.lfenergy.compas.sct.commons.util.ActiveStatus;

import java.util.List;
Expand All @@ -21,102 +21,48 @@
@Setter
public class LDeviceActivation {

private final List<Pair<String, String>> iedNameLdInstList;
public static final String LNODE_STATUS_PRIVATE_TYPE = "COMPAS-LNodeStatus";

private final List<TLNode> tlNodeList;
private boolean isUpdatable;
private String newVal;
private String errorMessage;

public LDeviceActivation(List<Pair<String, String>> iedNameLdInstList) {
this.iedNameLdInstList = iedNameLdInstList;
public LDeviceActivation(List<TLNode> tlNodeList) {
this.tlNodeList = tlNodeList;
}

/**
* checks whether LDevice status is authorized to be activated or Not
* @param iedName Ied name value which LDevice appear
* @param ldInst LDevice inst value
* @param compasLDeviceStatus Private value
* @param enumValues enum values
*/
public void checkLDeviceActivationStatus(String iedName, String ldInst, TCompasLDeviceStatus compasLDeviceStatus, Set<String> enumValues) {
public void checkLDeviceActivationStatus(String iedName, String ldInst, String lNodeStatus, Set<String> enumValues, List<SclReportItem> sclReportItems) {
String xpath = "/SCL/IED[@name=%s]/AccessPoint/Server/LDevice[@inst=%s]".formatted(iedName, ldInst);
if (!enumValues.contains(ActiveStatus.ON.getValue()) && !enumValues.contains(ActiveStatus.OFF.getValue())) {
errorMessage = "The LDevice cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'.";
}
if (!enumValues.contains(ActiveStatus.ON.getValue()) && enumValues.contains(ActiveStatus.OFF.getValue())) {
if (isDeclaredInSubstation(iedName, ldInst)) {
errorMessage = "The LDevice cannot be set to 'on' but has been selected into SSD.";
} else {
isUpdatable = true;
newVal = ActiveStatus.OFF.getValue();
}
}
if(compasLDeviceStatus.equals(TCompasLDeviceStatus.ACTIVE) ||
compasLDeviceStatus.equals(TCompasLDeviceStatus.UNTESTED)){
checkAuthorisationToActivateLDevice(iedName, ldInst, enumValues);
}
if(compasLDeviceStatus.equals(TCompasLDeviceStatus.INACTIVE)){
checkAuthorisationToDeactivateLDevice(iedName, ldInst, enumValues);
}
}

/**
* checks whether LDevice status is authorized to be activated when CompasLDeviceStatus Private is ACTIVE or UNTESTED
* @param iedName Ied name value which contains LDevice
* @param ldInst LDevice inst value
* @param enumValues enum values
*/
private void checkAuthorisationToActivateLDevice(String iedName, String ldInst, Set<String> enumValues) {
if (!enumValues.contains(ActiveStatus.OFF.getValue()) && enumValues.contains(ActiveStatus.ON.getValue())) {
if (isDeclaredInSubstation(iedName, ldInst)) {
isUpdatable = true;
newVal = ActiveStatus.ON.getValue();
} else {
errorMessage = "The LDevice cannot be set to 'off' but has not been selected into SSD.";
}
}
if (enumValues.contains(ActiveStatus.ON.getValue()) && enumValues.contains(ActiveStatus.OFF.getValue())) {
isUpdatable = true;
if (isDeclaredInSubstation(iedName, ldInst)) {
newVal = ActiveStatus.ON.getValue();
} else {
newVal = ActiveStatus.OFF.getValue();
}
}

}

/**
* checks whether LDevice Status is authorized to be deactivated when CompasLDeviceStatus Private is INACTIVE
* @param iedName Ied name value which contains LDevice
* @param ldInst LDevice inst value
* @param enumValues enum values
*/
private void checkAuthorisationToDeactivateLDevice(String iedName, String ldInst, Set<String> enumValues) {
if (!enumValues.contains(ActiveStatus.OFF.getValue()) && enumValues.contains(ActiveStatus.ON.getValue())) {
if (isDeclaredInSubstation(iedName, ldInst)) {
errorMessage = "The LDevice is not qualified into STD but has been selected into SSD.";
} else {
errorMessage = "The LDevice cannot be set to 'off' but has not been selected into SSD.";
}
}
if (enumValues.contains(ActiveStatus.ON.getValue()) && enumValues.contains(ActiveStatus.OFF.getValue())) {
if (isDeclaredInSubstation(iedName, ldInst)) {
errorMessage = "The LDevice is not qualified into STD but has been selected into SSD.";
} else {
isUpdatable = true;
newVal = ActiveStatus.OFF.getValue();
}
sclReportItems.add(SclReportItem.error(xpath, "The LDevice cannot be activated or desactivated because its BehaviourKind Enum contains NOT 'on' AND NOT 'off'."));
} else {
tlNodeList.stream().filter(tlNode1 -> tlNode1.isSetIedName() && tlNode1.isSetLdInst())
.filter(tlNode1 -> tlNode1.getIedName().equals(iedName) && tlNode1.getLdInst().equals(ldInst))
.findFirst()
.ifPresentOrElse(tlNode1 -> {
if(!enumValues.contains(ActiveStatus.ON.getValue())) {
sclReportItems.add(SclReportItem.error(xpath, "The LDevice cannot be set to 'on' but has been selected into SSD."));
} else
// Activate LDevice
if(lNodeStatus.equals("on") || lNodeStatus.equals("on;off")|| lNodeStatus.equals("off;on")){
isUpdatable = true;
newVal = ActiveStatus.ON.getValue();
} else
// Deactivate LDevice
if(lNodeStatus.equals("off")){
sclReportItems.add(SclReportItem.error(xpath, "The LDevice is not qualified into STD but has been selected into SSD."));
}
}, () -> {
// Deactivate LDevice
isUpdatable = true;
newVal = ActiveStatus.OFF.getValue();
});
}
}

/**
* checks whether a pair of IED name and LDevice inst are referenced in Substation...LNode list
* @param iedName Ied name value
* @param ldInst LDevice inst value
* @return Returns whether a pair of IED name and LDevice inst are referenced in Substation...LNode list
*/
private boolean isDeclaredInSubstation(String iedName, String ldInst){
return iedNameLdInstList.contains(Pair.of(iedName, ldInst));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.lfenergy.compas.sct.commons.scl.ied.InputsAdapter;
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceActivation;
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
import org.lfenergy.compas.sct.commons.util.ActiveStatus;
import org.lfenergy.compas.sct.commons.util.PrivateUtils;

import java.util.List;
Expand Down Expand Up @@ -176,7 +177,7 @@ public void removeAllControlBlocksAndDatasets() {
* @return Set of Errors
*/
public Optional<SclReportItem> updateLDeviceStatus(List<Pair<String, String>> iedNameLDeviceInstList) {
LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLDeviceInstList);
// LDeviceActivation lDeviceActivation = new LDeviceActivation(iedNameLDeviceInstList);
final String iedName = getParentAdapter().getParentAdapter().getName();
final String ldInst = getParentAdapter().getInst();
DataAttributeRef daiBehFilter = new DataAttributeRef(this, BEHAVIOUR_DO_TYPE_NAME, BEHAVIOUR_DA_TYPE_NAME);
Expand All @@ -199,20 +200,21 @@ public Optional<SclReportItem> updateLDeviceStatus(List<Pair<String, String>> ie
}
DataAttributeRef newDaModToSetInLN0 = optionalModStVal.get();
String initialValue = newDaModToSetInLN0.findFirstValue().orElse("");
lDeviceActivation.checkLDeviceActivationStatus(iedName, ldInst, compasLDeviceStatus, enumValues);
if (lDeviceActivation.isUpdatable()) {
if (!initialValue.equals(lDeviceActivation.getNewVal())) {
newDaModToSetInLN0.setVal(lDeviceActivation.getNewVal());
updateDAI(newDaModToSetInLN0);
}
} else {
if (lDeviceActivation.getErrorMessage() != null) {
return Optional.of(buildFatalReportItem(lDeviceActivation.getErrorMessage()));
}
}
// lDeviceActivation.checkLDeviceActivationStatus(iedName, ldInst, compasLDeviceStatus, enumValues);
// if (lDeviceActivation.isUpdatable()) {
// if (!initialValue.equals(lDeviceActivation.getNewVal())) {
// newDaModToSetInLN0.setVal(lDeviceActivation.getNewVal());
// updateDAI(newDaModToSetInLN0);
// }
// } else {
// if (lDeviceActivation.getErrorMessage() != null) {
// return Optional.of(buildFatalReportItem(lDeviceActivation.getErrorMessage()));
// }
// }
return Optional.empty();
}


private static DaTypeName getDaTypeNameForBeh() {
DaTypeName daTypeNameBeh = new DaTypeName();
daTypeNameBeh.setName(STVAL_DA_NAME);
Expand Down
Loading

0 comments on commit e28e8e1

Please sign in to comment.