From e5ca4d4a6bf58fcdbce3cd92b591a6f8e1bb1390 Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Tue, 8 Jul 2025 23:25:09 +0200 Subject: [PATCH] feat: allow to tag non IEC61850-7-4 namespaces --- .../insertSelecetdLNodeType.spec.ts | 27 ++++++++++++++++++- .../insertSelectedLNodeType.testdata.ts | 20 ++++++++++++++ tDataTypeTemplates/insertSelectedLNodeType.ts | 10 +++++++ tDataTypeTemplates/nsdToJson.ts | 5 ++-- 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/tDataTypeTemplates/insertSelecetdLNodeType.spec.ts b/tDataTypeTemplates/insertSelecetdLNodeType.spec.ts index ba78b7a..496e5ef 100644 --- a/tDataTypeTemplates/insertSelecetdLNodeType.spec.ts +++ b/tDataTypeTemplates/insertSelecetdLNodeType.spec.ts @@ -9,6 +9,7 @@ import { mhaiSelection, mmxuSelection, ptocSelection, + lln0Selection } from "./insertSelectedLNodeType.testdata.js"; import { @@ -19,7 +20,7 @@ import { } from "./insertSelectedDataType.testfiles.js"; import { insertSelectedLNodeType } from "./insertSelectedLNodeType.js"; -import { LNodeDescription, nsdToJson } from "./nsdToJson.js"; +import { CdcChildren, DaDescription, LNodeDescription, nsdToJson } from "./nsdToJson.js"; const incompleteMmxu = findElement(missingMmxuTypes) as XMLDocument; const imcompleteLtrk = findElement(incompleteLtrkTypes) as XMLDocument; @@ -215,4 +216,28 @@ describe("insertLNodeTypeSelection", () => { const doTypeEdit = edits[4].node as Element; expect(doTypeEdit.querySelector('SDO[name="phsAHar"]')?.getAttribute('count')).to.equal("maxPts"); }); + + it('add user defined data object', () => { + const lnData = nsdToJson("LLN0") as LNodeDescription; + const userData = nsdToJson("SPS") as CdcChildren; + (userData["dataNs"] as DaDescription).mandatory = true; + (userData["dataNs"] as DaDescription).val = "TestNameSpace-1-d-1234567890"; + + const cdcDescription = { + tagName: 'DataObject', + type: 'SPS', + descID: '', + presCond: 'O', + children: userData, + }; + + Object.assign(lnData, { + ['TestDo']: cdcDescription, + }); + + const edits = insertSelectedLNodeType(missingDataTypes, lln0Selection, { class: "LLN0", data: lnData }); + + expect(edits.length).to.equal(5); + expect((edits[3].node as Element).querySelector('DA[name="dataNs"] > Val')?.textContent).to.equal("TestNameSpace-1-d-1234567890"); + }) }); diff --git a/tDataTypeTemplates/insertSelectedLNodeType.testdata.ts b/tDataTypeTemplates/insertSelectedLNodeType.testdata.ts index 6e56b3f..aebc7d7 100644 --- a/tDataTypeTemplates/insertSelectedLNodeType.testdata.ts +++ b/tDataTypeTemplates/insertSelectedLNodeType.testdata.ts @@ -513,3 +513,23 @@ export const mhaiSelection = { } } } + +export const lln0Selection = { + "Beh": { + "q": {}, + "stVal": { + "blocked": {}, + "off": {}, + "on": {}, + "test": {}, + "test/blocked": {} + }, + "t": {} + }, + "TestDo": { + "stVal": {}, + "q": {}, + "t": {}, + "dataNs": {} + }, +} diff --git a/tDataTypeTemplates/insertSelectedLNodeType.ts b/tDataTypeTemplates/insertSelectedLNodeType.ts index 0d47fe4..4b52c9d 100644 --- a/tDataTypeTemplates/insertSelectedLNodeType.ts +++ b/tDataTypeTemplates/insertSelectedLNodeType.ts @@ -332,6 +332,7 @@ export function insertSelectedLNodeType( type?: string; isArray?: string; sizeAttribute?: string; + val?: string; }, ][] = Object.entries(dO.children); @@ -360,6 +361,15 @@ export function insertSelectedLNodeType( if (dep.typeKind === "BASIC" || !dep.typeKind) { da.setAttribute("bType", dep.type!); + + + // One can include a value for any data attribute + if (dep.val) { + const value = createElement(doc, "Val", {}); + value.textContent = dep.val; + (da as Node).insertBefore(value, null); + } + } if (dep.typeKind === "ENUMERATED") { diff --git a/tDataTypeTemplates/nsdToJson.ts b/tDataTypeTemplates/nsdToJson.ts index 4dfafb2..ec13136 100644 --- a/tDataTypeTemplates/nsdToJson.ts +++ b/tDataTypeTemplates/nsdToJson.ts @@ -58,7 +58,7 @@ type ServiceDaDescription = { children?: DaChildren; }; -type DaDescription = { +export type DaDescription = { tagName: string; name: string; type?: string; @@ -75,9 +75,10 @@ type DaDescription = { defaultValue?: string; presCondArgs?: string; children?: DaChildren; + val?: string }; -type CdcChildren = Record< +export type CdcChildren = Record< string, DaDescription | ServiceDaDescription | CdcDescription >;