@omicronenergy/oscd-scl-dialogs 0.0.13 → 0.0.15
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/CHANGELOG.md +14 -0
- package/custom-elements.json +23 -0
- package/dist/wizards/address.js +1 -1
- package/dist/wizards/address.js.map +1 -1
- package/dist/wizards/connectedap.js +6 -3
- package/dist/wizards/connectedap.js.map +1 -1
- package/dist/wizards/connectedap.spec.d.ts +1 -0
- package/dist/wizards/connectedap.spec.js +132 -0
- package/dist/wizards/connectedap.spec.js.map +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.0.15](https://github.com/OMICRONEnergyOSS/oscd-scl-dialogs/compare/oscd-scl-dialogs-v0.0.14...oscd-scl-dialogs-v0.0.15) (2026-04-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* edits to the connectedAP should affect the correct address ([e9318e5](https://github.com/OMICRONEnergyOSS/oscd-scl-dialogs/commit/e9318e5464508d7e5c29e3f1c0c5764451c46228))
|
|
9
|
+
|
|
10
|
+
## [0.0.14](https://github.com/OMICRONEnergyOSS/oscd-scl-dialogs/compare/oscd-scl-dialogs-v0.0.13...oscd-scl-dialogs-v0.0.14) (2026-04-20)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* connectedap adding illegal attribute to Address ([92ad0d7](https://github.com/OMICRONEnergyOSS/oscd-scl-dialogs/commit/92ad0d7319012ded4603cdaacbafa886ff90d4fb))
|
|
16
|
+
|
|
3
17
|
## [0.0.13](https://github.com/OMICRONEnergyOSS/oscd-scl-dialogs/compare/oscd-scl-dialogs-v0.0.12...oscd-scl-dialogs-v0.0.13) (2026-03-30)
|
|
4
18
|
|
|
5
19
|
|
package/custom-elements.json
CHANGED
|
@@ -2048,6 +2048,29 @@
|
|
|
2048
2048
|
}
|
|
2049
2049
|
]
|
|
2050
2050
|
},
|
|
2051
|
+
{
|
|
2052
|
+
"kind": "javascript-module",
|
|
2053
|
+
"path": "wizards/connectedap.spec.ts",
|
|
2054
|
+
"declarations": [],
|
|
2055
|
+
"exports": [
|
|
2056
|
+
{
|
|
2057
|
+
"kind": "custom-element-definition",
|
|
2058
|
+
"name": "scl-text-field",
|
|
2059
|
+
"declaration": {
|
|
2060
|
+
"name": "SclTextField",
|
|
2061
|
+
"package": "@openenergytools/scl-text-field"
|
|
2062
|
+
}
|
|
2063
|
+
},
|
|
2064
|
+
{
|
|
2065
|
+
"kind": "custom-element-definition",
|
|
2066
|
+
"name": "scl-checkbox",
|
|
2067
|
+
"declaration": {
|
|
2068
|
+
"name": "SclCheckbox",
|
|
2069
|
+
"package": "@openenergytools/scl-checkbox"
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
]
|
|
2073
|
+
},
|
|
2051
2074
|
{
|
|
2052
2075
|
"kind": "javascript-module",
|
|
2053
2076
|
"path": "wizards/connectedap.ts",
|
package/dist/wizards/address.js
CHANGED
|
@@ -32,7 +32,7 @@ export function createAddressElement(parent, inputs, instType) {
|
|
|
32
32
|
export function updateAddress(parent, inputs, instType) {
|
|
33
33
|
const actions = [];
|
|
34
34
|
const newAddress = createAddressElement(parent, inputs, instType);
|
|
35
|
-
const oldAddress = parent.querySelector('Address');
|
|
35
|
+
const oldAddress = parent.querySelector(':scope > Address');
|
|
36
36
|
if (oldAddress !== null && existDiff(oldAddress, newAddress)) {
|
|
37
37
|
actions.push({
|
|
38
38
|
node: oldAddress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../wizards/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAIzD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAO/D,SAAS,WAAW,CAAC,MAAe,EAAE,IAAmB;IACvD,OAAO,CACL,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAC9D,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,CACrC,IAAI,IAAI,CACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAgB,EAAE,OAAgB;IAC1D,IACE,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM;QACpC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,EACpC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CACnD,KAAK,CAAC,EAAE,CACN,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW;QAC7D,KAAK,CAAC,WAAW,CACpB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAe,EACf,MAAqC,EACrC,QAAiB;IAEjB,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IAEnE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;SAEnB,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC;SACtC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACxB,MAAM,IAAI,GAAG,GAAG,CAAC;QACjB,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,CAAC,cAAc,CAClB,2CAA2C,EAC3C,UAAU,EACV,MAAM,GAAG,EAAE,CACZ,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;QAC1B,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAAe,EACf,MAAqC,EACrC,QAAiB;IAEjB,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,UAAU,GAAG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClE,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../wizards/address.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { EditV2 } from '@openscd/oscd-api';\n\nimport { getReference } from '@openscd/scl-lib';\n\nimport { typePattern } from './patterns.js';\n\nimport { createElement, typeNullable } from '../foundation.js';\n\ninterface AddressContentOptions {\n element: Element;\n types: string[];\n}\n\nfunction getPElement(parent: Element, type: string | null): Element | null {\n return (\n Array.from(parent.querySelectorAll(':scope > Address > P')).find(\n p => p.getAttribute('type') === type,\n ) ?? null\n );\n}\n\nexport function existDiff(oldAddr: Element, newAddr: Element): boolean {\n if (\n oldAddr.querySelectorAll('P').length !==\n newAddr.querySelectorAll('P').length\n ) {\n return true;\n }\n return Array.from(oldAddr.querySelectorAll('P')).some(\n pType =>\n getPElement(newAddr, pType.getAttribute('type'))?.textContent !==\n pType.textContent,\n );\n}\n\nexport function createAddressElement(\n parent: Element,\n inputs: Record<string, string | null>,\n instType: boolean,\n): Element {\n const address = createElement(parent.ownerDocument, 'Address', {});\n\n Object.entries(inputs)\n\n .filter(([_, value]) => value !== null)\n .forEach(([key, value]) => {\n const type = key;\n const child = createElement(parent.ownerDocument, 'P', { type });\n if (instType) {\n child.setAttributeNS(\n 'http://www.w3.org/2001/XMLSchema-instance',\n 'xsi:type',\n `tP_${key}`,\n );\n }\n child.textContent = value;\n address.appendChild(child);\n });\n\n return address;\n}\n\nexport function updateAddress(\n parent: Element,\n inputs: Record<string, string | null>,\n instType: boolean,\n): EditV2[] {\n const actions: EditV2[] = [];\n\n const newAddress = createAddressElement(parent, inputs, instType);\n const oldAddress = parent.querySelector(':scope > Address');\n\n if (oldAddress !== null && existDiff(oldAddress, newAddress)) {\n actions.push({\n node: oldAddress,\n });\n actions.push({\n parent,\n node: newAddress,\n reference: oldAddress.nextSibling,\n });\n } else if (oldAddress === null) {\n actions.push({\n parent,\n node: newAddress,\n reference: getReference(parent, 'Address'),\n });\n }\n\n return actions;\n}\n\nexport function hasTypeRestriction(element: Element): boolean {\n return Array.from(element.querySelectorAll('Address > P')).some(pType =>\n pType.getAttribute('xsi:type'),\n );\n}\n\nexport function contentAddress(\n content: AddressContentOptions,\n): TemplateResult[] {\n const pChildren: Record<string, string | null> = {};\n\n content.types.forEach(type => {\n if (!pChildren[type]) {\n pChildren[type] =\n getPElement(content.element, type)?.textContent?.trim() ?? null;\n }\n });\n\n return [\n html`<scl-checkbox\n label=\"Add XMLSchema-instance type\"\n id=\"instType\"\n .value=\"${hasTypeRestriction(content.element) ? 'true' : 'false'}\"\n ></scl-checkbox>`,\n html`${Object.entries(pChildren).map(\n ([key, value]) =>\n html`<scl-text-field\n label=\"${key}\"\n ?nullable=${typeNullable[key]}\n .value=${value}\n pattern=\"${ifDefined(typePattern[key])}\"\n required\n ></scl-text-field>`,\n )}`,\n ];\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
|
+
import { SclCheckbox } from '@openenergytools/scl-checkbox';
|
|
2
3
|
import { appIdGenerator, getReference, identity, macAddressGenerator, } from '@openscd/scl-lib';
|
|
3
4
|
import { compareNames, createElement, getTypes, getValue, } from '../foundation.js';
|
|
4
5
|
import { contentAddress, updateAddress } from './address.js';
|
|
@@ -284,9 +285,11 @@ function updateAction(element) {
|
|
|
284
285
|
const instType = wizard.querySelector('#instType').value === 'true';
|
|
285
286
|
const addressContent = {};
|
|
286
287
|
inputs.forEach(input => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
if (!(input instanceof SclCheckbox)) {
|
|
289
|
+
const key = input.label;
|
|
290
|
+
const value = getValue(input);
|
|
291
|
+
addressContent[key] = value;
|
|
292
|
+
}
|
|
290
293
|
});
|
|
291
294
|
return updateAddress(element, addressContent, instType);
|
|
292
295
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectedap.js","sourceRoot":"","sources":["../../wizards/connectedap.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit';\n\nimport { EditV2 } from '@openscd/oscd-api';\n\nimport {\n SelectionList,\n SelectItem,\n} from '@openenergytools/filterable-lists/dist/SelectionList.js';\nimport { SclCheckbox } from '@openenergytools/scl-checkbox';\n\nimport {\n appIdGenerator,\n getReference,\n identity,\n macAddressGenerator,\n} from '@openscd/scl-lib';\n\nimport {\n compareNames,\n createElement,\n getTypes,\n getValue,\n Wizard,\n WizardActor,\n WizardInputElement,\n} from '../foundation.js';\n\nimport { contentAddress, updateAddress } from './address.js';\n\ninterface AccessPointDescription {\n element: Element;\n connected?: boolean;\n}\n\nfunction initSMVElements(\n doc: XMLDocument,\n connectedAp: Element,\n options: {\n macGeneratorSmv: () => string | null;\n appidGeneratorSmv: () => string | null;\n unconnectedSampledValueControl: Set<string>;\n },\n): EditV2[] {\n const actions: EditV2[] = [];\n\n const ied = doc.querySelector(\n `IED[name=\"${connectedAp.getAttribute('iedName')}\"]`,\n );\n\n Array.from(ied?.querySelectorAll('SampledValueControl') ?? [])\n .filter(sampledValueControl => {\n const id = identity(sampledValueControl) as string;\n\n if (options.unconnectedSampledValueControl.has(id)) {\n options.unconnectedSampledValueControl.delete(id);\n return true;\n }\n\n return false;\n })\n .forEach(sampledValueControl => {\n const cbName = sampledValueControl.getAttribute('name');\n const ldInst =\n sampledValueControl.closest('LDevice')?.getAttribute('inst') ?? null;\n\n const sMV = createElement(connectedAp.ownerDocument, 'SMV', {\n cbName,\n ldInst,\n });\n actions.push({\n parent: connectedAp,\n node: sMV,\n reference: getReference(connectedAp, 'SMV'),\n });\n\n const address = createElement(connectedAp.ownerDocument, 'Address', {});\n actions.push({\n parent: sMV,\n node: address,\n reference: getReference(sMV, 'Address'),\n });\n\n const pMac = createElement(connectedAp.ownerDocument, 'P', {\n type: 'MAC-Address',\n });\n pMac.textContent = options.macGeneratorSmv();\n actions.push({\n parent: address,\n node: pMac,\n reference: getReference(address, 'P'),\n });\n\n const pAppId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'APPID',\n });\n pAppId.textContent = options.appidGeneratorSmv();\n actions.push({\n parent: address,\n node: pAppId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-ID',\n });\n pVlanId.textContent = '000';\n actions.push({\n parent: address,\n node: pVlanId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanPrio = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-PRIORITY',\n });\n pVlanPrio.textContent = '4';\n actions.push({\n parent: address,\n node: pVlanPrio,\n reference: getReference(address, 'P'),\n });\n });\n\n return actions;\n}\n\nfunction initGSeElements(\n doc: XMLDocument,\n connectedAp: Element,\n options: {\n macGeneratorGse: () => string | null;\n appidGeneratorGse: () => string | null;\n unconnectedGseControl: Set<string>;\n },\n): EditV2[] {\n const actions: EditV2[] = [];\n\n const ied = doc.querySelector(\n `IED[name=\"${connectedAp.getAttribute('iedName')}\"]`,\n );\n\n Array.from(ied?.querySelectorAll('GSEControl') ?? [])\n .filter(gseControl => {\n const id = identity(gseControl) as string;\n\n if (options.unconnectedGseControl.has(id)) {\n options.unconnectedGseControl.delete(id);\n return true;\n }\n\n return false;\n })\n .forEach(gseControl => {\n const cbName = gseControl.getAttribute('name');\n const ldInst =\n gseControl.closest('LDevice')?.getAttribute('inst') ?? null;\n\n const gSE = createElement(connectedAp.ownerDocument, 'GSE', {\n cbName,\n ldInst,\n });\n actions.push({\n parent: connectedAp,\n node: gSE,\n reference: getReference(connectedAp, 'GSE'),\n });\n\n const address = createElement(connectedAp.ownerDocument, 'Address', {});\n actions.push({\n parent: gSE,\n node: address,\n reference: getReference(gSE, 'Address'),\n });\n\n const pMac = createElement(connectedAp.ownerDocument, 'P', {\n type: 'MAC-Address',\n });\n pMac.textContent = options.macGeneratorGse();\n actions.push({\n parent: address,\n node: pMac,\n reference: getReference(address, 'P'),\n });\n\n const pAppId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'APPID',\n });\n pAppId.textContent = options.appidGeneratorGse();\n actions.push({\n parent: address,\n node: pAppId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-ID',\n });\n pVlanId.textContent = '000';\n actions.push({\n parent: address,\n node: pVlanId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanPrio = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-PRIORITY',\n });\n pVlanPrio.textContent = '4';\n actions.push({\n parent: address,\n node: pVlanPrio,\n reference: getReference(address, 'P'),\n });\n\n const minTime = createElement(connectedAp.ownerDocument, 'MinTime', {\n unit: 's',\n multiplier: 'm',\n });\n minTime.textContent = '10';\n actions.push({\n parent: gSE,\n node: minTime,\n reference: getReference(gSE, 'MinTime'),\n });\n\n const maxTime = createElement(connectedAp.ownerDocument, 'MaxTime', {\n unit: 's',\n multiplier: 'm',\n });\n maxTime.textContent = '10000';\n actions.push({\n parent: gSE,\n node: maxTime,\n reference: getReference(gSE, 'MaxTime'),\n });\n });\n\n return actions;\n}\n\nfunction unconnectedGseControls(doc: XMLDocument): Set<string> {\n const allGseControl = Array.from(doc.querySelectorAll('GSEControl'));\n\n const unconnectedGseControl = allGseControl\n .filter(gseControl => {\n const iedName = gseControl.closest('IED')?.getAttribute('name');\n const ldInst = gseControl.closest('LDevice')?.getAttribute('inst');\n const cbName = gseControl.getAttribute('name');\n\n return !doc.querySelector(\n `ConnectedAP[iedName=\"${iedName}\"] ` +\n `> GSE[ldInst=\"${ldInst}\"][cbName=\"${cbName}\"]`,\n );\n })\n .map(gseControl => identity(gseControl) as string);\n\n const mySet = new Set(unconnectedGseControl);\n return mySet;\n}\n\nfunction unconnectedSampledValueControls(doc: XMLDocument): Set<string> {\n const allSmvControl = Array.from(doc.querySelectorAll('SampledValueControl'));\n\n const unconnectedSmvControl = allSmvControl\n .filter(gseControl => {\n const iedName = gseControl.closest('IED')?.getAttribute('name');\n const ldInst = gseControl.closest('LDevice')?.getAttribute('inst');\n const cbName = gseControl.getAttribute('name');\n\n return !doc.querySelector(\n `ConnectedAP[iedName=\"${iedName}\"] ` +\n `> SMV[ldInst=\"${ldInst}\"][cbName=\"${cbName}\"]`,\n );\n })\n .map(gseControl => identity(gseControl) as string);\n\n const mySet = new Set(unconnectedSmvControl);\n return mySet;\n}\n\nfunction createConnectedApAction(parent: Element): WizardActor {\n return (_: WizardInputElement[], wizard: Element): EditV2[] => {\n const doc = parent.ownerDocument;\n\n // generators ensure unique MAC-Address and APPID across the project\n const macGeneratorSmv = macAddressGenerator(doc, 'SMV');\n const appidGeneratorSmv = appIdGenerator(doc, 'SMV');\n const macGeneratorGse = macAddressGenerator(doc, 'GSE');\n const appidGeneratorGse = appIdGenerator(doc, 'GSE');\n\n // track GSE and SMV for multiselect access points connection\n const unconnectedGseControl = unconnectedGseControls(doc);\n const unconnectedSampledValueControl = unconnectedSampledValueControls(doc);\n\n const list = wizard.querySelector('#apList') as SelectionList;\n if (!list) {\n return [];\n }\n\n const actions = list.selectedElements.map(accP => {\n const id = `${identity(accP)}`;\n const [iedName, apName] = id.split('>');\n const connAPactions: EditV2[] = [];\n\n const connectedAp = createElement(parent.ownerDocument, 'ConnectedAP', {\n iedName,\n apName,\n });\n connAPactions.push({\n parent,\n node: connectedAp,\n reference: getReference(parent, 'ConnectedAP'),\n });\n connAPactions.push(\n ...initSMVElements(doc, connectedAp, {\n macGeneratorSmv,\n appidGeneratorSmv,\n unconnectedSampledValueControl,\n }),\n );\n connAPactions.push(\n ...initGSeElements(doc, connectedAp, {\n macGeneratorGse,\n appidGeneratorGse,\n unconnectedGseControl,\n }),\n );\n\n return connAPactions;\n });\n\n return actions;\n };\n}\n\n/** Sorts connected `AccessPoint`s to the bottom. */\nfunction compareAccessPointConnection(\n a: AccessPointDescription,\n b: AccessPointDescription,\n): number {\n if (a.connected !== b.connected) {\n return b.connected ? -1 : 1;\n }\n return 0;\n}\n\nfunction existConnectedAp(accessPoint: Element): boolean {\n const iedName = accessPoint.closest('IED')?.getAttribute('name');\n const apName = accessPoint.getAttribute('name');\n\n const connAp = accessPoint.ownerDocument.querySelector(\n `ConnectedAP[iedName=\"${iedName}\"][apName=\"${apName}\"]`,\n );\n\n return !!connAp;\n}\n\n/** @returns single page [[`Wizard`]] for creating SCL element ConnectedAP. */\nexport function createConnectedApWizard(element: Element): Wizard {\n const doc = element.ownerDocument;\n\n const accessPoints = Array.from(doc.querySelectorAll(':root > IED'))\n .sort(compareNames)\n .flatMap(ied =>\n Array.from(ied.querySelectorAll(':root > IED > AccessPoint')),\n )\n .map(accesspoint => ({\n element: accesspoint,\n connected: existConnectedAp(accesspoint),\n }))\n .sort(compareAccessPointConnection);\n\n const items: SelectItem[] = accessPoints.map(appP => ({\n headline: `${identity(appP.element)}`,\n supportingText: appP.connected ? 'AccessPoint already connected!' : '',\n selected: !appP.connected,\n disabled: appP.connected,\n attachedElement: appP.element,\n }));\n\n return {\n title: 'Add ConnectedAP',\n primary: {\n icon: 'save',\n label: 'save',\n action: createConnectedApAction(element),\n },\n content: [\n html`<selection-list\n id=\"apList\"\n multi\n .items=${items}\n filterable\n ></selection-list>`,\n ],\n };\n}\n\nfunction updateAction(element: Element): WizardActor {\n return (inputs: WizardInputElement[], wizard: Element): EditV2[] => {\n const instType: boolean =\n (wizard.querySelector('#instType') as SclCheckbox).value === 'true';\n\n const addressContent: Record<string, string | null> = {};\n inputs.forEach(input => {\n const key = input.label;\n const value = getValue(input);\n addressContent[key] = value;\n });\n\n return updateAddress(element, addressContent, instType);\n };\n}\n\n/** @returns single page [[`Wizard`]] to edit SCL element ConnectedAP. */\nexport function editConnectedApWizard(element: Element): Wizard {\n return {\n title: 'Edit ConnectedAP',\n primary: {\n icon: 'save',\n label: 'save',\n action: updateAction(element),\n },\n content: [...contentAddress({ element, types: getTypes(element) })],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"connectedap.js","sourceRoot":"","sources":["../../wizards/connectedap.ts"],"names":[],"mappings":"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","sourcesContent":["import { html } from 'lit';\n\nimport { EditV2 } from '@openscd/oscd-api';\n\nimport {\n SelectionList,\n SelectItem,\n} from '@openenergytools/filterable-lists/dist/SelectionList.js';\nimport { SclCheckbox } from '@openenergytools/scl-checkbox';\n\nimport {\n appIdGenerator,\n getReference,\n identity,\n macAddressGenerator,\n} from '@openscd/scl-lib';\n\nimport {\n compareNames,\n createElement,\n getTypes,\n getValue,\n Wizard,\n WizardActor,\n WizardInputElement,\n} from '../foundation.js';\n\nimport { contentAddress, updateAddress } from './address.js';\n\ninterface AccessPointDescription {\n element: Element;\n connected?: boolean;\n}\n\nfunction initSMVElements(\n doc: XMLDocument,\n connectedAp: Element,\n options: {\n macGeneratorSmv: () => string | null;\n appidGeneratorSmv: () => string | null;\n unconnectedSampledValueControl: Set<string>;\n },\n): EditV2[] {\n const actions: EditV2[] = [];\n\n const ied = doc.querySelector(\n `IED[name=\"${connectedAp.getAttribute('iedName')}\"]`,\n );\n\n Array.from(ied?.querySelectorAll('SampledValueControl') ?? [])\n .filter(sampledValueControl => {\n const id = identity(sampledValueControl) as string;\n\n if (options.unconnectedSampledValueControl.has(id)) {\n options.unconnectedSampledValueControl.delete(id);\n return true;\n }\n\n return false;\n })\n .forEach(sampledValueControl => {\n const cbName = sampledValueControl.getAttribute('name');\n const ldInst =\n sampledValueControl.closest('LDevice')?.getAttribute('inst') ?? null;\n\n const sMV = createElement(connectedAp.ownerDocument, 'SMV', {\n cbName,\n ldInst,\n });\n actions.push({\n parent: connectedAp,\n node: sMV,\n reference: getReference(connectedAp, 'SMV'),\n });\n\n const address = createElement(connectedAp.ownerDocument, 'Address', {});\n actions.push({\n parent: sMV,\n node: address,\n reference: getReference(sMV, 'Address'),\n });\n\n const pMac = createElement(connectedAp.ownerDocument, 'P', {\n type: 'MAC-Address',\n });\n pMac.textContent = options.macGeneratorSmv();\n actions.push({\n parent: address,\n node: pMac,\n reference: getReference(address, 'P'),\n });\n\n const pAppId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'APPID',\n });\n pAppId.textContent = options.appidGeneratorSmv();\n actions.push({\n parent: address,\n node: pAppId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-ID',\n });\n pVlanId.textContent = '000';\n actions.push({\n parent: address,\n node: pVlanId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanPrio = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-PRIORITY',\n });\n pVlanPrio.textContent = '4';\n actions.push({\n parent: address,\n node: pVlanPrio,\n reference: getReference(address, 'P'),\n });\n });\n\n return actions;\n}\n\nfunction initGSeElements(\n doc: XMLDocument,\n connectedAp: Element,\n options: {\n macGeneratorGse: () => string | null;\n appidGeneratorGse: () => string | null;\n unconnectedGseControl: Set<string>;\n },\n): EditV2[] {\n const actions: EditV2[] = [];\n\n const ied = doc.querySelector(\n `IED[name=\"${connectedAp.getAttribute('iedName')}\"]`,\n );\n\n Array.from(ied?.querySelectorAll('GSEControl') ?? [])\n .filter(gseControl => {\n const id = identity(gseControl) as string;\n\n if (options.unconnectedGseControl.has(id)) {\n options.unconnectedGseControl.delete(id);\n return true;\n }\n\n return false;\n })\n .forEach(gseControl => {\n const cbName = gseControl.getAttribute('name');\n const ldInst =\n gseControl.closest('LDevice')?.getAttribute('inst') ?? null;\n\n const gSE = createElement(connectedAp.ownerDocument, 'GSE', {\n cbName,\n ldInst,\n });\n actions.push({\n parent: connectedAp,\n node: gSE,\n reference: getReference(connectedAp, 'GSE'),\n });\n\n const address = createElement(connectedAp.ownerDocument, 'Address', {});\n actions.push({\n parent: gSE,\n node: address,\n reference: getReference(gSE, 'Address'),\n });\n\n const pMac = createElement(connectedAp.ownerDocument, 'P', {\n type: 'MAC-Address',\n });\n pMac.textContent = options.macGeneratorGse();\n actions.push({\n parent: address,\n node: pMac,\n reference: getReference(address, 'P'),\n });\n\n const pAppId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'APPID',\n });\n pAppId.textContent = options.appidGeneratorGse();\n actions.push({\n parent: address,\n node: pAppId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanId = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-ID',\n });\n pVlanId.textContent = '000';\n actions.push({\n parent: address,\n node: pVlanId,\n reference: getReference(address, 'P'),\n });\n\n const pVlanPrio = createElement(connectedAp.ownerDocument, 'P', {\n type: 'VLAN-PRIORITY',\n });\n pVlanPrio.textContent = '4';\n actions.push({\n parent: address,\n node: pVlanPrio,\n reference: getReference(address, 'P'),\n });\n\n const minTime = createElement(connectedAp.ownerDocument, 'MinTime', {\n unit: 's',\n multiplier: 'm',\n });\n minTime.textContent = '10';\n actions.push({\n parent: gSE,\n node: minTime,\n reference: getReference(gSE, 'MinTime'),\n });\n\n const maxTime = createElement(connectedAp.ownerDocument, 'MaxTime', {\n unit: 's',\n multiplier: 'm',\n });\n maxTime.textContent = '10000';\n actions.push({\n parent: gSE,\n node: maxTime,\n reference: getReference(gSE, 'MaxTime'),\n });\n });\n\n return actions;\n}\n\nfunction unconnectedGseControls(doc: XMLDocument): Set<string> {\n const allGseControl = Array.from(doc.querySelectorAll('GSEControl'));\n\n const unconnectedGseControl = allGseControl\n .filter(gseControl => {\n const iedName = gseControl.closest('IED')?.getAttribute('name');\n const ldInst = gseControl.closest('LDevice')?.getAttribute('inst');\n const cbName = gseControl.getAttribute('name');\n\n return !doc.querySelector(\n `ConnectedAP[iedName=\"${iedName}\"] ` +\n `> GSE[ldInst=\"${ldInst}\"][cbName=\"${cbName}\"]`,\n );\n })\n .map(gseControl => identity(gseControl) as string);\n\n const mySet = new Set(unconnectedGseControl);\n return mySet;\n}\n\nfunction unconnectedSampledValueControls(doc: XMLDocument): Set<string> {\n const allSmvControl = Array.from(doc.querySelectorAll('SampledValueControl'));\n\n const unconnectedSmvControl = allSmvControl\n .filter(gseControl => {\n const iedName = gseControl.closest('IED')?.getAttribute('name');\n const ldInst = gseControl.closest('LDevice')?.getAttribute('inst');\n const cbName = gseControl.getAttribute('name');\n\n return !doc.querySelector(\n `ConnectedAP[iedName=\"${iedName}\"] ` +\n `> SMV[ldInst=\"${ldInst}\"][cbName=\"${cbName}\"]`,\n );\n })\n .map(gseControl => identity(gseControl) as string);\n\n const mySet = new Set(unconnectedSmvControl);\n return mySet;\n}\n\nfunction createConnectedApAction(parent: Element): WizardActor {\n return (_: WizardInputElement[], wizard: Element): EditV2[] => {\n const doc = parent.ownerDocument;\n\n // generators ensure unique MAC-Address and APPID across the project\n const macGeneratorSmv = macAddressGenerator(doc, 'SMV');\n const appidGeneratorSmv = appIdGenerator(doc, 'SMV');\n const macGeneratorGse = macAddressGenerator(doc, 'GSE');\n const appidGeneratorGse = appIdGenerator(doc, 'GSE');\n\n // track GSE and SMV for multiselect access points connection\n const unconnectedGseControl = unconnectedGseControls(doc);\n const unconnectedSampledValueControl = unconnectedSampledValueControls(doc);\n\n const list = wizard.querySelector('#apList') as SelectionList;\n if (!list) {\n return [];\n }\n\n const actions = list.selectedElements.map(accP => {\n const id = `${identity(accP)}`;\n const [iedName, apName] = id.split('>');\n const connAPactions: EditV2[] = [];\n\n const connectedAp = createElement(parent.ownerDocument, 'ConnectedAP', {\n iedName,\n apName,\n });\n connAPactions.push({\n parent,\n node: connectedAp,\n reference: getReference(parent, 'ConnectedAP'),\n });\n connAPactions.push(\n ...initSMVElements(doc, connectedAp, {\n macGeneratorSmv,\n appidGeneratorSmv,\n unconnectedSampledValueControl,\n }),\n );\n connAPactions.push(\n ...initGSeElements(doc, connectedAp, {\n macGeneratorGse,\n appidGeneratorGse,\n unconnectedGseControl,\n }),\n );\n\n return connAPactions;\n });\n\n return actions;\n };\n}\n\n/** Sorts connected `AccessPoint`s to the bottom. */\nfunction compareAccessPointConnection(\n a: AccessPointDescription,\n b: AccessPointDescription,\n): number {\n if (a.connected !== b.connected) {\n return b.connected ? -1 : 1;\n }\n return 0;\n}\n\nfunction existConnectedAp(accessPoint: Element): boolean {\n const iedName = accessPoint.closest('IED')?.getAttribute('name');\n const apName = accessPoint.getAttribute('name');\n\n const connAp = accessPoint.ownerDocument.querySelector(\n `ConnectedAP[iedName=\"${iedName}\"][apName=\"${apName}\"]`,\n );\n\n return !!connAp;\n}\n\n/** @returns single page [[`Wizard`]] for creating SCL element ConnectedAP. */\nexport function createConnectedApWizard(element: Element): Wizard {\n const doc = element.ownerDocument;\n\n const accessPoints = Array.from(doc.querySelectorAll(':root > IED'))\n .sort(compareNames)\n .flatMap(ied =>\n Array.from(ied.querySelectorAll(':root > IED > AccessPoint')),\n )\n .map(accesspoint => ({\n element: accesspoint,\n connected: existConnectedAp(accesspoint),\n }))\n .sort(compareAccessPointConnection);\n\n const items: SelectItem[] = accessPoints.map(appP => ({\n headline: `${identity(appP.element)}`,\n supportingText: appP.connected ? 'AccessPoint already connected!' : '',\n selected: !appP.connected,\n disabled: appP.connected,\n attachedElement: appP.element,\n }));\n\n return {\n title: 'Add ConnectedAP',\n primary: {\n icon: 'save',\n label: 'save',\n action: createConnectedApAction(element),\n },\n content: [\n html`<selection-list\n id=\"apList\"\n multi\n .items=${items}\n filterable\n ></selection-list>`,\n ],\n };\n}\n\nfunction updateAction(element: Element): WizardActor {\n return (inputs: WizardInputElement[], wizard: Element): EditV2[] => {\n const instType: boolean =\n (wizard.querySelector('#instType') as SclCheckbox).value === 'true';\n\n const addressContent: Record<string, string | null> = {};\n inputs.forEach(input => {\n if (!(input instanceof SclCheckbox)) {\n const key = input.label;\n const value = getValue(input);\n addressContent[key] = value;\n }\n });\n\n return updateAddress(element, addressContent, instType);\n };\n}\n\n/** @returns single page [[`Wizard`]] to edit SCL element ConnectedAP. */\nexport function editConnectedApWizard(element: Element): Wizard {\n return {\n title: 'Edit ConnectedAP',\n primary: {\n icon: 'save',\n label: 'save',\n action: updateAction(element),\n },\n content: [...contentAddress({ element, types: getTypes(element) })],\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import { editConnectedApWizard } from './connectedap.js';
|
|
5
|
+
import { XMLEditor } from '@openscd/oscd-editor';
|
|
6
|
+
import { SclTextField } from '@openenergytools/scl-text-field';
|
|
7
|
+
import { SclCheckbox } from '@openenergytools/scl-checkbox';
|
|
8
|
+
if (!customElements.get('scl-text-field'))
|
|
9
|
+
customElements.define('scl-text-field', SclTextField);
|
|
10
|
+
if (!customElements.get('scl-checkbox'))
|
|
11
|
+
customElements.define('scl-checkbox', SclCheckbox);
|
|
12
|
+
async function setSclTextFieldValue(field, value) {
|
|
13
|
+
if (field.nullable && !field.nullSwitch?.selected) {
|
|
14
|
+
field.nullSwitch?.click();
|
|
15
|
+
await field.updateComplete;
|
|
16
|
+
}
|
|
17
|
+
field.value = value;
|
|
18
|
+
await field.updateComplete;
|
|
19
|
+
field.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
20
|
+
await field.updateComplete;
|
|
21
|
+
}
|
|
22
|
+
const xmlParser = new DOMParser();
|
|
23
|
+
function createSclDoc() {
|
|
24
|
+
return xmlParser.parseFromString(`<?xml version="1.0" encoding="UTF-8"?>
|
|
25
|
+
<SCL xmlns="http://www.iec.ch/61850/2003/SCL"
|
|
26
|
+
version="2007"
|
|
27
|
+
revision="B"
|
|
28
|
+
release="4">
|
|
29
|
+
<Substation name="S1">
|
|
30
|
+
<VoltageLevel name="V1">
|
|
31
|
+
<Bay name="PUB"/>
|
|
32
|
+
<Bay name="SUB"/>
|
|
33
|
+
</VoltageLevel>
|
|
34
|
+
</Substation>
|
|
35
|
+
<Communication>
|
|
36
|
+
<SubNetwork name="StationBus" type="8-MMS">
|
|
37
|
+
<BitRate unit="b/s" multiplier="M">100</BitRate>
|
|
38
|
+
<ConnectedAP iedName="PUB_A" apName="AP1">
|
|
39
|
+
<GSE ldInst="LD_A" cbName="GCB_A">
|
|
40
|
+
<Address>
|
|
41
|
+
<P type="MAC-Address">01-0C-CD-01-00-01</P>
|
|
42
|
+
<P type="APPID">0001</P>
|
|
43
|
+
</Address>
|
|
44
|
+
<MinTime unit="s" multiplier="m">10</MinTime>
|
|
45
|
+
<MaxTime unit="s" multiplier="m">1000</MaxTime>
|
|
46
|
+
</GSE>
|
|
47
|
+
</ConnectedAP>
|
|
48
|
+
</SubNetwork>
|
|
49
|
+
</Communication>
|
|
50
|
+
<IED name="PUB_A" manufacturer="OpenSCD">
|
|
51
|
+
<AccessPoint name="AP1">
|
|
52
|
+
<Server>
|
|
53
|
+
<Authentication/>
|
|
54
|
+
<LDevice inst="LD_A">
|
|
55
|
+
<LN0 lnClass="LLN0" inst="" lnType="LLN0_Test">
|
|
56
|
+
<DataSet name="DS_A">
|
|
57
|
+
<FCDA ldInst="LD_A" prefix="" lnClass="TCTR" lnInst="1" doName="Beh" daName="stVal" fc="ST"/>
|
|
58
|
+
<FCDA ldInst="LD_A" prefix="" lnClass="TCTR" lnInst="1" doName="Beh" daName="q" fc="ST"/>
|
|
59
|
+
</DataSet>
|
|
60
|
+
<GSEControl name="GCB_A" type="GOOSE" appID="0001" confRev="1" datSet="DS_A"/>
|
|
61
|
+
</LN0>
|
|
62
|
+
<LN lnClass="TCTR" inst="1" lnType="TCTR_Test">
|
|
63
|
+
<DOI name="Beh">
|
|
64
|
+
<DAI name="stVal">
|
|
65
|
+
<Val>on</Val>
|
|
66
|
+
</DAI>
|
|
67
|
+
</DOI>
|
|
68
|
+
<DOI name="HzRtg"/>
|
|
69
|
+
<DOI name="ARtg"/>
|
|
70
|
+
</LN>
|
|
71
|
+
</LDevice>
|
|
72
|
+
</Server>
|
|
73
|
+
</AccessPoint>
|
|
74
|
+
</IED>
|
|
75
|
+
</SCL>`, 'application/xml');
|
|
76
|
+
}
|
|
77
|
+
describe('ConnectedAP wizard', () => {
|
|
78
|
+
let xmlEditor;
|
|
79
|
+
beforeEach(() => {
|
|
80
|
+
xmlEditor = new XMLEditor();
|
|
81
|
+
});
|
|
82
|
+
it('Editing a ConnectedAP to add an IP/Subnet does not affect GSE elements contained within', async () => {
|
|
83
|
+
const doc = createSclDoc();
|
|
84
|
+
const connectedAP = doc.querySelector('ConnectedAP');
|
|
85
|
+
expect(connectedAP).to.exist;
|
|
86
|
+
// Verify GSE > Address exists before editing
|
|
87
|
+
const gseBefore = connectedAP.querySelector('GSE');
|
|
88
|
+
expect(gseBefore).to.exist;
|
|
89
|
+
const gseAddressBefore = gseBefore.querySelector('Address');
|
|
90
|
+
expect(gseAddressBefore).to.exist;
|
|
91
|
+
expect(gseAddressBefore.querySelectorAll('P').length).to.equal(2);
|
|
92
|
+
// Create the edit wizard
|
|
93
|
+
const wizard = editConnectedApWizard(connectedAP);
|
|
94
|
+
expect(wizard).to.exist;
|
|
95
|
+
expect(wizard.primary).to.exist;
|
|
96
|
+
// Render the wizard content
|
|
97
|
+
const content = await fixture(html `<form>${wizard.content}</form>`);
|
|
98
|
+
// Find the IP field and set a value
|
|
99
|
+
const ipField = content.querySelector('scl-text-field[label="IP"]');
|
|
100
|
+
expect(ipField).to.exist;
|
|
101
|
+
await setSclTextFieldValue(ipField, '192.168.0.1');
|
|
102
|
+
// Find the IP-SUBNET field and set a value
|
|
103
|
+
const subnetField = content.querySelector('scl-text-field[label="IP-SUBNET"]');
|
|
104
|
+
expect(subnetField).to.exist;
|
|
105
|
+
await setSclTextFieldValue(subnetField, '255.255.255.0');
|
|
106
|
+
// Gather inputs (all scl-text-field elements)
|
|
107
|
+
const inputs = Array.from(content.querySelectorAll('scl-text-field'));
|
|
108
|
+
// Execute the update action
|
|
109
|
+
const edits = wizard.primary.action(inputs, content);
|
|
110
|
+
expect(edits).to.exist;
|
|
111
|
+
expect(edits.length).to.be.greaterThan(0);
|
|
112
|
+
// Apply edits
|
|
113
|
+
xmlEditor.commit(edits);
|
|
114
|
+
// After applying edits, verify the GSE > Address still exists and is intact
|
|
115
|
+
const gseAfter = connectedAP.querySelector('GSE');
|
|
116
|
+
expect(gseAfter, 'GSE element should still exist').to.exist;
|
|
117
|
+
const gseAddressAfter = gseAfter.querySelector('Address');
|
|
118
|
+
expect(gseAddressAfter, 'GSE > Address element should still exist after editing ConnectedAP address').to.exist;
|
|
119
|
+
const gsePElements = gseAddressAfter.querySelectorAll('P');
|
|
120
|
+
expect(gsePElements.length, 'GSE > Address should still have 2 P elements').to.equal(2);
|
|
121
|
+
const macAddress = Array.from(gsePElements).find(p => p.getAttribute('type') === 'MAC-Address');
|
|
122
|
+
expect(macAddress, 'GSE MAC-Address should be preserved').to.exist;
|
|
123
|
+
expect(macAddress.textContent).to.equal('01-0C-CD-01-00-01');
|
|
124
|
+
const appId = Array.from(gsePElements).find(p => p.getAttribute('type') === 'APPID');
|
|
125
|
+
expect(appId, 'GSE APPID should be preserved').to.exist;
|
|
126
|
+
expect(appId.textContent).to.equal('0001');
|
|
127
|
+
// Also verify that the ConnectedAP now has its own direct Address child
|
|
128
|
+
const connApAddress = connectedAP.querySelector(':scope > Address');
|
|
129
|
+
expect(connApAddress, 'ConnectedAP should have a direct Address child with IP info').to.exist;
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=connectedap.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectedap.spec.js","sourceRoot":"","sources":["../../wizards/connectedap.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-expressions */\nimport { expect, fixture } from '@open-wc/testing';\nimport { html } from 'lit';\n\nimport { editConnectedApWizard } from './connectedap.js';\nimport { EditV2 } from '@openscd/oscd-api';\nimport { XMLEditor } from '@openscd/oscd-editor';\nimport { SclTextField } from '@openenergytools/scl-text-field';\nimport { SclCheckbox } from '@openenergytools/scl-checkbox';\nimport { WizardInputElement } from '../foundation.js';\n\nif (!customElements.get('scl-text-field'))\n customElements.define('scl-text-field', SclTextField);\nif (!customElements.get('scl-checkbox'))\n customElements.define('scl-checkbox', SclCheckbox);\n\nasync function setSclTextFieldValue(\n field: SclTextField,\n value: string,\n): Promise<void> {\n if (field.nullable && !field.nullSwitch?.selected) {\n field.nullSwitch?.click();\n await field.updateComplete;\n }\n\n field.value = value;\n await field.updateComplete;\n field.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n await field.updateComplete;\n}\n\nconst xmlParser = new DOMParser();\nfunction createSclDoc(): XMLDocument {\n return xmlParser.parseFromString(\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<SCL xmlns=\"http://www.iec.ch/61850/2003/SCL\"\n version=\"2007\"\n revision=\"B\"\n release=\"4\">\n <Substation name=\"S1\">\n <VoltageLevel name=\"V1\">\n <Bay name=\"PUB\"/>\n <Bay name=\"SUB\"/>\n </VoltageLevel>\n </Substation>\n <Communication>\n <SubNetwork name=\"StationBus\" type=\"8-MMS\">\n <BitRate unit=\"b/s\" multiplier=\"M\">100</BitRate>\n <ConnectedAP iedName=\"PUB_A\" apName=\"AP1\">\n <GSE ldInst=\"LD_A\" cbName=\"GCB_A\">\n <Address>\n <P type=\"MAC-Address\">01-0C-CD-01-00-01</P>\n <P type=\"APPID\">0001</P>\n </Address>\n <MinTime unit=\"s\" multiplier=\"m\">10</MinTime>\n <MaxTime unit=\"s\" multiplier=\"m\">1000</MaxTime>\n </GSE>\n </ConnectedAP>\n </SubNetwork>\n </Communication>\n <IED name=\"PUB_A\" manufacturer=\"OpenSCD\">\n <AccessPoint name=\"AP1\">\n <Server>\n <Authentication/>\n <LDevice inst=\"LD_A\">\n <LN0 lnClass=\"LLN0\" inst=\"\" lnType=\"LLN0_Test\">\n <DataSet name=\"DS_A\">\n <FCDA ldInst=\"LD_A\" prefix=\"\" lnClass=\"TCTR\" lnInst=\"1\" doName=\"Beh\" daName=\"stVal\" fc=\"ST\"/>\n <FCDA ldInst=\"LD_A\" prefix=\"\" lnClass=\"TCTR\" lnInst=\"1\" doName=\"Beh\" daName=\"q\" fc=\"ST\"/>\n </DataSet>\n <GSEControl name=\"GCB_A\" type=\"GOOSE\" appID=\"0001\" confRev=\"1\" datSet=\"DS_A\"/>\n </LN0>\n <LN lnClass=\"TCTR\" inst=\"1\" lnType=\"TCTR_Test\">\n <DOI name=\"Beh\">\n <DAI name=\"stVal\">\n <Val>on</Val>\n </DAI>\n </DOI>\n <DOI name=\"HzRtg\"/>\n <DOI name=\"ARtg\"/>\n </LN>\n </LDevice>\n </Server>\n </AccessPoint>\n </IED>\n</SCL>`,\n 'application/xml',\n );\n}\n\ndescribe('ConnectedAP wizard', () => {\n let xmlEditor: XMLEditor;\n\n beforeEach(() => {\n xmlEditor = new XMLEditor();\n });\n\n it('Editing a ConnectedAP to add an IP/Subnet does not affect GSE elements contained within', async () => {\n const doc = createSclDoc();\n const connectedAP = doc.querySelector('ConnectedAP')!;\n expect(connectedAP).to.exist;\n\n // Verify GSE > Address exists before editing\n const gseBefore = connectedAP.querySelector('GSE');\n expect(gseBefore).to.exist;\n const gseAddressBefore = gseBefore!.querySelector('Address');\n expect(gseAddressBefore).to.exist;\n expect(gseAddressBefore!.querySelectorAll('P').length).to.equal(2);\n\n // Create the edit wizard\n const wizard = editConnectedApWizard(connectedAP);\n expect(wizard).to.exist;\n expect(wizard.primary).to.exist;\n\n // Render the wizard content\n const content = await fixture(html`<form>${wizard.content}</form>`);\n\n // Find the IP field and set a value\n const ipField = content.querySelector(\n 'scl-text-field[label=\"IP\"]',\n ) as SclTextField;\n expect(ipField).to.exist;\n await setSclTextFieldValue(ipField, '192.168.0.1');\n\n // Find the IP-SUBNET field and set a value\n const subnetField = content.querySelector(\n 'scl-text-field[label=\"IP-SUBNET\"]',\n ) as SclTextField;\n expect(subnetField).to.exist;\n await setSclTextFieldValue(subnetField, '255.255.255.0');\n\n // Gather inputs (all scl-text-field elements)\n const inputs = Array.from(\n content.querySelectorAll('scl-text-field'),\n ) as WizardInputElement[];\n\n // Execute the update action\n const edits = wizard.primary!.action(inputs, content) as EditV2[];\n expect(edits).to.exist;\n expect(edits.length).to.be.greaterThan(0);\n\n // Apply edits\n xmlEditor.commit(edits);\n\n // After applying edits, verify the GSE > Address still exists and is intact\n const gseAfter = connectedAP.querySelector('GSE');\n expect(gseAfter, 'GSE element should still exist').to.exist;\n\n const gseAddressAfter = gseAfter!.querySelector('Address');\n expect(\n gseAddressAfter,\n 'GSE > Address element should still exist after editing ConnectedAP address',\n ).to.exist;\n\n const gsePElements = gseAddressAfter!.querySelectorAll('P');\n expect(\n gsePElements.length,\n 'GSE > Address should still have 2 P elements',\n ).to.equal(2);\n\n const macAddress = Array.from(gsePElements).find(\n p => p.getAttribute('type') === 'MAC-Address',\n );\n expect(macAddress, 'GSE MAC-Address should be preserved').to.exist;\n expect(macAddress!.textContent).to.equal('01-0C-CD-01-00-01');\n\n const appId = Array.from(gsePElements).find(\n p => p.getAttribute('type') === 'APPID',\n );\n expect(appId, 'GSE APPID should be preserved').to.exist;\n expect(appId!.textContent).to.equal('0001');\n\n // Also verify that the ConnectedAP now has its own direct Address child\n const connApAddress = connectedAP.querySelector(':scope > Address');\n expect(\n connApAddress,\n 'ConnectedAP should have a direct Address child with IP info',\n ).to.exist;\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@omicronenergy/oscd-scl-dialogs",
|
|
3
3
|
"description": "Provides a resuable dialog for adding and editing SCL elements in OpenSCD.",
|
|
4
4
|
"displayName": "OpenSCD Edit Dialog",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.15",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/OMICRONEnergyOSS/oscd-scl-dialogs.git"
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
"typescript": "^5.9.3"
|
|
118
118
|
},
|
|
119
119
|
"overrides": {
|
|
120
|
-
"playwright": "1.
|
|
120
|
+
"playwright": "1.59.1"
|
|
121
121
|
},
|
|
122
122
|
"customElements": "custom-elements.json",
|
|
123
123
|
"prettier": {
|