4
4
5
5
package org .lfenergy .compas .sct .commons ;
6
6
7
+ import lombok .Getter ;
7
8
import lombok .RequiredArgsConstructor ;
8
9
import org .lfenergy .compas .scl2007b4 .model .*;
9
10
import org .lfenergy .compas .sct .commons .api .ExtRefEditor ;
15
16
import org .lfenergy .compas .sct .commons .model .epf .TCBScopeType ;
16
17
import org .lfenergy .compas .sct .commons .model .epf .TChannel ;
17
18
import org .lfenergy .compas .sct .commons .model .epf .TChannelType ;
19
+ import org .lfenergy .compas .sct .commons .model .epf .TChannelLevMod ;
18
20
import org .lfenergy .compas .sct .commons .scl .SclRootAdapter ;
19
21
import org .lfenergy .compas .sct .commons .scl .ied .IEDAdapter ;
20
22
import org .lfenergy .compas .sct .commons .scl .ldevice .LDeviceAdapter ;
34
36
@ RequiredArgsConstructor
35
37
public class ExtRefEditorService implements ExtRefEditor {
36
38
private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info" ;
39
+ private static final String COMPAS_LNODE_STATUS = "COMPAS-LNodeStatus" ;
40
+ private static final List <DoNameAndDaName > DO_DA_MAPPINGS = List .of (
41
+ new DoNameAndDaName (CHNUM1_DO_NAME , DU_DA_NAME ),
42
+ new DoNameAndDaName (LEVMOD_DO_NAME , SETVAL_DA_NAME ),
43
+ new DoNameAndDaName (MOD_DO_NAME , STVAL_DA_NAME ),
44
+ new DoNameAndDaName (SRCREF_DO_NAME , SETSRCREF_DA_NAME )
45
+ );
37
46
38
47
private final IedService iedService ;
39
48
private final LdeviceService ldeviceService ;
40
49
private final LnEditor lnEditor ;
41
- private final DataTypeTemplatesService dataTypeTemplatesService ;
50
+
51
+ @ Getter
52
+ private final List <SclReportItem > errorHandler = new ArrayList <>();
42
53
43
54
/**
44
55
* Provides valid IED sources according to EPF configuration.<br/>
@@ -76,30 +87,21 @@ private List<TIED> getIedSources(SclRootAdapter sclRootAdapter, TCompasBay compa
76
87
* - The location of ExtRef should be in LDevice (inst=LDEPF) <br/>
77
88
* - ExtRef that lacks Bay or ICDHeader Private is not returned <br/>
78
89
*
79
- * @param sclReportItems List of SclReportItem
80
90
* @return list of ExtRef and associated Bay
81
91
*/
82
- private List <ExtRefInfo .ExtRefWithBayReference > getExtRefWithBayReferenceInLDEPF (TDataTypeTemplates dataTypeTemplates , TIED tied , final TLDevice tlDevice , final List <SclReportItem > sclReportItems ) {
83
- List <ExtRefInfo .ExtRefWithBayReference > extRefBayReferenceList = new ArrayList <>();
92
+ private List <ExtRefInfo .ExtRefWithBayReference > getExtRefWithBayReferenceInLDEPF (TIED tied , final TLDevice tlDevice ) {
84
93
String lDevicePath = "SCL/IED[@name=\" " + tied .getName () + "\" ]/AccessPoint/Server/LDevice[@inst=\" " + tlDevice .getInst () + "\" ]" ;
85
94
Optional <TCompasBay > tCompasBay = PrivateUtils .extractCompasPrivate (tied , TCompasBay .class );
86
95
if (tCompasBay .isEmpty ()) {
87
- sclReportItems .add (SclReportItem .error (lDevicePath , "The IED has no Private Bay" ));
96
+ errorHandler .add (SclReportItem .error (lDevicePath , "The IED has no Private Bay" ));
88
97
if (PrivateUtils .extractCompasPrivate (tied , TCompasICDHeader .class ).isEmpty ()) {
89
- sclReportItems .add (SclReportItem .error (lDevicePath , "The IED has no Private compas:ICDHeader" ));
98
+ errorHandler .add (SclReportItem .error (lDevicePath , "The IED has no Private compas:ICDHeader" ));
90
99
}
91
100
return Collections .emptyList ();
92
101
}
93
-
94
- if (dataTypeTemplatesService .isDoModAndDaStValExist (dataTypeTemplates , tlDevice .getLN0 ().getLnType ())) {
95
- extRefBayReferenceList .addAll (tlDevice .getLN0 ()
96
- .getInputs ()
97
- .getExtRef ().stream ()
98
- .map (extRef -> new ExtRefInfo .ExtRefWithBayReference (tied .getName (), tCompasBay .get (), extRef )).toList ());
99
- } else {
100
- sclReportItems .add (SclReportItem .error (lDevicePath , "DO@name=Mod/DA@name=stVal not found in DataTypeTemplate" ));
101
- }
102
- return extRefBayReferenceList ;
102
+ return tlDevice .getLN0 ().getInputs ().getExtRef ().stream ()
103
+ .map (extRef -> new ExtRefInfo .ExtRefWithBayReference (tied .getName (), tCompasBay .get (), extRef ))
104
+ .toList ();
103
105
}
104
106
105
107
/**
@@ -114,7 +116,7 @@ private static Boolean doesExtRefMatchLDEPFChannel(TExtRef extRef, TChannel tCha
114
116
&& extRef .getDesc ().startsWith ("DYN_LDEPF_ANALOG CHANNEL " + tChannel .getChannelNum () + "_1_AnalogueValue" )
115
117
&& extRef .getDesc ().endsWith ("_" + tChannel .getDAName () + "_1" );
116
118
Boolean doesExtRefDescMatchDigitalChannel = tChannel .getChannelType ().equals (TChannelType .DIGITAL )
117
- && extRef .getDesc ().startsWith ("DYN_LDEPF_DIGITAL CHANNEL " + tChannel .getChannelNum () + "_1_BOOLEEN " )
119
+ && extRef .getDesc ().startsWith ("DYN_LDEPF_DIGITAL CHANNEL " + tChannel .getChannelNum () + "_1_BOOLEAN " )
118
120
&& extRef .getDesc ().endsWith ("_" + tChannel .getDAName () + "_1" );
119
121
return extRef .isSetDesc () && (doesExtRefDescMatchAnalogChannel || doesExtRefDescMatchDigitalChannel )
120
122
&& extRef .isSetPLN () && Utils .lnClassEquals (extRef .getPLN (), tChannel .getLNClass ())
@@ -263,29 +265,30 @@ public TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws ScdExce
263
265
264
266
@ Override
265
267
public List <SclReportItem > manageBindingForLDEPF (SCL scd , EPF epf ) {
266
- List < SclReportItem > sclReportItems = new ArrayList <> ();
268
+ errorHandler . clear ();
267
269
SclRootAdapter sclRootAdapter = new SclRootAdapter (scd );
268
- if (!epf .isSetChannels ()) return sclReportItems ;
270
+ if (!epf .isSetChannels ()) return errorHandler ;
269
271
iedService .getFilteredIeds (scd , ied -> !ied .getName ().contains ("TEST" ))
270
- .forEach (tied -> ldeviceService .findLdevice (tied , LDEVICE_LDEPF )
271
- .ifPresent (tlDevice -> getExtRefWithBayReferenceInLDEPF (scd .getDataTypeTemplates (), tied , tlDevice , sclReportItems )
272
+ .forEach (tied -> ldeviceService .findLdevice (tied , tlDevice -> tlDevice .getInst ().equals (LDEVICE_LDEPF ))
273
+ .filter (ldepfLdevice -> PrivateUtils .extractStringPrivate (ldepfLdevice .getLN0 (), COMPAS_LNODE_STATUS ).map (status -> !status .equals ("off" )).orElse (false ))
274
+ .ifPresent (ldepfLdevice -> getExtRefWithBayReferenceInLDEPF (tied , ldepfLdevice )
272
275
.forEach (extRefBayRef -> epf .getChannels ().getChannel ().stream ().filter (tChannel -> doesExtRefMatchLDEPFChannel (extRefBayRef .extRef (), tChannel ))
273
276
.findFirst ().ifPresent (channel -> {
274
277
List <TIED > iedSources = getIedSources (sclRootAdapter , extRefBayRef .compasBay (), channel );
275
278
if (iedSources .size () == 1 ) {
276
- updateLDEPFExtRefBinding (extRefBayRef . extRef () , iedSources .getFirst (), channel );
277
- LDeviceAdapter lDeviceAdapter = new LDeviceAdapter (new IEDAdapter (sclRootAdapter , tied .getName ()), tlDevice );
278
- sclReportItems . addAll ( updateLDEPFDos (lDeviceAdapter , extRefBayRef .extRef (), channel ) );
279
+ updateLDEPFExtRefBinding (extRefBayRef , iedSources .getFirst (), channel );
280
+ LDeviceAdapter lDeviceAdapter = new LDeviceAdapter (new IEDAdapter (sclRootAdapter , tied .getName ()), ldepfLdevice );
281
+ updateLDEPFDos (lDeviceAdapter , extRefBayRef .extRef (), channel );
279
282
} else {
280
283
if (iedSources .size () > 1 ) {
281
- sclReportItems .add (SclReportItem .warning (null , "There is more than one IED source to bind the signal " +
284
+ errorHandler .add (SclReportItem .warning (null , "There is more than one IED source to bind the signal " +
282
285
"/IED@name=" + extRefBayRef .iedName () + "/LDevice@inst=LDEPF/LN0" +
283
286
"/ExtRef@desc=" + extRefBayRef .extRef ().getDesc ()));
284
287
}
285
288
// If the source IED is not found, there will be no update or report message.
286
289
}
287
290
}))));
288
- return sclReportItems ;
291
+ return errorHandler ;
289
292
}
290
293
291
294
@ Override
@@ -320,56 +323,65 @@ public void epfPostProcessing(SCL scd) {
320
323
})));
321
324
}
322
325
323
- private void updateLDEPFExtRefBinding (TExtRef extRef , TIED iedSource , TChannel setting ) {
324
- extRef .setIedName (iedSource .getName ());
325
- extRef .setLdInst (setting .getLDInst ());
326
- extRef .getLnClass ().add (setting .getLNClass ());
327
- extRef .setLnInst (setting .getLNInst ());
326
+ private void updateLDEPFExtRefBinding (ExtRefInfo .ExtRefWithBayReference extRefWithBay , TIED iedSource , TChannel setting ) {
327
+ TExtRef tExtRef = extRefWithBay .extRef ();
328
+ tExtRef .setIedName (iedSource .getName ());
329
+ tExtRef .setLdInst (setting .getLDInst ());
330
+ tExtRef .getLnClass ().add (setting .getLNClass ());
331
+ tExtRef .setLnInst (setting .getLNInst ());
328
332
if (!isBlank (setting .getLNPrefix ())) {
329
- extRef .setPrefix (setting .getLNPrefix ());
333
+ tExtRef .setPrefix (setting .getLNPrefix ());
330
334
}
331
335
String doName = isBlank (setting .getDOInst ()) || setting .getDOInst ().equals ("0" ) ? setting .getDOName () : setting .getDOName () + setting .getDOInst ();
332
- extRef .setDoName (doName );
336
+ tExtRef .setDoName (doName );
337
+ // This is true for External Binding
338
+ if (!extRefWithBay .iedName ().equals (iedSource .getName ())) {
339
+ tExtRef .setServiceType (
340
+ switch (setting .getChannelType ()) {
341
+ case DIGITAL -> TServiceType .GOOSE ;
342
+ case ANALOG -> TServiceType .SMV ;
343
+ });
344
+ }
333
345
}
334
346
335
- private List <SclReportItem > updateLDEPFDos (LDeviceAdapter lDeviceAdapter , TExtRef extRef , TChannel setting ) {
336
- List <SclReportItem > sclReportItems = new ArrayList <>();
337
- List <DoNameAndDaName > doNameAndDaNameList = List .of (
338
- new DoNameAndDaName (CHNUM1_DO_NAME , DU_DA_NAME ),
339
- new DoNameAndDaName (LEVMOD_DO_NAME , SETVAL_DA_NAME ),
340
- new DoNameAndDaName (MOD_DO_NAME , STVAL_DA_NAME ),
341
- new DoNameAndDaName (SRCREF_DO_NAME , SETSRCREF_DA_NAME )
342
- );
347
+ private void updateLDEPFDos (LDeviceAdapter lDeviceAdapter , TExtRef extRef , TChannel setting ) {
343
348
if (setting .getChannelType ().equals (TChannelType .DIGITAL )) {
344
349
//digital
345
350
lDeviceAdapter .findLnAdapter (LN_RBDR , setting .getChannelNum (), null )
346
- .ifPresent (lnAdapter -> doNameAndDaNameList .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName . doName , doNameAndDaName . daName , extRef , setting ). ifPresent ( sclReportItems :: add )));
351
+ .ifPresent (lnAdapter -> DO_DA_MAPPINGS .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName , extRef , setting )));
347
352
lDeviceAdapter .findLnAdapter (LN_RBDR , setting .getChannelNum (), LN_PREFIX_B )
348
- .ifPresent (lnAdapter -> doNameAndDaNameList .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName . doName , doNameAndDaName . daName , extRef , setting ). ifPresent ( sclReportItems :: add )));
353
+ .ifPresent (lnAdapter -> DO_DA_MAPPINGS .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName , extRef , setting )));
349
354
}
350
355
if (setting .getChannelType ().equals (TChannelType .ANALOG )) {
351
356
//analog
352
357
lDeviceAdapter .findLnAdapter (LN_RADR , setting .getChannelNum (), null )
353
- .ifPresent (lnAdapter -> doNameAndDaNameList .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName . doName , doNameAndDaName . daName , extRef , setting ). ifPresent ( sclReportItems :: add )));
358
+ .ifPresent (lnAdapter -> DO_DA_MAPPINGS .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName , extRef , setting )));
354
359
lDeviceAdapter .findLnAdapter (LN_RADR , setting .getChannelNum (), LN_PREFIX_A )
355
- .ifPresent (lnAdapter -> doNameAndDaNameList .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName . doName , doNameAndDaName . daName , extRef , setting ). ifPresent ( sclReportItems :: add )));
360
+ .ifPresent (lnAdapter -> DO_DA_MAPPINGS .forEach (doNameAndDaName -> updateVal (lnAdapter , doNameAndDaName , extRef , setting )));
356
361
}
357
- return sclReportItems ;
358
362
}
359
363
360
- private Optional <SclReportItem > updateVal (AbstractLNAdapter <?> lnAdapter , String doName , String daName , TExtRef extRef , TChannel setting ) {
361
- String value = switch (daName ) {
362
- case DU_DA_NAME -> setting .getChannelShortLabel ();
363
- case SETVAL_DA_NAME -> LN_PREFIX_B .equals (lnAdapter .getPrefix ()) || LN_PREFIX_A .equals (lnAdapter .getPrefix ()) ? setting .getChannelLevModQ ().value () : setting .getChannelLevMod ().value ();
364
- case STVAL_DA_NAME -> ActiveStatus .ON .getValue ();
365
- case SETSRCREF_DA_NAME -> computeDaiValue (lnAdapter , extRef , setting .getDAName ());
366
- default -> null ;
364
+ private void updateVal (AbstractLNAdapter <?> lnAdapter , DoNameAndDaName doDaName , TExtRef extRef , TChannel setting ) {
365
+ String lnPrefix = lnAdapter .getPrefix ();
366
+ Optional <SclReportItem > sclReportItem = switch (doDaName .daName ) {
367
+ case DU_DA_NAME -> setting .isSetChannelShortLabel () ? lnAdapter .getDOIAdapterByName (doDaName .doName ).updateDAI (doDaName .daName , setting .getChannelShortLabel ()) :
368
+ Optional .empty ();
369
+ case SETVAL_DA_NAME -> {
370
+ if (LN_PREFIX_B .equals (lnPrefix ) || LN_PREFIX_A .equals (lnPrefix )) {
371
+ yield setting .isSetChannelLevModQ () && !setting .getChannelLevModQ ().equals (TChannelLevMod .NA ) ? lnAdapter .getDOIAdapterByName (doDaName .doName ).updateDAI (doDaName .daName , setting .getChannelLevModQ ().value ()) : Optional .empty ();
372
+ } else {
373
+ yield setting .isSetChannelLevMod () && !setting .getChannelLevMod ().equals (TChannelLevMod .NA ) ? lnAdapter .getDOIAdapterByName (doDaName .doName ).updateDAI (doDaName .daName , setting .getChannelLevMod ().value ()) : Optional .empty ();
374
+ }
375
+ }
376
+ case STVAL_DA_NAME -> lnAdapter .getDOIAdapterByName (doDaName .doName ).updateDAI (doDaName .daName , ActiveStatus .ON .getValue ());
377
+ case SETSRCREF_DA_NAME -> lnAdapter .getDOIAdapterByName (doDaName .doName ).updateDAI (doDaName .daName , computeDaiValue (lnPrefix , extRef , setting .getDAName ()));
378
+ default -> throw new IllegalStateException ("Unexpected value: " + doDaName .daName );
367
379
};
368
- return lnAdapter . getDOIAdapterByName ( doName ). updateDAI ( daName , value );
380
+ sclReportItem . ifPresent ( errorHandler :: add );
369
381
}
370
382
371
- private String computeDaiValue (AbstractLNAdapter <?> lnAdapter , TExtRef extRef , String daName ) {
372
- if (LN_PREFIX_B .equals (lnAdapter . getPrefix ()) || LN_PREFIX_A .equals (lnAdapter . getPrefix () )) {
383
+ private String computeDaiValue (String lnPrefix , TExtRef extRef , String daName ) {
384
+ if (LN_PREFIX_B .equals (lnPrefix ) || LN_PREFIX_A .equals (lnPrefix )) {
373
385
return extRef .getIedName () +
374
386
extRef .getLdInst () + "/" +
375
387
trimToEmpty (extRef .getPrefix ()) +
0 commit comments