Skip to content

Commit

Permalink
Merge pull request #434 from com-pas/develop
Browse files Browse the repository at this point in the history
Release 0.2.30
  • Loading branch information
GuillaumeJAFFRE authored Oct 14, 2024
2 parents 00a334c + d47bf74 commit ebbac56
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 565 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
import org.junit.jupiter.api.Test;
import org.lfenergy.compas.scl2007b4.model.LN0;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.sct.commons.ControlBlockEditorService;
import org.lfenergy.compas.sct.commons.LdeviceService;
import org.lfenergy.compas.sct.commons.SclService;
import org.lfenergy.compas.sct.commons.SubstationService;
import org.lfenergy.compas.sct.commons.*;
import org.lfenergy.compas.sct.commons.api.ControlBlockEditor;
import org.lfenergy.compas.sct.commons.api.SclEditor;
import org.lfenergy.compas.sct.commons.api.SubstationEditor;
Expand All @@ -34,7 +31,7 @@ class SclAutomationServiceIntegrationTest {

private SclAutomationService sclAutomationService ;
private static final SclEditor sclEditor = new SclService() ;
private static final SubstationEditor substationEditor = new SubstationService() ;
private static final SubstationEditor substationEditor = new SubstationService(new VoltageLevelService()) ;
private static final ControlBlockEditor controlBlockEditor = new ControlBlockEditorService(new ControlService(), new LdeviceService()) ;

private HeaderDTO headerDTO;
Expand Down
19 changes: 0 additions & 19 deletions sct-commons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -197,25 +197,6 @@
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>cb_po</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>
<source>
${project.basedir}/src/main/resources/xsd/CB_REPORT_SUPERVISION_Config_file.xsd
</source>
</sources>
<xjbSources>
<xjbSource>${project.basedir}/src/main/resources/binding_configuration.xjb</xjbSource>
</xjbSources>
<packageName>org.lfenergy.compas.sct.commons.model.cb_po</packageName>
<noPackageLevelAnnotations>true</noPackageLevelAnnotations>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>cbcom</id>
<goals>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
package org.lfenergy.compas.sct.commons;

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.lfenergy.compas.sct.commons.api.SubstationEditor;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter;
import org.lfenergy.compas.sct.commons.scl.sstation.VoltageLevelAdapter;

@RequiredArgsConstructor
public class SubstationService implements SubstationEditor {

private final VoltageLevelService voltageLevelService;

@Override
public void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdException {
if (scd.getSubstation().size() > 1) {
Expand All @@ -25,53 +26,48 @@ public void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdExceptio
if (ssd.getSubstation().size() != 1) {
throw new ScdException(String.format("SSD file must have exactly 1 Substation, but got %d", ssd.getSubstation().size()));
}
TSubstation ssdTSubstation = ssd.getSubstation().get(0);
TSubstation ssdTSubstation = ssd.getSubstation().getFirst();
if (scd.getSubstation().isEmpty()) {
scd.getSubstation().add(ssdTSubstation);
} else {
TSubstation scdTSubstation = scd.getSubstation().get(0);
if (scdTSubstation.getName().equalsIgnoreCase(ssdTSubstation.getName())) {
SubstationAdapter scdSubstationAdapter = new SclRootAdapter(scd).getSubstationAdapter(scdTSubstation.getName());
TSubstation scdTSubstation = scd.getSubstation().getFirst();
if (scdTSubstation.getName().equalsIgnoreCase(ssdTSubstation.getName())){
for (TVoltageLevel tvl : ssdTSubstation.getVoltageLevel()) {
updateVoltageLevel(scdSubstationAdapter, tvl);
updateVoltageLevel(scd, tvl);
}
} else
} else {
throw new ScdException("SCD file must have only one Substation and the Substation name from SSD file is" +
" different from the one in SCD file. The files are rejected.");
}
}
}

/**
* Creates new VoltageLevel section or updates VoltageLevel contents
* @param scdSubstationAdapter Substation in which VoltageLevel should be created/updated
* @param scd SCL contain Substation in which VoltageLevel should be created/updated
* @param vl VoltageLevel to create/update
* @throws ScdException throws when unable to create new VoltageLevel section which is not already present in Substation
*/
private void updateVoltageLevel(@NonNull SubstationAdapter scdSubstationAdapter, TVoltageLevel vl) throws ScdException {
if (scdSubstationAdapter.getVoltageLevelAdapter(vl.getName()).isPresent()) {
VoltageLevelAdapter scdVoltageLevelAdapter = scdSubstationAdapter.getVoltageLevelAdapter(vl.getName())
.orElseThrow(() -> new ScdException("Unable to create VoltageLevelAdapter"));
for (TBay tbay : vl.getBay()) {
updateBay(scdVoltageLevelAdapter, tbay);
}
} else {
scdSubstationAdapter.getCurrentElem().getVoltageLevel().add(vl);
}
private void updateVoltageLevel(@NonNull SCL scd, TVoltageLevel vl) throws ScdException {
voltageLevelService.findVoltageLevel(scd, tVoltageLevel -> tVoltageLevel.getName().equals(vl.getName()))
.ifPresentOrElse(tVoltageLevel -> vl.getBay().forEach(tBay -> updateBay(tVoltageLevel, tBay)),
()-> scd.getSubstation().getFirst().getVoltageLevel().add(vl));
}


/**
* Adds new Bay in VoltageLevel or if already exist removes and replaces it
* @param scdVoltageLevelAdapter VoltageLevel in which Bay should be created/updated
* @param tVoltageLevel VoltageLevel in which Bay should be created/updated
* @param tBay Bay to add
*/
private void updateBay(@NonNull VoltageLevelAdapter scdVoltageLevelAdapter, TBay tBay) {
if (scdVoltageLevelAdapter.getBayAdapter(tBay.getName()).isPresent()) {
scdVoltageLevelAdapter.getCurrentElem().getBay()
.removeIf(t -> t.getName().equalsIgnoreCase(tBay.getName()));
scdVoltageLevelAdapter.getCurrentElem().getBay().add(tBay);
} else {
scdVoltageLevelAdapter.getCurrentElem().getBay().add(tBay);
}
private void updateBay(@NonNull TVoltageLevel tVoltageLevel, TBay tBay) {
tVoltageLevel.getBay()
.stream().filter(tBay1 -> tBay1.getName().equals(tBay.getName()))
.findFirst()
.ifPresentOrElse(tBay1 -> {
tVoltageLevel.getBay().removeIf(t -> t.getName().equalsIgnoreCase(tBay.getName()));
tVoltageLevel.getBay().add(tBay);
}, ()-> tVoltageLevel.getBay().add(tBay));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2024 RTE FRANCE
//
// SPDX-License-Identifier: Apache-2.0

package org.lfenergy.compas.sct.commons;

import org.lfenergy.compas.scl2007b4.model.*;

import java.util.Collection;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class VoltageLevelService {

public Stream<TVoltageLevel> getVoltageLevels(SCL scd) {
if (!scd.isSetSubstation()) {
return Stream.empty();
}
return scd.getSubstation()
.stream()
.map(TSubstation::getVoltageLevel)
.flatMap(Collection::stream);
}

public Optional<TVoltageLevel> findVoltageLevel(SCL scd, Predicate<TVoltageLevel> tVoltageLevelPredicate) {
return getVoltageLevels(scd).filter(tVoltageLevelPredicate).findFirst();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,18 @@
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.*;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.model.cb_po.PO;
import org.lfenergy.compas.sct.commons.model.cb_po.TFCDAFilter;
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter;
import org.lfenergy.compas.sct.commons.scl.ied.ControlBlockAdapter;
import org.lfenergy.compas.sct.commons.scl.ied.DataSetAdapter;
import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
import org.lfenergy.compas.sct.commons.scl.ln.AbstractLNAdapter;
import org.lfenergy.compas.sct.commons.scl.ln.LN0Adapter;
import org.lfenergy.compas.sct.commons.scl.ln.LNAdapter;
import org.lfenergy.compas.sct.commons.util.ActiveStatus;
import org.lfenergy.compas.sct.commons.util.ControlBlockEnum;
import org.lfenergy.compas.sct.commons.util.MonitoringLnClassEnum;
import org.lfenergy.compas.sct.commons.util.Utils;

import java.util.*;

import static org.lfenergy.compas.sct.commons.util.CommonConstants.*;
import static org.lfenergy.compas.sct.commons.util.Utils.copySclElement;

/**
Expand Down Expand Up @@ -63,10 +57,7 @@
@Slf4j
public class LDeviceAdapter extends SclElementAdapter<IEDAdapter, TLDevice> {

private static final long INTG_PD_VALUE_FOR_FC_MX = 2000L;

private static final String DA_SETSRCREF = "setSrcRef";
private static final String CYC_REPORT_TYPE = "CYC";

/**
* Constructor
Expand All @@ -78,43 +69,6 @@ public LDeviceAdapter(IEDAdapter parentAdapter, TLDevice currentElem) {
super(parentAdapter, currentElem);
}

/**
* Create DataSet and ReportControl Blocks for the HMI with the given FCDAs.
* DataSet and ReportControl are created in LN0, even if FCDA refers to another LN.
*
* @param po object containing list of FCDA for which we must create the DataSet and ReportControl
*/
public void createHmiReportControlBlocks(PO po) {
LN0Adapter ln0 = getLN0Adapter();
if (!ln0.getDaiModStValValue().map(ActiveStatus::fromValue).map(ActiveStatus.ON::equals).orElse(false)) return;
po.getFCDAs().getFCDA().stream()
.filter(tfcdaFilter -> getInst().equals(tfcdaFilter.getLdInst()) && tfcdaFilter.isSetLnClass())
.forEach(tfcdaFilter -> (tfcdaFilter.getLnClass().equals(TLLN0Enum.LLN_0.value()) ?
Optional.of(ln0) // ln0 Mod stVal "ON" has already been checked, no need to check it again
:
findLnAdapter(tfcdaFilter.getLnClass(), tfcdaFilter.getLnInst(), tfcdaFilter.getPrefix()).filter(lnAdapter -> lnAdapter.getDaiModStValValue().map(ActiveStatus::fromValue).map(ActiveStatus.ON::equals).orElse(true)))
.map(sourceLn -> sourceLn.getDAI(new DataAttributeRef(toFCDA(tfcdaFilter)), false))
.filter(das -> das.stream().anyMatch(da -> TFCEnum.fromValue(tfcdaFilter.getFc().value()) == da.getFc())) // getDAI does not filter on DA.
.ifPresent(dataAttributeRefs -> createHmiReportCB(ln0, tfcdaFilter)));
}

private void createHmiReportCB(LN0Adapter ln0, TFCDAFilter tfcdaFilter) {
TFCDA fcda = toFCDA(tfcdaFilter);
String dataSetSuffix = getInst().toUpperCase(Locale.ENGLISH) + ATTRIBUTE_VALUE_SEPARATOR + tfcdaFilter.getReportType().substring(0, 2) + "PO";
String dataSetName = DATASET_NAME_PREFIX + dataSetSuffix;
DataSetAdapter dataSet = ln0.createDataSetIfNotExists(dataSetName, ControlBlockEnum.REPORT);
dataSet.createFCDAIfNotExists(fcda.getLdInst(), fcda.getPrefix(), fcda.getLnClass().getFirst(), fcda.getLnInst(), fcda.getDoName(), fcda.getDaName(), fcda.getFc());
String cbName = CONTROLBLOCK_NAME_PREFIX + dataSetSuffix;
String cbId = ln0.generateControlBlockId(getLdName(), cbName);
ControlBlockAdapter controlBlockAdapter = ln0.createControlBlockIfNotExists(cbName, cbId, dataSetName, ControlBlockEnum.REPORT);
if (tfcdaFilter.getReportType().equals(CYC_REPORT_TYPE)) {
TReportControl tReportControl = (TReportControl) controlBlockAdapter.getCurrentElem();
tReportControl.setIntgPd(INTG_PD_VALUE_FOR_FC_MX);
tReportControl.getTrgOps().setDchg(false);
tReportControl.getTrgOps().setQchg(false);
}
}

/**
* Check if node is child of the reference node
*
Expand Down Expand Up @@ -483,15 +437,4 @@ private String createVal(TExtRef tExtRef) {
return sourceLdName + "/" + lnClass + "." + tExtRef.getSrcCBName();
}

private TFCDA toFCDA(TFCDAFilter tfcdaFilter) {
TFCDA tfcda = new TFCDA();
tfcda.setLdInst(tfcdaFilter.getLdInst());
tfcda.getLnClass().add(tfcdaFilter.getLnClass());
tfcda.setPrefix(tfcdaFilter.getPrefix());
tfcda.setLnInst(tfcdaFilter.getLnInst());
tfcda.setDoName(tfcdaFilter.getDoName());
tfcda.setFc(TFCEnum.fromValue(tfcdaFilter.getFc().value()));
return tfcda;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public final class Utils {
private static final Pattern MAC_ADDRESS_PATTERN = Pattern.compile("[0-9A-F]{2}([-:][0-9A-F]{2}){5}", Pattern.CASE_INSENSITIVE);

private static JAXBContext jaxbContext = null;
private static Unmarshaller unmarshaller = null;

/**
* Private Constructor, should not be instanced
Expand Down Expand Up @@ -149,7 +148,7 @@ public static String xpathAttributeFilter(String name, Collection<String> value)
* @param s1 first string
* @param s2 seconde string
* @return true if strings are equals or both blank, false otherwise
* @see org.apache.commons.lang3.StringUtils#isBlank(CharSequence)
* @see StringUtils#isBlank(CharSequence)
*/
public static boolean equalsOrBothBlank(String s1, String s2) {
return Objects.equals(s1, s2)
Expand All @@ -167,9 +166,9 @@ public static boolean equalsOrBothBlank(String s1, String s2) {
* @param s2 second String to compare
* @return when s1 and s2 are not blank, same result as {@link String#compare(CharSequence, CharSequence)},
* zero when s1 and s2 are both blanks, negative integer when s1 is blank and s2 is not, positive integer when s1 is not blank but s2 is.
* @see java.util.Comparator#compare(Object, Object)
* @see org.apache.commons.lang3.StringUtils#isBlank(CharSequence)
* @see java.util.Comparator#nullsFirst(Comparator)
* @see Comparator#compare(Object, Object)
* @see StringUtils#isBlank(CharSequence)
* @see Comparator#nullsFirst(Comparator)
*/
public static int blanksFirstComparator(String s1, String s2) {
if (StringUtils.isBlank(s1)){
Expand Down Expand Up @@ -314,11 +313,12 @@ public static String toHex(long number, int length) {
* @return copy of the object
*/
public static <T> T copySclElement(T object, Class<T> clazz) {
Unmarshaller unmarshaller;
try {
if (jaxbContext == null) {
jaxbContext = JAXBContext.newInstance("org.lfenergy.compas.scl2007b4.model");
unmarshaller = jaxbContext.createUnmarshaller();
}
unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement<T> contentObject = new JAXBElement<>(new QName(clazz.getSimpleName()), clazz, object);
JAXBSource source = new JAXBSource(jaxbContext, contentObject);
return unmarshaller.unmarshal(source, clazz).getValue();
Expand Down
Loading

0 comments on commit ebbac56

Please sign in to comment.