From 329b85455d2cb64fc7e8a9ec180ca85ca583ba78 Mon Sep 17 00:00:00 2001 From: Stef3st Date: Mon, 18 Dec 2023 10:05:22 +0100 Subject: [PATCH 1/8] feat: implement wye and del cdc support Signed-off-by: Stef3st --- .../src/editors/protocol104/foundation/cdc.ts | 69 +++++++++++++++++-- .../editors/protocol104/wizards/address.ts | 6 +- .../protocol104/wizards/createAddresses.ts | 5 +- .../src/editors/protocol104/wizards/doi.ts | 3 +- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/packages/open-scd/src/editors/protocol104/foundation/cdc.ts b/packages/open-scd/src/editors/protocol104/foundation/cdc.ts index ddcd428e06..cdde77237e 100644 --- a/packages/open-scd/src/editors/protocol104/foundation/cdc.ts +++ b/packages/open-scd/src/editors/protocol104/foundation/cdc.ts @@ -37,6 +37,7 @@ export const supportedCdcTypes = [ 'BCR', 'BSC', 'CMV', + 'DEL', 'DPC', 'DPS', 'ENG', @@ -50,6 +51,7 @@ export const supportedCdcTypes = [ 'SPC', 'SPG', 'SPS', + 'WYE', ] as const; export type SupportedCdcType = (typeof supportedCdcTypes)[number]; @@ -230,6 +232,29 @@ export const cdcProcessings: Record< }, control: {}, }, + DEL: { + monitor: { + '35': { + daPaths: [ + { path: ['phsAB', 'cVal', 'mag', 'f'] }, + { path: ['phsBC', 'cVal', 'mag', 'f'] }, + { path: ['phsCA', 'cVal', 'mag', 'f'] }, + ], + create: createAddressAction, + inverted: false, + }, + '36': { + daPaths: [ + { path: ['phsAB', 'cVal', 'mag', 'f'] }, + { path: ['phsBC', 'cVal', 'mag', 'f'] }, + { path: ['phsCA', 'cVal', 'mag', 'f'] }, + ], + create: createAddressAction, + inverted: false, + }, + }, + control: {}, + }, DPC: { monitor: { '31': { @@ -413,6 +438,29 @@ export const cdcProcessings: Record< }, control: {}, }, + WYE: { + monitor: { + '35': { + daPaths: [ + { path: ['phsA', 'cVal', 'mag', 'f'] }, + { path: ['phsB', 'cVal', 'mag', 'f'] }, + { path: ['phsC', 'cVal', 'mag', 'f'] }, + ], + create: createAddressAction, + inverted: false, + }, + '36': { + daPaths: [ + { path: ['phsA', 'cVal', 'mag', 'f'] }, + { path: ['phsB', 'cVal', 'mag', 'f'] }, + { path: ['phsC', 'cVal', 'mag', 'f'] }, + ], + create: createAddressAction, + inverted: false, + }, + }, + control: {}, + }, }; /** @@ -729,19 +777,30 @@ function createTemplateStructure( templateStructure = null; return; } - const daElement = typeElement.querySelector( + const sdoElement = typeElement.querySelector( + `:scope > SDO[name="${name}"]` + ); + const sdoType = sdoElement?.getAttribute('type'); + + if (sdoType) typeElement = doc.querySelector(`DOType[id="${sdoType}"]`); + + const daElement = typeElement!.querySelector( `:scope > DA[name="${name}"], :scope > BDA[name="${name}"]` ); + console.log(daElement); // If there is no DA/BDA Element found the structure is incorrect, so just stop. - if (daElement === null) { + if (daElement === null && sdoElement === null) { templateStructure = null; return; } - templateStructure!.push(daElement); - const bType = daElement.getAttribute('bType') ?? ''; + templateStructure!.push(sdoElement ? sdoElement : daElement!); + + if (sdoElement) return; + + const bType = daElement!.getAttribute('bType') ?? ''; if (bType === 'Struct') { - const type = getTypeAttribute(daElement) ?? ''; + const type = getTypeAttribute(daElement!) ?? ''; typeElement = doc.querySelector(`DAType[id="${type}"]`); } else { typeElement = null; diff --git a/packages/open-scd/src/editors/protocol104/wizards/address.ts b/packages/open-scd/src/editors/protocol104/wizards/address.ts index e902581096..2fed1fcb94 100644 --- a/packages/open-scd/src/editors/protocol104/wizards/address.ts +++ b/packages/open-scd/src/editors/protocol104/wizards/address.ts @@ -57,7 +57,8 @@ export function updateAddressValue( addressElement: Element ): WizardActor { return (inputs: WizardInputElement[]): EditorAction[] => { - const cdc = getCdcValueFromDOIElement(doiElement) ?? ''; + const foundCdc = getCdcValueFromDOIElement(doiElement) ?? ''; + const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; const ti = addressElement.getAttribute('ti') ?? ''; const casdu = getValue(inputs.find(i => i.label === 'casdu')!)!; @@ -103,7 +104,8 @@ export function editAddressWizard( addressElement: Element ): Wizard { function renderAddressWizard(): TemplateResult[] { - const cdc = getCdcValueFromDOIElement(doiElement) ?? ''; + const foundCdc = getCdcValueFromDOIElement(doiElement) ?? ''; + const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; const ti = addressElement.getAttribute('ti') ?? ''; let casdu = addressElement.getAttribute('casdu') ?? ''; diff --git a/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts b/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts index 224c6668d5..ab7adcbd34 100644 --- a/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts +++ b/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts @@ -187,8 +187,9 @@ export function createAddressesWizard( lnElement: Element, doElement: Element ): Wizard { - const cdc = getCdcValueFromDOElement(doElement) ?? ''; - const cdcProcessing = cdcProcessings[cdc]; + const foundCdc = getCdcValueFromDOElement(doElement) ?? ''; + const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; + const cdcProcessing = cdcProcessings[foundCdc]; const monitorTis = Object.keys(cdcProcessing.monitor); const controlTis = Object.keys(cdcProcessing.control); diff --git a/packages/open-scd/src/editors/protocol104/wizards/doi.ts b/packages/open-scd/src/editors/protocol104/wizards/doi.ts index fafca3d117..110a1e035c 100644 --- a/packages/open-scd/src/editors/protocol104/wizards/doi.ts +++ b/packages/open-scd/src/editors/protocol104/wizards/doi.ts @@ -39,7 +39,8 @@ function renderTiOverview(foundTis: string[], label: string): TemplateResult { export function renderDOIWizard(doiElement: Element): TemplateResult[] { const iedElement = doiElement.closest('IED'); const fullpath = getFullPath(doiElement, 'IED'); - const cdc = getCdcValueFromDOIElement(doiElement); + const foundCdc = getCdcValueFromDOIElement(doiElement); + const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; // Add the basic fields to the list. const fields: TemplateResult[] = [ From d3e4ee077ad54ef1f8b2e844234a43e437a4900d Mon Sep 17 00:00:00 2001 From: Stef3st Date: Mon, 18 Dec 2023 14:42:42 +0100 Subject: [PATCH 2/8] chore: add description for mapping to cmv Signed-off-by: Stef3st --- .../src/editors/protocol104/wizards/address.ts | 12 ++++++++++-- packages/open-scd/src/translations/de.ts | 2 ++ packages/open-scd/src/translations/en.ts | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/open-scd/src/editors/protocol104/wizards/address.ts b/packages/open-scd/src/editors/protocol104/wizards/address.ts index 2fed1fcb94..b6917ce9a0 100644 --- a/packages/open-scd/src/editors/protocol104/wizards/address.ts +++ b/packages/open-scd/src/editors/protocol104/wizards/address.ts @@ -105,7 +105,8 @@ export function editAddressWizard( ): Wizard { function renderAddressWizard(): TemplateResult[] { const foundCdc = getCdcValueFromDOIElement(doiElement) ?? ''; - const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; + const reqCmvMapping = foundCdc === 'WYE' || foundCdc === 'DEL'; + const cdc = reqCmvMapping ? 'CMV' : foundCdc; const ti = addressElement.getAttribute('ti') ?? ''; let casdu = addressElement.getAttribute('casdu') ?? ''; @@ -145,7 +146,14 @@ export function editAddressWizard( disabled > `, - html` + html` `, html` Date: Mon, 18 Dec 2023 15:52:40 +0100 Subject: [PATCH 3/8] chore: added tests Signed-off-by: Stef3st --- .../protocol104/wizards/address.test.ts | 21 ++++++++++++++++--- .../editors/protocol104/wizards/doi.test.ts | 16 ++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts b/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts index e5cc137a0a..9d4f5ca15b 100644 --- a/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts +++ b/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts @@ -49,7 +49,9 @@ describe('Wizards for 104 Address Element', () => { describe('when adding a 104 Address', () => { beforeEach(async () => { - await prepareWizard('IED[name="B1"] LN[lnType="SE_GGIO_SET_V002"] DOI[name="Mod"] DAI[name="ctlVal"] Address'); + await prepareWizard( + 'IED[name="B1"] LN[lnType="SE_GGIO_SET_V002"] DOI[name="Mod"] DAI[name="ctlVal"] Address' + ); }); it('shows a validation error message if the combination of casdu and ioa is already in use', async () => { @@ -95,8 +97,6 @@ describe('Wizards for 104 Address Element', () => { it('looks like the latest snapshot', async () => { await expect(element.wizardUI.dialog).dom.to.equalSnapshot(); }); - - }); describe('edit 104 Address with expected value', () => { @@ -197,6 +197,21 @@ describe('Wizards for 104 Address Element', () => { }); }); + describe('edit 104 Address with mapped cdc value', () => { + beforeEach(async () => { + await prepareWizard( + 'IED[name="B1"] LN[lnType="SE_MMXU_SET_V001"] DOI[name="PPV"] DAI[name="f"] Address' + ); + }); + it('should have mappedCmv translation value', async () => { + const cdc = element.wizardUI.dialog!.querySelector( + 'wizard-textfield[label="cdc"]' + ) as WizardTextField; + expect(cdc).to.exist; + await expect(cdc.maybeValue).to.equal('[protocol104.mappedCmv]'); + }); + }); + describe('edit 104 Address with inverted value', () => { beforeEach(async () => { await prepareWizard( diff --git a/packages/open-scd/test/unit/editors/protocol104/wizards/doi.test.ts b/packages/open-scd/test/unit/editors/protocol104/wizards/doi.test.ts index 7ab0b7c4c9..df09cfb9df 100644 --- a/packages/open-scd/test/unit/editors/protocol104/wizards/doi.test.ts +++ b/packages/open-scd/test/unit/editors/protocol104/wizards/doi.test.ts @@ -81,6 +81,22 @@ describe('Wizards for 104 DOI Element', () => { }); }); + describe('show 104 DOI Basic Info for CDC=DEL', () => { + beforeEach(async () => { + doiElement = doc.querySelector( + 'IED[name="B1"] LN[lnType="SE_MMXU_SET_V001"] DOI[name="PPV"]' + )!; + + const doElement = doc + .querySelector('LNodeType[id="SE_MMXU_SET_V001"] > DO[name="PPV"]') + ?.getAttribute('type')!; + + expect(doElement).to.be.equal('SE_DEL_V001'); + const doType = doc.querySelector(`DOType[id="${doElement}"]`)!; + expect(doType.getAttribute('cdc')).to.be.equal('DEL'); + }); + }); + describe('remove104Private', () => { let wizard: Element; let actionEvent: SinonSpy; From 3dec458e6013cabaaa295cbb6ce9b5f4699664f8 Mon Sep 17 00:00:00 2001 From: Stef3st Date: Wed, 20 Dec 2023 13:54:50 +0100 Subject: [PATCH 4/8] chore: add descriptive texts for cdc mapping Signed-off-by: Stef3st --- .../src/editors/protocol104/wizards/address.ts | 8 +++++--- .../protocol104/wizards/createAddresses.ts | 9 +++++++-- packages/open-scd/src/translations/de.ts | 2 +- packages/open-scd/src/translations/en.ts | 2 +- .../editors/protocol104/wizards/address.test.ts | 4 ++-- .../protocol104/wizards/createAddresses.test.ts | 17 +++++++++++++++++ 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/packages/open-scd/src/editors/protocol104/wizards/address.ts b/packages/open-scd/src/editors/protocol104/wizards/address.ts index b6917ce9a0..82fb2ead86 100644 --- a/packages/open-scd/src/editors/protocol104/wizards/address.ts +++ b/packages/open-scd/src/editors/protocol104/wizards/address.ts @@ -148,9 +148,11 @@ export function editAddressWizard( `, html` diff --git a/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts b/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts index ab7adcbd34..7110b8fec7 100644 --- a/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts +++ b/packages/open-scd/src/editors/protocol104/wizards/createAddresses.ts @@ -188,7 +188,8 @@ export function createAddressesWizard( doElement: Element ): Wizard { const foundCdc = getCdcValueFromDOElement(doElement) ?? ''; - const cdc = foundCdc === 'WYE' || foundCdc === 'DEL' ? 'CMV' : foundCdc; + const reqCmvMapping = foundCdc === 'WYE' || foundCdc === 'DEL'; + const cdc = reqCmvMapping ? 'CMV' : foundCdc; const cdcProcessing = cdcProcessings[foundCdc]; const monitorTis = Object.keys(cdcProcessing.monitor); @@ -240,7 +241,11 @@ export function createAddressesWizard( `, html` diff --git a/packages/open-scd/src/translations/de.ts b/packages/open-scd/src/translations/de.ts index b31aac4050..c6d674b865 100644 --- a/packages/open-scd/src/translations/de.ts +++ b/packages/open-scd/src/translations/de.ts @@ -452,7 +452,7 @@ export const de: Translations = { networkView: 'Netzwerk', }, mappedCmv: - 'CMV (gemäß dem IEC 61850-80-1 Standard ist eine WYE zuordnung über CMV erforderlich)', + 'Gemäß dem IEC 61850-80-1 Standard ist eine "{{ cdc }}" zuordnung über CMV erforderlich', values: { missing: 'Kein IED mit 104 Adressen', removeAddresses: 'Alle Adressen entfernen', diff --git a/packages/open-scd/src/translations/en.ts b/packages/open-scd/src/translations/en.ts index fcca5665e0..e6accd2df3 100644 --- a/packages/open-scd/src/translations/en.ts +++ b/packages/open-scd/src/translations/en.ts @@ -448,7 +448,7 @@ export const en = { networkView: 'Network', }, mappedCmv: - 'CMV (according to the IEC 61850-80-1 standard, WYE mapping is required via CMV)', + 'According to the IEC 61850-80-1 standard, "{{ cdc }}" mapping is required via CMV', values: { missing: 'No IED with 104 Addresses', removeAddresses: 'Remove all Addresses', diff --git a/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts b/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts index 9d4f5ca15b..6b2fe36521 100644 --- a/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts +++ b/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts @@ -203,12 +203,12 @@ describe('Wizards for 104 Address Element', () => { 'IED[name="B1"] LN[lnType="SE_MMXU_SET_V001"] DOI[name="PPV"] DAI[name="f"] Address' ); }); - it('should have mappedCmv translation value', async () => { + it('should have mappedCmv translation value in helper field', async () => { const cdc = element.wizardUI.dialog!.querySelector( 'wizard-textfield[label="cdc"]' ) as WizardTextField; expect(cdc).to.exist; - await expect(cdc.maybeValue).to.equal('[protocol104.mappedCmv]'); + await expect(cdc.helper).to.equal('[protocol104.mappedCmv]'); }); }); diff --git a/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts b/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts index 4c5d2a3441..ec2ae7c01f 100644 --- a/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts +++ b/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts @@ -10,6 +10,7 @@ import { WizardInputElement, } from '../../../../../src/foundation.js'; +import { WizardTextField } from '../../../../../src/wizard-textfield.js'; import '../../../../mock-wizard.js'; import { @@ -119,6 +120,22 @@ describe('Wizards for preparing 104 Address Creation', () => { }); }); + describe('show prepare 104 Address creation with mapped cdc value', () => { + beforeEach(async () => { + await prepareWizard( + 'IED[name="B1"] LN[lnType="SE_MMXU_SET_V001"]', + 'PPV' + ); + }); + it('should have mappedCmv translation value in helper field', async () => { + const cdc = element.wizardUI.dialog!.querySelector( + 'wizard-textfield[label="Common Data Class"]' + ) as WizardTextField; + expect(cdc).to.exist; + await expect(cdc.helper).to.equal('[protocol104.mappedCmv]'); + }); + }); + describe('show prepare 104 Address creation (single monitor TI with CtlModel)', () => { beforeEach(async () => { await prepareWizard( From bb550f595b61d7d3325df97b00da7c08abe35835 Mon Sep 17 00:00:00 2001 From: Stef3st Date: Thu, 11 Jan 2024 09:30:49 +0100 Subject: [PATCH 5/8] chore: remove console.log Signed-off-by: Stef3st --- packages/open-scd/src/editors/protocol104/foundation/cdc.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/open-scd/src/editors/protocol104/foundation/cdc.ts b/packages/open-scd/src/editors/protocol104/foundation/cdc.ts index cdde77237e..30b75ad72d 100644 --- a/packages/open-scd/src/editors/protocol104/foundation/cdc.ts +++ b/packages/open-scd/src/editors/protocol104/foundation/cdc.ts @@ -787,7 +787,6 @@ function createTemplateStructure( const daElement = typeElement!.querySelector( `:scope > DA[name="${name}"], :scope > BDA[name="${name}"]` ); - console.log(daElement); // If there is no DA/BDA Element found the structure is incorrect, so just stop. if (daElement === null && sdoElement === null) { templateStructure = null; From e3e17244399dade0b161ae7cb66a43a8153a1e84 Mon Sep 17 00:00:00 2001 From: Stef3st Date: Thu, 11 Jan 2024 10:26:37 +0100 Subject: [PATCH 6/8] chore: removed duplicate import Signed-off-by: Stef3st --- .../unit/editors/protocol104/wizards/createAddresses.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts b/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts index c8efca859e..8d4ecaddbb 100644 --- a/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts +++ b/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts @@ -20,8 +20,6 @@ import { import { fetchDoc } from '../../../wizards/test-support.js'; import { Switch } from '@material/mwc-switch'; -import { WizardSelect } from '../../../../../src/wizard-select.js'; -import { WizardTextField } from '../../../../../src/wizard-textfield.js'; describe('Wizards for preparing 104 Address Creation', () => { let doc: XMLDocument; From 21148abe1dc057eddfa0a667967b02a38bebd703 Mon Sep 17 00:00:00 2001 From: Stef3st Date: Mon, 15 Jan 2024 11:42:42 +0100 Subject: [PATCH 7/8] chore: altered wizardtextfield casting Signed-off-by: Stef3st --- .../test/unit/editors/protocol104/wizards/address.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts b/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts index 6b2fe36521..42cac53297 100644 --- a/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts +++ b/packages/open-scd/test/unit/editors/protocol104/wizards/address.test.ts @@ -204,11 +204,11 @@ describe('Wizards for 104 Address Element', () => { ); }); it('should have mappedCmv translation value in helper field', async () => { - const cdc = element.wizardUI.dialog!.querySelector( + const cdc = element.wizardUI.dialog!.querySelector( 'wizard-textfield[label="cdc"]' - ) as WizardTextField; + ); expect(cdc).to.exist; - await expect(cdc.helper).to.equal('[protocol104.mappedCmv]'); + await expect(cdc!.helper).to.equal('[protocol104.mappedCmv]'); }); }); From fa31cf446b5a42867405e7c1363cadcc0ca6a05b Mon Sep 17 00:00:00 2001 From: Stef3st Date: Mon, 15 Jan 2024 13:04:27 +0100 Subject: [PATCH 8/8] chore: add wizard select import Signed-off-by: Stef3st --- .../unit/editors/protocol104/wizards/createAddresses.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts b/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts index 57f83086da..795f0f80c7 100644 --- a/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts +++ b/packages/open-scd/test/unit/editors/protocol104/wizards/createAddresses.test.ts @@ -10,6 +10,7 @@ import { WizardInputElement, } from '../../../../../src/foundation.js'; +import { WizardSelect } from '../../../../../src/wizard-select.js'; import { WizardTextField } from '../../../../../src/wizard-textfield.js'; import '../../../../mock-wizard.js'; @@ -160,7 +161,7 @@ describe('Wizards for preparing 104 Address Creation', () => { expect(monitorTi.maybeValue).to.equal('35'); }); }); - + describe('show prepare 104 Address creation with mapped cdc value', () => { beforeEach(async () => { await prepareWizard(