@openscd/scl-lib 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENCE +201 -0
- package/README.md +20 -0
- package/dist/foundation/codecomponents/nsds.d.ts +5 -0
- package/dist/foundation/codecomponents/nsds.js +22435 -0
- package/dist/foundation/codecomponents/nsds.js.map +1 -0
- package/dist/foundation/nsd.json +137748 -0
- package/dist/foundation/uniqueElementName.d.ts +2 -0
- package/dist/foundation/uniqueElementName.js +18 -0
- package/dist/foundation/uniqueElementName.js.map +1 -0
- package/dist/foundation/utils.d.ts +20 -0
- package/dist/foundation/utils.js +14 -0
- package/dist/foundation/utils.js.map +1 -0
- package/dist/generator/appIdGenerator.d.ts +21 -0
- package/dist/generator/appIdGenerator.js +53 -0
- package/dist/generator/appIdGenerator.js.map +1 -0
- package/dist/generator/lnInstGenerator.d.ts +16 -0
- package/dist/generator/lnInstGenerator.js +41 -0
- package/dist/generator/lnInstGenerator.js.map +1 -0
- package/dist/generator/macAddressGenerator.d.ts +14 -0
- package/dist/generator/macAddressGenerator.js +39 -0
- package/dist/generator/macAddressGenerator.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/tAddress/changeGseOrSmvAddress.d.ts +14 -0
- package/dist/tAddress/changeGseOrSmvAddress.js +43 -0
- package/dist/tAddress/changeGseOrSmvAddress.js.map +1 -0
- package/dist/tBaseElement/find.d.ts +6 -0
- package/dist/tBaseElement/find.js +529 -0
- package/dist/tBaseElement/find.js.map +1 -0
- package/dist/tBaseElement/getChildren.d.ts +5 -0
- package/dist/tBaseElement/getChildren.js +12 -0
- package/dist/tBaseElement/getChildren.js.map +1 -0
- package/dist/tBaseElement/getReference.d.ts +9 -0
- package/dist/tBaseElement/getReference.js +31 -0
- package/dist/tBaseElement/getReference.js.map +1 -0
- package/dist/tBaseElement/identity.d.ts +2 -0
- package/dist/tBaseElement/identity.js +566 -0
- package/dist/tBaseElement/identity.js.map +1 -0
- package/dist/tBaseElement/isPublic.d.ts +2 -0
- package/dist/tBaseElement/isPublic.js +5 -0
- package/dist/tBaseElement/isPublic.js.map +1 -0
- package/dist/tBaseElement/parentTags.d.ts +3 -0
- package/dist/tBaseElement/parentTags.js +8 -0
- package/dist/tBaseElement/parentTags.js.map +1 -0
- package/dist/tBaseElement/tags.d.ts +8 -0
- package/dist/tBaseElement/tags.js +807 -0
- package/dist/tBaseElement/tags.js.map +1 -0
- package/dist/tBay/updateBay.d.ts +5 -0
- package/dist/tBay/updateBay.js +81 -0
- package/dist/tBay/updateBay.js.map +1 -0
- package/dist/tControl/controlBlockGseOrSmv.d.ts +7 -0
- package/dist/tControl/controlBlockGseOrSmv.js +26 -0
- package/dist/tControl/controlBlockGseOrSmv.js.map +1 -0
- package/dist/tControl/controlBlockObjRef.d.ts +2 -0
- package/dist/tControl/controlBlockObjRef.js +14 -0
- package/dist/tControl/controlBlockObjRef.js.map +1 -0
- package/dist/tControl/controlBlocks.d.ts +2 -0
- package/dist/tControl/controlBlocks.js +9 -0
- package/dist/tControl/controlBlocks.js.map +1 -0
- package/dist/tControl/findControlSubscription.d.ts +2 -0
- package/dist/tControl/findControlSubscription.js +8 -0
- package/dist/tControl/findControlSubscription.js.map +1 -0
- package/dist/tControl/pathId.d.ts +1 -0
- package/dist/tControl/pathId.js +9 -0
- package/dist/tControl/pathId.js.map +1 -0
- package/dist/tControl/removeControlBlock.d.ts +14 -0
- package/dist/tControl/removeControlBlock.js +35 -0
- package/dist/tControl/removeControlBlock.js.map +1 -0
- package/dist/tControl/updateConfRev.d.ts +2 -0
- package/dist/tControl/updateConfRev.js +8 -0
- package/dist/tControl/updateConfRev.js.map +1 -0
- package/dist/tControl/updateDatSet.d.ts +6 -0
- package/dist/tControl/updateDatSet.js +22 -0
- package/dist/tControl/updateDatSet.js.map +1 -0
- package/dist/tControlWithIEDName/connctedAp.d.ts +2 -0
- package/dist/tControlWithIEDName/connctedAp.js +7 -0
- package/dist/tControlWithIEDName/connctedAp.js.map +1 -0
- package/dist/tDataSet/canAddDataSet.d.ts +4 -0
- package/dist/tDataSet/canAddDataSet.js +44 -0
- package/dist/tDataSet/canAddDataSet.js.map +1 -0
- package/dist/tDataSet/createDataSet.d.ts +9 -0
- package/dist/tDataSet/createDataSet.js +33 -0
- package/dist/tDataSet/createDataSet.js.map +1 -0
- package/dist/tDataSet/removeDataSet.d.ts +10 -0
- package/dist/tDataSet/removeDataSet.js +27 -0
- package/dist/tDataSet/removeDataSet.js.map +1 -0
- package/dist/tDataSet/updateDataSet.d.ts +7 -0
- package/dist/tDataSet/updateDataSet.js +28 -0
- package/dist/tDataSet/updateDataSet.js.map +1 -0
- package/dist/tDataTypeTemplates/foundation.d.ts +2 -0
- package/dist/tDataTypeTemplates/foundation.js +118 -0
- package/dist/tDataTypeTemplates/foundation.js.map +1 -0
- package/dist/tDataTypeTemplates/importLNodeType.d.ts +13 -0
- package/dist/tDataTypeTemplates/importLNodeType.js +88 -0
- package/dist/tDataTypeTemplates/importLNodeType.js.map +1 -0
- package/dist/tDataTypeTemplates/insertSelectedLNodeType.d.ts +20 -0
- package/dist/tDataTypeTemplates/insertSelectedLNodeType.js +187 -0
- package/dist/tDataTypeTemplates/insertSelectedLNodeType.js.map +1 -0
- package/dist/tDataTypeTemplates/lNodeTypeToSelection.d.ts +8 -0
- package/dist/tDataTypeTemplates/lNodeTypeToSelection.js +67 -0
- package/dist/tDataTypeTemplates/lNodeTypeToSelection.js.map +1 -0
- package/dist/tDataTypeTemplates/nsdToJson.d.ts +101 -0
- package/dist/tDataTypeTemplates/nsdToJson.js +433 -0
- package/dist/tDataTypeTemplates/nsdToJson.js.map +1 -0
- package/dist/tDataTypeTemplates/removeDataType.d.ts +12 -0
- package/dist/tDataTypeTemplates/removeDataType.js +62 -0
- package/dist/tDataTypeTemplates/removeDataType.js.map +1 -0
- package/dist/tDataTypeTemplates/updateLNodeType.d.ts +2 -0
- package/dist/tDataTypeTemplates/updateLNodeType.js +22 -0
- package/dist/tDataTypeTemplates/updateLNodeType.js.map +1 -0
- package/dist/tExtRef/doesFcdaMeetExtRefRestrictions.d.ts +16 -0
- package/dist/tExtRef/doesFcdaMeetExtRefRestrictions.js +52 -0
- package/dist/tExtRef/doesFcdaMeetExtRefRestrictions.js.map +1 -0
- package/dist/tExtRef/extRefTypeRestrictions.d.ts +17 -0
- package/dist/tExtRef/extRefTypeRestrictions.js +32 -0
- package/dist/tExtRef/extRefTypeRestrictions.js.map +1 -0
- package/dist/tExtRef/isSubscribed.d.ts +7 -0
- package/dist/tExtRef/isSubscribed.js +23 -0
- package/dist/tExtRef/isSubscribed.js.map +1 -0
- package/dist/tExtRef/matchDataAttributes.d.ts +2 -0
- package/dist/tExtRef/matchDataAttributes.js +13 -0
- package/dist/tExtRef/matchDataAttributes.js.map +1 -0
- package/dist/tExtRef/matchSrcAttributes.d.ts +2 -0
- package/dist/tExtRef/matchSrcAttributes.js +28 -0
- package/dist/tExtRef/matchSrcAttributes.js.map +1 -0
- package/dist/tExtRef/sourceControlBlock.d.ts +8 -0
- package/dist/tExtRef/sourceControlBlock.js +52 -0
- package/dist/tExtRef/sourceControlBlock.js.map +1 -0
- package/dist/tExtRef/subscribe.d.ts +47 -0
- package/dist/tExtRef/subscribe.js +187 -0
- package/dist/tExtRef/subscribe.js.map +1 -0
- package/dist/tExtRef/unsubscribe.d.ts +27 -0
- package/dist/tExtRef/unsubscribe.js +55 -0
- package/dist/tExtRef/unsubscribe.js.map +1 -0
- package/dist/tFCDA/canAddFCDA.d.ts +10 -0
- package/dist/tFCDA/canAddFCDA.js +42 -0
- package/dist/tFCDA/canAddFCDA.js.map +1 -0
- package/dist/tFCDA/fcdaBaseTypes.d.ts +11 -0
- package/dist/tFCDA/fcdaBaseTypes.js +56 -0
- package/dist/tFCDA/fcdaBaseTypes.js.map +1 -0
- package/dist/tFCDA/removeFCDA.d.ts +8 -0
- package/dist/tFCDA/removeFCDA.js +33 -0
- package/dist/tFCDA/removeFCDA.js.map +1 -0
- package/dist/tGSE/changeGSEContent.d.ts +17 -0
- package/dist/tGSE/changeGSEContent.js +53 -0
- package/dist/tGSE/changeGSEContent.js.map +1 -0
- package/dist/tGSE/createGSE.d.ts +20 -0
- package/dist/tGSE/createGSE.js +44 -0
- package/dist/tGSE/createGSE.js.map +1 -0
- package/dist/tGSEControl/canAddGSEControl.d.ts +4 -0
- package/dist/tGSEControl/canAddGSEControl.js +27 -0
- package/dist/tGSEControl/canAddGSEControl.js.map +1 -0
- package/dist/tGSEControl/createGSEControl.d.ts +49 -0
- package/dist/tGSEControl/createGSEControl.js +65 -0
- package/dist/tGSEControl/createGSEControl.js.map +1 -0
- package/dist/tGSEControl/updateGSEControl.d.ts +15 -0
- package/dist/tGSEControl/updateGSEControl.js +61 -0
- package/dist/tGSEControl/updateGSEControl.js.map +1 -0
- package/dist/tIED/insertIED.d.ts +13 -0
- package/dist/tIED/insertIED.js +245 -0
- package/dist/tIED/insertIED.js.map +1 -0
- package/dist/tIED/removeIED.d.ts +14 -0
- package/dist/tIED/removeIED.js +70 -0
- package/dist/tIED/removeIED.js.map +1 -0
- package/dist/tIED/updateIED.d.ts +17 -0
- package/dist/tIED/updateIED.js +185 -0
- package/dist/tIED/updateIED.js.map +1 -0
- package/dist/tInputs/removeInputs.d.ts +7 -0
- package/dist/tInputs/removeInputs.js +25 -0
- package/dist/tInputs/removeInputs.js.map +1 -0
- package/dist/tLN/removeSubscriptionSupervision.d.ts +7 -0
- package/dist/tLN/removeSubscriptionSupervision.js +94 -0
- package/dist/tLN/removeSubscriptionSupervision.js.map +1 -0
- package/dist/tLN/supervision/canInstantiateSubscriptionSupervision.d.ts +13 -0
- package/dist/tLN/supervision/canInstantiateSubscriptionSupervision.js +116 -0
- package/dist/tLN/supervision/canInstantiateSubscriptionSupervision.js.map +1 -0
- package/dist/tLN/supervision/createSupervisionEdit.d.ts +20 -0
- package/dist/tLN/supervision/createSupervisionEdit.js +129 -0
- package/dist/tLN/supervision/createSupervisionEdit.js.map +1 -0
- package/dist/tLN/supervision/findControlBlockOnSrcAttributes.d.ts +10 -0
- package/dist/tLN/supervision/findControlBlockOnSrcAttributes.js +13 -0
- package/dist/tLN/supervision/findControlBlockOnSrcAttributes.js.map +1 -0
- package/dist/tLN/supervision/foundation.d.ts +37 -0
- package/dist/tLN/supervision/foundation.js +43 -0
- package/dist/tLN/supervision/foundation.js.map +1 -0
- package/dist/tLN/supervision/insertSubscriptionSupervisions.d.ts +11 -0
- package/dist/tLN/supervision/insertSubscriptionSupervisions.js +98 -0
- package/dist/tLN/supervision/insertSubscriptionSupervisions.js.map +1 -0
- package/dist/tLN/supervision/instantiateSubscriptionSupervision.d.ts +10 -0
- package/dist/tLN/supervision/instantiateSubscriptionSupervision.js +36 -0
- package/dist/tLN/supervision/instantiateSubscriptionSupervision.js.map +1 -0
- package/dist/tLN/supervision/removeSupervision.d.ts +7 -0
- package/dist/tLN/supervision/removeSupervision.js +39 -0
- package/dist/tLN/supervision/removeSupervision.js.map +1 -0
- package/dist/tReportControl/canAddReportControl.d.ts +11 -0
- package/dist/tReportControl/canAddReportControl.js +24 -0
- package/dist/tReportControl/canAddReportControl.js.map +1 -0
- package/dist/tReportControl/createReportControl.d.ts +68 -0
- package/dist/tReportControl/createReportControl.js +78 -0
- package/dist/tReportControl/createReportControl.js.map +1 -0
- package/dist/tReportControl/numberReportControlInstances.d.ts +5 -0
- package/dist/tReportControl/numberReportControlInstances.js +19 -0
- package/dist/tReportControl/numberReportControlInstances.js.map +1 -0
- package/dist/tReportControl/updateReportControl.d.ts +5 -0
- package/dist/tReportControl/updateReportControl.js +24 -0
- package/dist/tReportControl/updateReportControl.js.map +1 -0
- package/dist/tSMV/changeSMVContent.d.ts +3 -0
- package/dist/tSMV/changeSMVContent.js +5 -0
- package/dist/tSMV/changeSMVContent.js.map +1 -0
- package/dist/tSMV/createSMV.d.ts +16 -0
- package/dist/tSMV/createSMV.js +32 -0
- package/dist/tSMV/createSMV.js.map +1 -0
- package/dist/tSampledValueControl/canAddSampledValueControl.d.ts +4 -0
- package/dist/tSampledValueControl/canAddSampledValueControl.js +27 -0
- package/dist/tSampledValueControl/canAddSampledValueControl.js.map +1 -0
- package/dist/tSampledValueControl/createSampledValueControl.d.ts +66 -0
- package/dist/tSampledValueControl/createSampledValueControl.js +74 -0
- package/dist/tSampledValueControl/createSampledValueControl.js.map +1 -0
- package/dist/tSampledValueControl/updateSampledValueControl.d.ts +14 -0
- package/dist/tSampledValueControl/updateSampledValueControl.js +60 -0
- package/dist/tSampledValueControl/updateSampledValueControl.js.map +1 -0
- package/dist/tServices/tConfReportControl/maxReportControl.d.ts +9 -0
- package/dist/tServices/tConfReportControl/maxReportControl.js +14 -0
- package/dist/tServices/tConfReportControl/maxReportControl.js.map +1 -0
- package/dist/tSubstation/removeProcessElement.d.ts +9 -0
- package/dist/tSubstation/removeProcessElement.js +50 -0
- package/dist/tSubstation/removeProcessElement.js.map +1 -0
- package/dist/tSubstation/updateLnType.d.ts +8 -0
- package/dist/tSubstation/updateLnType.js +96 -0
- package/dist/tSubstation/updateLnType.js.map +1 -0
- package/dist/tSubstation/updateSubstation.d.ts +5 -0
- package/dist/tSubstation/updateSubstation.js +75 -0
- package/dist/tSubstation/updateSubstation.js.map +1 -0
- package/dist/tVoltageLevel/updateVoltageLevel.d.ts +5 -0
- package/dist/tVoltageLevel/updateVoltageLevel.js +83 -0
- package/dist/tVoltageLevel/updateVoltageLevel.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { controlBlockObjRef } from "../tControl/controlBlockObjRef.js";
|
|
2
|
+
import { sourceControlBlock } from "../tExtRef/sourceControlBlock.js";
|
|
3
|
+
import { isSrcRefEditable } from "./supervision/foundation.js";
|
|
4
|
+
/** @returns Element to remove the subscription supervision */
|
|
5
|
+
function removableSupervisionElement(ctrlBlock, subscriberIed) {
|
|
6
|
+
const supervisionType = ctrlBlock.tagName === "GSEControl" ? "LGOS" : "LSVS";
|
|
7
|
+
const doiName = ctrlBlock.tagName === "GSEControl" ? "GoCBRef" : "SvCBRef";
|
|
8
|
+
const valElement = Array.from(subscriberIed.querySelectorAll(`LN[lnClass="${supervisionType}"] > DOI[name="${doiName}"] > DAI[name="setSrcRef"] > Val`)).find((val) => val.textContent === controlBlockObjRef(ctrlBlock));
|
|
9
|
+
if (!valElement)
|
|
10
|
+
return null;
|
|
11
|
+
const ln = valElement.closest("LN");
|
|
12
|
+
// do not remove logical nodes `LGOS`, `LSVS` unless privately tagged
|
|
13
|
+
const canRemoveLn = ln.querySelector(':scope > Private[type="OpenSCD.create"]');
|
|
14
|
+
if (canRemoveLn)
|
|
15
|
+
return ln;
|
|
16
|
+
return (Array.from(valElement.childNodes).find((child) => child.nodeType === Node.TEXT_NODE) ?? null);
|
|
17
|
+
}
|
|
18
|
+
/** @returns Whether `DA` with name `setSrcRef` can edited by SCL editor */
|
|
19
|
+
function isSupervisionEditable(ctrlBlock, subscriberIed) {
|
|
20
|
+
const supervisionElement = removableSupervisionElement(ctrlBlock, subscriberIed);
|
|
21
|
+
if (!supervisionElement)
|
|
22
|
+
return false;
|
|
23
|
+
let supervisionLn = null;
|
|
24
|
+
if (supervisionElement.nodeType === Node.TEXT_NODE) {
|
|
25
|
+
supervisionLn = supervisionElement.parentElement?.closest("LN") ?? null;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
supervisionLn = supervisionElement.closest("LN") ?? null;
|
|
29
|
+
}
|
|
30
|
+
if (!supervisionLn)
|
|
31
|
+
return false;
|
|
32
|
+
return isSrcRefEditable(supervisionLn);
|
|
33
|
+
}
|
|
34
|
+
/** @returns Whether other subscribed ExtRef of the same control block exist */
|
|
35
|
+
function isControlBlockSubscribed(extRefs) {
|
|
36
|
+
const [srcCBName, srcLDInst, srcLNClass, iedName, srcPrefix, srcLNInst, serviceType,] = [
|
|
37
|
+
"srcCBName",
|
|
38
|
+
"srcLDInst",
|
|
39
|
+
"srcLNClass",
|
|
40
|
+
"iedName",
|
|
41
|
+
"srcPrefix",
|
|
42
|
+
"srcLNInst",
|
|
43
|
+
"serviceType",
|
|
44
|
+
].map((attr) => extRefs[0].getAttribute(attr));
|
|
45
|
+
const parentIed = extRefs[0].closest("IED");
|
|
46
|
+
return Array.from(parentIed.getElementsByTagName("ExtRef")).some((otherExtRef) => !extRefs.includes(otherExtRef) &&
|
|
47
|
+
(otherExtRef.getAttribute("srcPrefix") ?? "") === (srcPrefix ?? "") &&
|
|
48
|
+
(otherExtRef.getAttribute("srcLNInst") ?? "") === (srcLNInst ?? "") &&
|
|
49
|
+
otherExtRef.getAttribute("srcCBName") === srcCBName &&
|
|
50
|
+
otherExtRef.getAttribute("srcLDInst") === srcLDInst &&
|
|
51
|
+
otherExtRef.getAttribute("srcLNClass") === srcLNClass &&
|
|
52
|
+
otherExtRef.getAttribute("iedName") === iedName &&
|
|
53
|
+
otherExtRef.getAttribute("serviceType") === serviceType);
|
|
54
|
+
}
|
|
55
|
+
function cannotRemoveSupervision(extRefGroup) {
|
|
56
|
+
return (isControlBlockSubscribed(extRefGroup.extRefs) ||
|
|
57
|
+
!isSupervisionEditable(extRefGroup.ctrlBlock, extRefGroup.subscriberIed));
|
|
58
|
+
}
|
|
59
|
+
function groupPerControlBlock(extRefs) {
|
|
60
|
+
const groupedExtRefs = {};
|
|
61
|
+
extRefs.forEach((extRef) => {
|
|
62
|
+
const ctrlBlock = sourceControlBlock(extRef);
|
|
63
|
+
if (ctrlBlock) {
|
|
64
|
+
const ctrlBlockRef = controlBlockObjRef(ctrlBlock);
|
|
65
|
+
if (groupedExtRefs[ctrlBlockRef])
|
|
66
|
+
groupedExtRefs[ctrlBlockRef].extRefs.push(extRef);
|
|
67
|
+
else
|
|
68
|
+
groupedExtRefs[ctrlBlockRef] = {
|
|
69
|
+
extRefs: [extRef],
|
|
70
|
+
ctrlBlock,
|
|
71
|
+
subscriberIed: extRef.closest("IED"),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return groupedExtRefs;
|
|
76
|
+
}
|
|
77
|
+
/** Removes subscription supervision - `LGOS` or `LSVS` - when no other data
|
|
78
|
+
* of a given `GSEControl` or `SampledValueControl`
|
|
79
|
+
* @param extRefs - An array of external reference elements
|
|
80
|
+
* @returns edits to remove subscription supervision `LGOS` or `LSVS`
|
|
81
|
+
*/
|
|
82
|
+
export function removeSubscriptionSupervision(extRefs) {
|
|
83
|
+
if (extRefs.length === 0)
|
|
84
|
+
return [];
|
|
85
|
+
const groupedExtRefs = groupPerControlBlock(extRefs);
|
|
86
|
+
return Object.values(groupedExtRefs)
|
|
87
|
+
.map((extRefGroup) => {
|
|
88
|
+
if (cannotRemoveSupervision(extRefGroup))
|
|
89
|
+
return null;
|
|
90
|
+
return removableSupervisionElement(extRefGroup.ctrlBlock, extRefGroup.subscriberIed);
|
|
91
|
+
})
|
|
92
|
+
.filter((element) => element).map((node) => ({ node }));
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=removeSubscriptionSupervision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removeSubscriptionSupervision.js","sourceRoot":"","sources":["../../tLN/removeSubscriptionSupervision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Supervision, SupervisionOptions } from "./foundation.js";
|
|
2
|
+
/** Whether subscription supervision instantiation can be performed.
|
|
3
|
+
* ```md
|
|
4
|
+
* - check if `valImport` and `valKind` allow to change subscriber logical node
|
|
5
|
+
* - check whether the control block is already supervised in the IED
|
|
6
|
+
* - check whether there is an available location for the control block
|
|
7
|
+
* reference to be stored in the supervision source reference.
|
|
8
|
+
* - check whether `Service` element requirements are met
|
|
9
|
+
* - check whether the logical node has missing or empty `Val` content
|
|
10
|
+
* (iedOrLn is LN)
|
|
11
|
+
* ```
|
|
12
|
+
* @returns Whether subscription supervision can be done */
|
|
13
|
+
export declare function canInstantiateSubscriptionSupervision(supervision: Supervision, options?: SupervisionOptions): boolean;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { controlBlockObjRef } from "../../tControl/controlBlockObjRef.js";
|
|
2
|
+
import { supervisionLnClass, type, } from "./foundation.js";
|
|
3
|
+
/** @returns Whether a supervision LN holds a valid control block object ref */
|
|
4
|
+
function holdsValidObjRef(ln, type) {
|
|
5
|
+
const objRef = ln.querySelector(`:scope > DOI[name="${type}"] > DAI[name="setSrcRef"] > Val`)?.textContent;
|
|
6
|
+
if (!objRef)
|
|
7
|
+
return false;
|
|
8
|
+
// IEDnameLDinst/prefixLnClassLnInst.CbName
|
|
9
|
+
const indexSlash = objRef.indexOf("/");
|
|
10
|
+
const indexDot = objRef.indexOf(".");
|
|
11
|
+
return (indexSlash !== 0 &&
|
|
12
|
+
indexSlash < indexDot + 1 &&
|
|
13
|
+
indexDot - 1 < objRef.length);
|
|
14
|
+
}
|
|
15
|
+
/** @returns Whether `Services` element requirement is met */
|
|
16
|
+
function withinSupervisionLimits(supervision) {
|
|
17
|
+
const subscriberIed = supervision.subscriberIedOrLn.tagName === "IED"
|
|
18
|
+
? supervision.subscriberIedOrLn
|
|
19
|
+
: supervision.subscriberIedOrLn.closest("IED");
|
|
20
|
+
const lnClass = supervisionLnClass(supervision);
|
|
21
|
+
const max = subscriberIed
|
|
22
|
+
?.querySelector("Services > SupSubscription")
|
|
23
|
+
?.getAttribute(`${lnClass === "LGOS" ? "maxGo" : "maxSv"}`);
|
|
24
|
+
if (!max || isNaN(parseInt(max, 10)))
|
|
25
|
+
return false;
|
|
26
|
+
const existingSupervisionLNs = Array.from(subscriberIed.querySelectorAll(`LN[lnClass="${lnClass}"]`));
|
|
27
|
+
if (existingSupervisionLNs.length < parseInt(max, 10))
|
|
28
|
+
return true;
|
|
29
|
+
const availableSupervisorSpots = existingSupervisionLNs.filter((ln) => !holdsValidObjRef(ln, type(supervision)));
|
|
30
|
+
return (existingSupervisionLNs.length === parseInt(max, 10) &&
|
|
31
|
+
availableSupervisorSpots.length > 0);
|
|
32
|
+
}
|
|
33
|
+
/** @returns Whether `DA`|`DAI` with name `setSrcRef` is editable */
|
|
34
|
+
function isSrcRefEditable(supervision) {
|
|
35
|
+
const lnClass = supervisionLnClass(supervision);
|
|
36
|
+
const ln = supervision.subscriberIedOrLn.tagName === "LN"
|
|
37
|
+
? supervision.subscriberIedOrLn
|
|
38
|
+
: supervision.subscriberIedOrLn.querySelector(`LN[lnClass="${lnClass}"]`);
|
|
39
|
+
const doiName = type(supervision);
|
|
40
|
+
if (ln.querySelector(`:scope > DOI[name="${doiName}"] >
|
|
41
|
+
DAI[name="setSrcRef"][valImport="true"][valKind="RO"],
|
|
42
|
+
:scope > DOI[name="${doiName}"] >
|
|
43
|
+
DAI[name="setSrcRef"][valImport="true"][valKind="Conf"]`))
|
|
44
|
+
return true;
|
|
45
|
+
const rootNode = ln.ownerDocument;
|
|
46
|
+
const lnType = ln.getAttribute("lnType");
|
|
47
|
+
const goOrSvCBRef = rootNode.querySelector(`DataTypeTemplates >
|
|
48
|
+
LNodeType[id="${lnType}"][lnClass="${lnClass}"] > DO[name="${type(supervision)}"]`);
|
|
49
|
+
const cbRefId = goOrSvCBRef?.getAttribute("type");
|
|
50
|
+
const setSrcRef = rootNode.querySelector(`DataTypeTemplates > DOType[id="${cbRefId}"] > DA[name="setSrcRef"]`);
|
|
51
|
+
return ((setSrcRef?.getAttribute("valKind") === "Conf" ||
|
|
52
|
+
setSrcRef?.getAttribute("valKind") === "RO") &&
|
|
53
|
+
setSrcRef.getAttribute("valImport") === "true");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A pre requirement for a subscription supervision is an already existing
|
|
57
|
+
* LN of the class `LGOS` or `LSVS` in the subscriber IED.
|
|
58
|
+
* @returns Whether there is a logical node element `LN` with the class `LGOS`, `LSVS`
|
|
59
|
+
*/
|
|
60
|
+
function existFirstSupervisionOfType(supervision) {
|
|
61
|
+
const lnClass = supervision.sourceControlBlock.tagName === "GSEControl" ? "LGOS" : "LSVS";
|
|
62
|
+
const firstSupervisionOfType = supervision.subscriberIedOrLn.querySelector(`:scope > AccessPoint > Server > LDevice > LN[lnClass="${lnClass}"]`);
|
|
63
|
+
return firstSupervisionOfType ? true : false;
|
|
64
|
+
}
|
|
65
|
+
/** @returns Whether [[`controlBlock`]] is supervised in [[`subscriberIed`]] */
|
|
66
|
+
function isControlBlockSupervised(supervision) {
|
|
67
|
+
const subscriberIed = supervision.subscriberIedOrLn.tagName === "IED"
|
|
68
|
+
? supervision.subscriberIedOrLn
|
|
69
|
+
: supervision.subscriberIedOrLn.closest("IED");
|
|
70
|
+
const lnClass = supervision.sourceControlBlock.tagName === "GSEControl" ? "LGOS" : "LSVS";
|
|
71
|
+
const refType = supervision.sourceControlBlock.tagName === "GSEControl"
|
|
72
|
+
? "GoCBRef"
|
|
73
|
+
: "SvCBRef";
|
|
74
|
+
return Array.from(subscriberIed?.querySelectorAll(`:scope > AccessPoint > Server > LDevice > LN[lnClass="${lnClass}"]
|
|
75
|
+
> DOI[name="${refType}"] > DAI[name="setSrcRef"] > Val`)).some((val) => val.textContent === controlBlockObjRef(supervision.sourceControlBlock));
|
|
76
|
+
}
|
|
77
|
+
/** Whether subscription supervision instantiation can be performed.
|
|
78
|
+
* ```md
|
|
79
|
+
* - check if `valImport` and `valKind` allow to change subscriber logical node
|
|
80
|
+
* - check whether the control block is already supervised in the IED
|
|
81
|
+
* - check whether there is an available location for the control block
|
|
82
|
+
* reference to be stored in the supervision source reference.
|
|
83
|
+
* - check whether `Service` element requirements are met
|
|
84
|
+
* - check whether the logical node has missing or empty `Val` content
|
|
85
|
+
* (iedOrLn is LN)
|
|
86
|
+
* ```
|
|
87
|
+
* @returns Whether subscription supervision can be done */
|
|
88
|
+
export function canInstantiateSubscriptionSupervision(supervision, options = {
|
|
89
|
+
newSupervisionLn: false,
|
|
90
|
+
fixedLnInst: -1,
|
|
91
|
+
checkEditableSrcRef: true,
|
|
92
|
+
checkDuplicateSupervisions: true,
|
|
93
|
+
checkMaxSupervisionLimits: true,
|
|
94
|
+
}) {
|
|
95
|
+
if (options.checkDuplicateSupervisions &&
|
|
96
|
+
isControlBlockSupervised(supervision))
|
|
97
|
+
return false;
|
|
98
|
+
if (supervision.subscriberIedOrLn.tagName === "LN") {
|
|
99
|
+
const type = supervision.sourceControlBlock.tagName === "GSEControl"
|
|
100
|
+
? "GoCBRef"
|
|
101
|
+
: "SvCBRef";
|
|
102
|
+
if (holdsValidObjRef(supervision.subscriberIedOrLn, type))
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
if (!existFirstSupervisionOfType(supervision))
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
if (options.checkMaxSupervisionLimits &&
|
|
110
|
+
!withinSupervisionLimits(supervision))
|
|
111
|
+
return false;
|
|
112
|
+
if (options.checkEditableSrcRef && !isSrcRefEditable(supervision))
|
|
113
|
+
return false;
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=canInstantiateSubscriptionSupervision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canInstantiateSubscriptionSupervision.js","sourceRoot":"","sources":["../../../tLN/supervision/canInstantiateSubscriptionSupervision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Insert } from "@openscd/oscd-api";
|
|
2
|
+
import { Supervision } from "./foundation.js";
|
|
3
|
+
type SupervisionWithDynamicInst = {
|
|
4
|
+
usedSupervisions?: Set<Element>;
|
|
5
|
+
instGenerator: (supervision: Supervision) => string | undefined;
|
|
6
|
+
};
|
|
7
|
+
type SupervisionWithFixedInst = {
|
|
8
|
+
usedSupervisions?: Set<Element>;
|
|
9
|
+
fixedInst: string;
|
|
10
|
+
};
|
|
11
|
+
type NewSupervisionLN = {
|
|
12
|
+
usedSupervisions?: Set<Element>;
|
|
13
|
+
newSupervisionLn: boolean;
|
|
14
|
+
fixedInst?: string;
|
|
15
|
+
instGenerator: (supervision: Supervision) => string | undefined;
|
|
16
|
+
};
|
|
17
|
+
type CreateSupervisionOptions = NewSupervisionLN | SupervisionWithFixedInst | SupervisionWithDynamicInst;
|
|
18
|
+
/** @returns Insert edit on unused supervision logical node or new supervision logical node */
|
|
19
|
+
export declare function createSupervisionEdit(supervision: Supervision, options: CreateSupervisionOptions): Insert | null;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createElement } from "../../foundation/utils.js";
|
|
2
|
+
import { getReference } from "../../tBaseElement/getReference.js";
|
|
3
|
+
import { controlBlockObjRef } from "../../tControl/controlBlockObjRef.js";
|
|
4
|
+
import { supervisionLnClass, type } from "./foundation.js";
|
|
5
|
+
function isFixedInst(options) {
|
|
6
|
+
return "fixedInst" in options;
|
|
7
|
+
}
|
|
8
|
+
function isNewSupervisionLn(options) {
|
|
9
|
+
return "newSupervisionLn" in options;
|
|
10
|
+
}
|
|
11
|
+
function createSupervisionDaiElement(input) {
|
|
12
|
+
const dai = createElement(input.doc, "DAI", { name: "setSrcRef" });
|
|
13
|
+
const val = createElement(input.doc, "Val", {});
|
|
14
|
+
dai.appendChild(val);
|
|
15
|
+
val.textContent = input.controlBlockReference;
|
|
16
|
+
return dai;
|
|
17
|
+
}
|
|
18
|
+
function createSupervisionDoiElement(input) {
|
|
19
|
+
const doi = createElement(input.doc, "DOI", { name: input.cbRefType });
|
|
20
|
+
const dai = createElement(input.doc, "DAI", { name: "setSrcRef" });
|
|
21
|
+
const val = createElement(input.doc, "Val", {});
|
|
22
|
+
doi.appendChild(dai);
|
|
23
|
+
dai.appendChild(val);
|
|
24
|
+
val.textContent = input.controlBlockReference;
|
|
25
|
+
return doi;
|
|
26
|
+
}
|
|
27
|
+
function cdRefType(logicalNode) {
|
|
28
|
+
const lnClass = logicalNode.getAttribute("lnClass");
|
|
29
|
+
const cbRefType = lnClass === "LGOS" ? "GoCBRef" : "SvCBRef";
|
|
30
|
+
return cbRefType;
|
|
31
|
+
}
|
|
32
|
+
function availableSupervisionLn(supervision, usedSupervisions) {
|
|
33
|
+
const lnClass = supervisionLnClass(supervision);
|
|
34
|
+
const cbRefType = type(supervision);
|
|
35
|
+
return (Array.from(supervision.subscriberIedOrLn.querySelectorAll(`:scope > AccessPoint > Server > LDevice > LN[lnClass="${lnClass}"]`))
|
|
36
|
+
// filter already used available logical nodes
|
|
37
|
+
.filter((ln) => !usedSupervisions?.has(ln))
|
|
38
|
+
.find((ln) => {
|
|
39
|
+
return (ln.querySelector(`:scope > DOI[name="${cbRefType}"] > DAI[name="setSrcRef"] > Val`) === null ||
|
|
40
|
+
ln.querySelector(`:scope > DOI[name="${cbRefType}"] > DAI[name="setSrcRef"] > Val`)?.textContent === "");
|
|
41
|
+
}) ?? null);
|
|
42
|
+
}
|
|
43
|
+
function createSupervisionLogicalNode(supervision, controlBlockReference, inst) {
|
|
44
|
+
const subscriberIed = supervision.subscriberIedOrLn;
|
|
45
|
+
const lnClass = supervisionLnClass(supervision);
|
|
46
|
+
const formLn = subscriberIed.querySelector(`LN[lnClass="${lnClass}"]`);
|
|
47
|
+
const parent = formLn.parentElement;
|
|
48
|
+
const lnType = formLn.getAttribute("lnType");
|
|
49
|
+
const prefix = formLn.getAttribute("prefix");
|
|
50
|
+
const ln = createElement(subscriberIed.ownerDocument, "LN", {
|
|
51
|
+
prefix,
|
|
52
|
+
lnClass,
|
|
53
|
+
lnType,
|
|
54
|
+
inst,
|
|
55
|
+
});
|
|
56
|
+
const openScdTag = createElement(subscriberIed.ownerDocument, "Private", {
|
|
57
|
+
type: "OpenSCD.create",
|
|
58
|
+
});
|
|
59
|
+
ln.appendChild(openScdTag);
|
|
60
|
+
const lastSupervisionLn = parent.querySelector(`:scope > LN[lnClass="${lnClass}"]:last-child`);
|
|
61
|
+
const reference = lastSupervisionLn
|
|
62
|
+
? lastSupervisionLn.nextElementSibling
|
|
63
|
+
: getReference(parent, "LN");
|
|
64
|
+
const doc = ln.ownerDocument;
|
|
65
|
+
const cbRefType = cdRefType(ln);
|
|
66
|
+
ln.appendChild(createSupervisionDoiElement({
|
|
67
|
+
doc,
|
|
68
|
+
cbRefType,
|
|
69
|
+
controlBlockReference,
|
|
70
|
+
}));
|
|
71
|
+
return { parent, node: ln, reference };
|
|
72
|
+
}
|
|
73
|
+
function updateSupervisionLogicalNode(controlBlockReference, logicalNode) {
|
|
74
|
+
const doc = logicalNode.ownerDocument;
|
|
75
|
+
const cbRefType = cdRefType(logicalNode);
|
|
76
|
+
const createSupervisionElementInput = {
|
|
77
|
+
doc,
|
|
78
|
+
cbRefType,
|
|
79
|
+
controlBlockReference,
|
|
80
|
+
};
|
|
81
|
+
const doi = logicalNode.querySelector(`:scope > DOI[name="${cbRefType}"]`);
|
|
82
|
+
if (!doi)
|
|
83
|
+
return {
|
|
84
|
+
parent: logicalNode,
|
|
85
|
+
node: createSupervisionDoiElement(createSupervisionElementInput),
|
|
86
|
+
reference: getReference(logicalNode, "DOI"),
|
|
87
|
+
};
|
|
88
|
+
const dai = logicalNode.querySelector(`:scope > DOI[name="${cbRefType}"] > DAI[name="setSrcRef"]`);
|
|
89
|
+
if (!dai)
|
|
90
|
+
return {
|
|
91
|
+
parent: doi,
|
|
92
|
+
node: createSupervisionDaiElement(createSupervisionElementInput),
|
|
93
|
+
reference: getReference(doi, "DAI"),
|
|
94
|
+
};
|
|
95
|
+
const val = logicalNode.querySelector(`:scope > DOI[name="${cbRefType}"] > DAI[name="setSrcRef"] > Val`);
|
|
96
|
+
if (!val) {
|
|
97
|
+
const newVal = createElement(doc, "Val", {});
|
|
98
|
+
dai.appendChild(newVal);
|
|
99
|
+
newVal.textContent = controlBlockReference;
|
|
100
|
+
return { parent: dai, node: newVal, reference: getReference(dai, "Val") };
|
|
101
|
+
}
|
|
102
|
+
const cbRef = document.createTextNode(controlBlockReference);
|
|
103
|
+
return { parent: val, node: cbRef, reference: null };
|
|
104
|
+
}
|
|
105
|
+
/** @returns Insert edit on unused supervision logical node or new supervision logical node */
|
|
106
|
+
export function createSupervisionEdit(supervision, options) {
|
|
107
|
+
const sourceControlBlock = supervision.sourceControlBlock;
|
|
108
|
+
const controlBlockReference = controlBlockObjRef(sourceControlBlock);
|
|
109
|
+
if (!controlBlockReference)
|
|
110
|
+
return null;
|
|
111
|
+
if (supervision.subscriberIedOrLn.tagName === "LN")
|
|
112
|
+
return updateSupervisionLogicalNode(controlBlockReference, supervision.subscriberIedOrLn);
|
|
113
|
+
if (isNewSupervisionLn(options) && options.newSupervisionLn) {
|
|
114
|
+
const inst = options.fixedInst
|
|
115
|
+
? options.fixedInst
|
|
116
|
+
: options.instGenerator(supervision);
|
|
117
|
+
return createSupervisionLogicalNode(supervision, controlBlockReference, inst);
|
|
118
|
+
}
|
|
119
|
+
const unusedSupervisionLogicalNode = availableSupervisionLn(supervision, options?.usedSupervisions);
|
|
120
|
+
if (!unusedSupervisionLogicalNode) {
|
|
121
|
+
const inst = isFixedInst(options)
|
|
122
|
+
? options.fixedInst
|
|
123
|
+
: options.instGenerator(supervision);
|
|
124
|
+
return createSupervisionLogicalNode(supervision, controlBlockReference, inst);
|
|
125
|
+
}
|
|
126
|
+
options.usedSupervisions?.add(unusedSupervisionLogicalNode);
|
|
127
|
+
return updateSupervisionLogicalNode(controlBlockReference, unusedSupervisionLogicalNode);
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=createSupervisionEdit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createSupervisionEdit.js","sourceRoot":"","sources":["../../../tLN/supervision/createSupervisionEdit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ExtRefSource = {
|
|
2
|
+
iedName: string;
|
|
3
|
+
ldInst: string;
|
|
4
|
+
prefix: string;
|
|
5
|
+
lnClass: string;
|
|
6
|
+
lnInst: string;
|
|
7
|
+
cbName: string;
|
|
8
|
+
};
|
|
9
|
+
/** @returns control block or null for a set of ExtRef attributes */
|
|
10
|
+
export declare function findControlBlockBySrcAttributes(doc: XMLDocument, extRefSrc: ExtRefSource): Element | null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** @returns control block or null for a set of ExtRef attributes */
|
|
2
|
+
export function findControlBlockBySrcAttributes(doc, extRefSrc) {
|
|
3
|
+
return (Array.from(doc.querySelectorAll(`:root > IED[name="${extRefSrc.iedName}"] ReportControl,
|
|
4
|
+
:root > IED[name="${extRefSrc.iedName}"] GSEControl,
|
|
5
|
+
:root > IED[name="${extRefSrc.iedName}"] SampledValueControl`)).find((cBlock) => cBlock.closest("LDevice").getAttribute("inst") === extRefSrc.ldInst &&
|
|
6
|
+
(cBlock.closest("LN, LN0").getAttribute("prefix") ?? "") ===
|
|
7
|
+
extRefSrc.prefix &&
|
|
8
|
+
cBlock.closest("LN, LN0").getAttribute("lnClass") ===
|
|
9
|
+
extRefSrc.lnClass &&
|
|
10
|
+
cBlock.closest("LN, LN0").getAttribute("inst") === extRefSrc.lnInst &&
|
|
11
|
+
cBlock.getAttribute("name") === extRefSrc.cbName) ?? null);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=findControlBlockOnSrcAttributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findControlBlockOnSrcAttributes.js","sourceRoot":"","sources":["../../../tLN/supervision/findControlBlockOnSrcAttributes.ts"],"names":[],"mappings":"AASA,oEAAoE;AACpE,MAAM,UAAU,+BAA+B,CAC7C,GAAgB,EAChB,SAAuB;IAEvB,OAAO,CACL,KAAK,CAAC,IAAI,CACR,GAAG,CAAC,gBAAgB,CAClB,qBAAqB,SAAS,CAAC,OAAO;gCACd,SAAS,CAAC,OAAO;gCACjB,SAAS,CAAC,OAAO,wBAAwB,CAClE,CACF,CAAC,IAAI,CACJ,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,OAAO,CAAC,SAAS,CAAE,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,MAAM;QACpE,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACvD,SAAS,CAAC,MAAM;QAClB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAE,CAAC,YAAY,CAAC,SAAS,CAAC;YAChD,SAAS,CAAC,OAAO;QACnB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAE,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,MAAM;QACpE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,MAAM,CACnD,IAAI,IAAI,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type Supervision = {
|
|
2
|
+
/**
|
|
3
|
+
* Reference to the supervision location either as the subscriber IED
|
|
4
|
+
* or the logical node of the class `LGOS`/`LSVS` itself
|
|
5
|
+
*/
|
|
6
|
+
subscriberIedOrLn: Element;
|
|
7
|
+
/** The control block to be supervised */
|
|
8
|
+
sourceControlBlock: Element;
|
|
9
|
+
};
|
|
10
|
+
export type SupervisionOptions = {
|
|
11
|
+
/** Whether supervision instantiation shall be with new logical node instance */
|
|
12
|
+
newSupervisionLn: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* A fixed `inst` attribute for a new logical node (LGOS/LSVS) instance
|
|
15
|
+
* otherwise ignored. The default -1 sets the `inst` attribute automatically.
|
|
16
|
+
*/
|
|
17
|
+
fixedLnInst: number;
|
|
18
|
+
/** Whether to check for `valKind`/`valImport`. Defaulting to true */
|
|
19
|
+
checkEditableSrcRef: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the given control block is already supervised in the subscriber
|
|
22
|
+
* IED. Defaulting to true.
|
|
23
|
+
*/
|
|
24
|
+
checkDuplicateSupervisions: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Whether a new supervision would exceed the limits set in the `Services`
|
|
27
|
+
* section or whether an existing supervision LN control block reference is
|
|
28
|
+
* empty or invalid and can be used. Defaulting to true.
|
|
29
|
+
*/
|
|
30
|
+
checkMaxSupervisionLimits: boolean;
|
|
31
|
+
};
|
|
32
|
+
export declare function type(supervision: Supervision): "GoCBRef" | "SvCBRef";
|
|
33
|
+
export declare function supervisionLnClass(supervision: Supervision): "LGOS" | "LSVS";
|
|
34
|
+
/** @returns Unique attribute `inst` for supervision logical nodes. */
|
|
35
|
+
export declare function globalLnInstGenerator(): (supervision: Supervision) => string | undefined;
|
|
36
|
+
/** @returns Whether child `DA` with name `setSrcRef` can edited by SCL editor */
|
|
37
|
+
export declare function isSrcRefEditable(supervisionLn: Element): boolean;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { lnInstGenerator } from "../../generator/lnInstGenerator.js";
|
|
2
|
+
export function type(supervision) {
|
|
3
|
+
const serviceType = supervision.sourceControlBlock.tagName;
|
|
4
|
+
return serviceType === "GSEControl" ? "GoCBRef" : "SvCBRef";
|
|
5
|
+
}
|
|
6
|
+
export function supervisionLnClass(supervision) {
|
|
7
|
+
const serviceType = supervision.sourceControlBlock.tagName;
|
|
8
|
+
return serviceType === "GSEControl" ? "LGOS" : "LSVS";
|
|
9
|
+
}
|
|
10
|
+
/** @returns Unique attribute `inst` for supervision logical nodes. */
|
|
11
|
+
export function globalLnInstGenerator() {
|
|
12
|
+
const lnInstGenerators = new Map();
|
|
13
|
+
return (supervision) => {
|
|
14
|
+
const ied = supervision.subscriberIedOrLn;
|
|
15
|
+
const lnClass = supervisionLnClass(supervision);
|
|
16
|
+
const formLn = ied.querySelector(`LN[lnClass="${lnClass}"]`);
|
|
17
|
+
const lDevice = formLn.parentElement;
|
|
18
|
+
const iedName = `${ied.getAttribute("name")}`;
|
|
19
|
+
if (!lnInstGenerators.has(iedName))
|
|
20
|
+
lnInstGenerators.set(iedName, lnInstGenerator(lDevice, "LN"));
|
|
21
|
+
return lnInstGenerators.get(iedName)(lnClass);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** @returns Whether child `DA` with name `setSrcRef` can edited by SCL editor */
|
|
25
|
+
export function isSrcRefEditable(supervisionLn) {
|
|
26
|
+
const lnClass = supervisionLn.getAttribute("lnClass");
|
|
27
|
+
const cbRefType = lnClass === "LGOS" ? "GoCBRef" : "SvCBRef";
|
|
28
|
+
if (supervisionLn.querySelector(`:scope > DOI[name="${cbRefType}"] >
|
|
29
|
+
DAI[name="setSrcRef"][valImport="true"][valKind="RO"],
|
|
30
|
+
:scope > DOI[name="${cbRefType}"] >
|
|
31
|
+
DAI[name="setSrcRef"][valImport="true"][valKind="Conf"]`))
|
|
32
|
+
return true;
|
|
33
|
+
const rootNode = supervisionLn.ownerDocument;
|
|
34
|
+
const lnType = supervisionLn.getAttribute("lnType");
|
|
35
|
+
const goOrSvCBRef = rootNode.querySelector(`DataTypeTemplates >
|
|
36
|
+
LNodeType[id="${lnType}"][lnClass="${lnClass}"] > DO[name="${cbRefType}"]`);
|
|
37
|
+
const cbRefId = goOrSvCBRef?.getAttribute("type");
|
|
38
|
+
const setSrcRef = rootNode.querySelector(`DataTypeTemplates > DOType[id="${cbRefId}"] > DA[name="setSrcRef"]`);
|
|
39
|
+
return ((setSrcRef?.getAttribute("valKind") === "Conf" ||
|
|
40
|
+
setSrcRef?.getAttribute("valKind") === "RO") &&
|
|
41
|
+
setSrcRef.getAttribute("valImport") === "true");
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=foundation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundation.js","sourceRoot":"","sources":["../../../tLN/supervision/foundation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAmCrE,MAAM,UAAU,IAAI,CAAC,WAAwB;IAC3C,MAAM,WAAW,GAAG,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC;IAC3D,OAAO,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,WAAwB;IACzD,MAAM,WAAW,GAAG,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC;IAC3D,OAAO,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AACxD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,qBAAqB;IAGnC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAG7B,CAAC;IAEJ,OAAO,CAAC,WAAW,EAAE,EAAE;QACrB,MAAM,GAAG,GAAG,WAAW,CAAC,iBAAiB,CAAC;QAC1C,MAAM,OAAO,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,eAAe,OAAO,IAAI,CAAE,CAAC;QAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,aAAc,CAAC;QAEtC,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC;YAChC,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAEhE,OAAO,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,gBAAgB,CAAC,aAAsB;IACrD,MAAM,OAAO,GAAG,aAAa,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAE7D,IACE,aAAa,CAAC,aAAa,CACzB,sBAAsB,SAAS;;4BAET,SAAS;gEAC2B,CAC3D;QAED,OAAO,IAAI,CAAC;IAEd,MAAM,QAAQ,GAAG,aAAa,CAAC,aAAa,CAAC;IAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEpD,MAAM,WAAW,GAAG,QAAQ,CAAC,aAAa,CACxC;wBACoB,MAAM,eAAe,OAAO,iBAAiB,SAAS,IAAI,CAC/E,CAAC;IAEF,MAAM,OAAO,GAAG,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CACtC,kCAAkC,OAAO,2BAA2B,CACrE,CAAC;IAEF,OAAO,CACL,CAAC,SAAS,EAAE,YAAY,CAAC,SAAS,CAAC,KAAK,MAAM;QAC5C,SAAS,EAAE,YAAY,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;QAC9C,SAAS,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,MAAM,CAC/C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Insert, SetAttributes } from "@openscd/oscd-api";
|
|
2
|
+
/**
|
|
3
|
+
* Insert supervisions triggered by an array of subscribe edits. Subscribe edits
|
|
4
|
+
* are:
|
|
5
|
+
* 1. SetAttributes edit with element key being `ExtRef` element
|
|
6
|
+
* 2. Insert edit with node key being `ExtRef` element
|
|
7
|
+
* All other edits are not taking into consideration
|
|
8
|
+
* @param edits - Subscribe edit array
|
|
9
|
+
* @returns Edit array adding supervision on top of the subscription
|
|
10
|
+
*/
|
|
11
|
+
export declare function insertSubscriptionSupervisions(edits: (SetAttributes | Insert)[]): Insert[];
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { isInsert, isSetAttributes } from "@openscd/oscd-api/utils.js";
|
|
2
|
+
import { findControlBlockBySrcAttributes, } from "./findControlBlockOnSrcAttributes.js";
|
|
3
|
+
import { controlBlockObjRef } from "../../tControl/controlBlockObjRef.js";
|
|
4
|
+
import { globalLnInstGenerator } from "./foundation.js";
|
|
5
|
+
import { canInstantiateSubscriptionSupervision } from "./canInstantiateSubscriptionSupervision.js";
|
|
6
|
+
import { createSupervisionEdit } from "./createSupervisionEdit.js";
|
|
7
|
+
/** In case a new ExtRef is added to inputs-less LN/LN0
|
|
8
|
+
* ExtRef does not have parent IED yet.
|
|
9
|
+
* @returns A sink IED for a given ExtRef insert or `null`*/
|
|
10
|
+
function findIED(edit, previousEdits) {
|
|
11
|
+
// case 1: Input is already in the SCL and ExtRef is added to it
|
|
12
|
+
const inputs = edit.parent;
|
|
13
|
+
const inputsParent = inputs.parentElement;
|
|
14
|
+
if (inputsParent)
|
|
15
|
+
return inputs.closest("IED");
|
|
16
|
+
// case 2: Input element is added as part of the subscription as well.
|
|
17
|
+
const inputsInsertEdit = previousEdits.find((otherEdit) => isInsert(otherEdit) && otherEdit.node === edit.parent);
|
|
18
|
+
if (inputsInsertEdit)
|
|
19
|
+
return inputsInsertEdit.parent.closest("IED");
|
|
20
|
+
// fallback for invalid files
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function uniqueSupervisions(edits) {
|
|
24
|
+
const uniqueSupervisions = {};
|
|
25
|
+
edits.forEach((edit) => {
|
|
26
|
+
let sink = null;
|
|
27
|
+
let source;
|
|
28
|
+
let sinkIED = null;
|
|
29
|
+
const isExtRefUpdate = isSetAttributes(edit) && edit.element.tagName === "ExtRef";
|
|
30
|
+
const newExtRefInsert = isInsert(edit) && edit.node.tagName === "ExtRef";
|
|
31
|
+
if (isExtRefUpdate) {
|
|
32
|
+
source = {
|
|
33
|
+
iedName: edit.attributes?.["iedName"] ?? "",
|
|
34
|
+
ldInst: edit.attributes?.["srcLDInst"] ?? "",
|
|
35
|
+
prefix: edit.attributes?.["srcPrefix"] ?? "",
|
|
36
|
+
lnClass: edit.attributes?.["srcLNClass"] ?? "",
|
|
37
|
+
lnInst: edit.attributes?.["srcLNInst"] ?? "",
|
|
38
|
+
cbName: edit.attributes?.["srcCBName"] ?? "",
|
|
39
|
+
};
|
|
40
|
+
sink = edit.element;
|
|
41
|
+
sinkIED = sink.closest("IED");
|
|
42
|
+
}
|
|
43
|
+
else if (newExtRefInsert) {
|
|
44
|
+
const extRef = edit.node;
|
|
45
|
+
source = {
|
|
46
|
+
iedName: extRef.getAttribute("iedName") ?? "",
|
|
47
|
+
ldInst: extRef.getAttribute("srcLDInst") ?? "",
|
|
48
|
+
prefix: extRef.getAttribute("srcPrefix") ?? "",
|
|
49
|
+
lnClass: extRef.getAttribute("srcLNClass") ?? "",
|
|
50
|
+
lnInst: extRef.getAttribute("srcLNInst") ?? "",
|
|
51
|
+
cbName: extRef.getAttribute("srcCBName") ?? "",
|
|
52
|
+
};
|
|
53
|
+
sink = edit.parent;
|
|
54
|
+
sinkIED = findIED(edit, edits);
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
return;
|
|
58
|
+
const controlBlock = findControlBlockBySrcAttributes(sink.ownerDocument, source);
|
|
59
|
+
if (!controlBlock)
|
|
60
|
+
return;
|
|
61
|
+
const controlBlockReference = controlBlockObjRef(controlBlock);
|
|
62
|
+
if (!sinkIED)
|
|
63
|
+
return;
|
|
64
|
+
const iedName = sinkIED.getAttribute("name");
|
|
65
|
+
const id = `${controlBlockReference}-${iedName}`;
|
|
66
|
+
if (!uniqueSupervisions[id])
|
|
67
|
+
uniqueSupervisions[id] = {
|
|
68
|
+
sourceControlBlock: controlBlock,
|
|
69
|
+
subscriberIedOrLn: sinkIED,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
return uniqueSupervisions;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Insert supervisions triggered by an array of subscribe edits. Subscribe edits
|
|
76
|
+
* are:
|
|
77
|
+
* 1. SetAttributes edit with element key being `ExtRef` element
|
|
78
|
+
* 2. Insert edit with node key being `ExtRef` element
|
|
79
|
+
* All other edits are not taking into consideration
|
|
80
|
+
* @param edits - Subscribe edit array
|
|
81
|
+
* @returns Edit array adding supervision on top of the subscription
|
|
82
|
+
*/
|
|
83
|
+
export function insertSubscriptionSupervisions(edits) {
|
|
84
|
+
/** Global as multiple subscription could be defined for different subscriber IEDs */
|
|
85
|
+
const instGenerator = globalLnInstGenerator();
|
|
86
|
+
const usedSupervisions = new Set();
|
|
87
|
+
return Object.values(uniqueSupervisions(edits))
|
|
88
|
+
.map((supervision) => {
|
|
89
|
+
if (!canInstantiateSubscriptionSupervision(supervision))
|
|
90
|
+
return null;
|
|
91
|
+
return createSupervisionEdit(supervision, {
|
|
92
|
+
usedSupervisions,
|
|
93
|
+
instGenerator,
|
|
94
|
+
});
|
|
95
|
+
})
|
|
96
|
+
.filter((action) => action);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=insertSubscriptionSupervisions.js.map
|