Skip to content

Commit

Permalink
feat(104): implement wye and del cdc support (#1390)
Browse files Browse the repository at this point in the history
* feat: implement wye and del cdc support

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

* chore: add description for mapping to cmv

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

* chore: added tests

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

* chore: add descriptive texts for cdc mapping

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

* chore: remove console.log

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

* chore: removed duplicate import

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

* chore: altered wizardtextfield casting

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

* chore: add wizard select import

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>

---------

Signed-off-by: Stef3st <steffen.van.den.driest@alliander.com>
Co-authored-by: Juan Munoz <juan.munoz@alliander.com>
  • Loading branch information
Stef3st and juancho0202 authored Jan 29, 2024
1 parent c0972f3 commit 43b8285
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 17 deletions.
68 changes: 63 additions & 5 deletions packages/open-scd/src/editors/protocol104/foundation/cdc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const supportedCdcTypes = [
'BCR',
'BSC',
'CMV',
'DEL',
'DPC',
'DPS',
'ENC',
Expand All @@ -51,6 +52,7 @@ export const supportedCdcTypes = [
'SPC',
'SPG',
'SPS',
'WYE',
] as const;
export type SupportedCdcType = (typeof supportedCdcTypes)[number];

Expand Down Expand Up @@ -231,6 +233,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': {
Expand Down Expand Up @@ -442,6 +467,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: {},
},
};

/**
Expand Down Expand Up @@ -758,19 +806,29 @@ 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}"]`
);
// 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;
Expand Down
18 changes: 15 additions & 3 deletions packages/open-scd/src/editors/protocol104/wizards/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')!)!;
Expand Down Expand Up @@ -103,7 +104,9 @@ export function editAddressWizard(
addressElement: Element
): Wizard {
function renderAddressWizard(): TemplateResult[] {
const cdc = getCdcValueFromDOIElement(doiElement) ?? '';
const foundCdc = getCdcValueFromDOIElement(doiElement) ?? '';
const reqCmvMapping = foundCdc === 'WYE' || foundCdc === 'DEL';
const cdc = reqCmvMapping ? 'CMV' : foundCdc;
const ti = addressElement.getAttribute('ti') ?? '';

let casdu = addressElement.getAttribute('casdu') ?? '';
Expand Down Expand Up @@ -143,7 +146,16 @@ export function editAddressWizard(
disabled
>
</mwc-textarea>`,
html`<wizard-textfield label="cdc" .maybeValue="${cdc}" disabled readonly>
html`<wizard-textfield
label="cdc"
.maybeValue="${cdc}"
.helper="${reqCmvMapping
? translate('protocol104.mappedCmv', { cdc: foundCdc })
: ''}"
.helperPersistent="${reqCmvMapping}"
disabled
readonly
>
</wizard-textfield>`,
html`<mwc-textarea
label="DAI"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,10 @@ export function createAddressesWizard(
lnElement: Element,
doElement: Element
): Wizard {
const cdc = getCdcValueFromDOElement(doElement) ?? '';
const cdcProcessing = cdcProcessings[<SupportedCdcType>cdc];
const foundCdc = getCdcValueFromDOElement(doElement) ?? '';
const reqCmvMapping = foundCdc === 'WYE' || foundCdc === 'DEL';
const cdc = reqCmvMapping ? 'CMV' : foundCdc;
const cdcProcessing = cdcProcessings[<SupportedCdcType>foundCdc];

const monitorTis = Object.keys(cdcProcessing.monitor);
const controlTis = Object.keys(cdcProcessing.control);
Expand Down Expand Up @@ -261,7 +263,11 @@ export function createAddressesWizard(
</wizard-textfield>`,
html`<wizard-textfield
label="Common Data Class"
.maybeValue=${cdc}
.maybeValue="${cdc}"
.helper="${reqCmvMapping
? translate('protocol104.mappedCmv', { cdc: foundCdc })
: ''}"
.helperPersistent="${reqCmvMapping}"
disabled
readonly
>
Expand Down
3 changes: 2 additions & 1 deletion packages/open-scd/src/editors/protocol104/wizards/doi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [
Expand Down
2 changes: 2 additions & 0 deletions packages/open-scd/src/translations/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,8 @@ export const de: Translations = {
valuesView: 'Werte',
networkView: 'Netzwerk',
},
mappedCmv:
'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',
Expand Down
2 changes: 2 additions & 0 deletions packages/open-scd/src/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ export const en = {
valuesView: 'Values',
networkView: 'Network',
},
mappedCmv:
'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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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 in helper field', async () => {
const cdc = element.wizardUI.dialog!.querySelector<WizardTextField>(
'wizard-textfield[label="cdc"]'
);
expect(cdc).to.exist;
await expect(cdc!.helper).to.equal('[protocol104.mappedCmv]');
});
});

describe('edit 104 Address with inverted value', () => {
beforeEach(async () => {
await prepareWizard(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
WizardInputElement,
} from '../../../../../src/foundation.js';

import { WizardSelect } from '../../../../../src/wizard-select.js';
import { WizardTextField } from '../../../../../src/wizard-textfield.js';
import '../../../../mock-wizard.js';

import {
Expand All @@ -19,8 +21,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;
Expand Down Expand Up @@ -162,6 +162,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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 43b8285

Please sign in to comment.