Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wizards/reportcontrol): add copy to other IEDs #632

Merged
merged 10 commits into from
Apr 1, 2022
89 changes: 89 additions & 0 deletions src/foundation/scl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { crossProduct } from '../foundation.js';

function getDataModelChildren(parent: Element): Element[] {
if (['LDevice', 'Server'].includes(parent.tagName))
return Array.from(parent.children).filter(
child =>
child.tagName === 'LDevice' ||
child.tagName === 'LN0' ||
child.tagName === 'LN'
);

const id =
parent.tagName === 'LN' || parent.tagName === 'LN0'
? parent.getAttribute('lnType')
: parent.getAttribute('type');

return Array.from(
parent.ownerDocument.querySelectorAll(
`LNodeType[id="${id}"] > DO, DOType[id="${id}"] > SDO, DOType[id="${id}"] > DA, DAType[id="${id}"] > BDA`
)
);
}

export function existFcdaReference(fcda: Element, ied: Element): boolean {
const [ldInst, prefix, lnClass, lnInst, doName, daName, fc] = [
'ldInst',
'prefix',
'lnClass',
'lnInst',
'doName',
'daName',
'fc',
].map(attr => fcda.getAttribute(attr));

const sinkLdInst = ied.querySelector(`LDevice[inst="${ldInst}"]`);
if (!sinkLdInst) return false;

const prefixSelctors = prefix
? [`[prefix="${prefix}"]`]
: ['[prefix=""]', ':not([prefix])'];
const lnInstSelectors = lnInst
? [`[inst="${lnInst}"]`]
: ['[inst=""]', ':not([inst])'];

const anyLnSelector = crossProduct(
['LN0', 'LN'],
prefixSelctors,
[`[lnClass="${lnClass}"]`],
lnInstSelectors
)
.map(strings => strings.join(''))
.join(',');

const sinkAnyLn = ied.querySelector(anyLnSelector);
if (!sinkAnyLn) return false;

const doNames = doName?.split('.');
if (!doNames) return false;

let parent: Element | undefined = sinkAnyLn;
for (const doNameAttr of doNames) {
parent = getDataModelChildren(parent).find(
child => child.getAttribute('name') === doNameAttr
);
if (!parent) return false;
}

const daNames = daName?.split('.');
const someFcInSink = getDataModelChildren(parent).some(
da => da.getAttribute('fc') === fc
);
if (!daNames && someFcInSink) return true;
if (!daNames) return false;

let sinkFc = '';
for (const daNameAttr of daNames) {
parent = getDataModelChildren(parent).find(
child => child.getAttribute('name') === daNameAttr
);

if (parent?.getAttribute('fc')) sinkFc = parent.getAttribute('fc')!;

if (!parent) return false;
}

if (sinkFc !== fc) return false;

return true;
}
22 changes: 16 additions & 6 deletions src/translations/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,28 +293,28 @@ export const de: Translations = {
subscription: {
none: 'Keine Verbindung vorhanden',
publisherGoose: {
title: 'GOOSE-Publizierer'
title: 'GOOSE-Publizierer',
},
subscriberIed: {
title: 'Verbunden mit {{ selected }}',
subscribed: 'Verbunden',
availableToSubscribe: 'Kann verbunden werden',
partiallySubscribed: 'Teilweise verbunden',
noGooseMessageSelected: 'Keine GOOSE ausgewählt'
}
noGooseMessageSelected: 'Keine GOOSE ausgewählt',
Flurb marked this conversation as resolved.
Show resolved Hide resolved
},
},
sampledvalues: {
none: 'Keine Verbindung vorhanden',
sampledValuesList: {
title: 'Sampled Values'
title: 'Sampled Values',
},
subscriberIed: {
title: 'Verbunden mit {{ selected }}',
subscribed: 'Verbunden',
availableToSubscribe: 'Kann verbunden werden',
partiallySubscribed: 'Teilweise verbunden',
noSampledValuesSelected: 'Keinen Kontrollblock ausgewählt'
}
noSampledValuesSelected: 'Keinen Kontrollblock ausgewählt',
},
},
'enum-val': {
wizard: {
Expand Down Expand Up @@ -526,6 +526,16 @@ export const de: Translations = {
remove:
'{{type}} "{{name}}" and referenzierte Element von IED {{iedName}} entfernt',
},
hints: {
source: 'Quell-IED',
missingServer: 'Kein Server vorhanden',
exist: '{{type}} mit dem Namen {{name}} existiert',
noMatchingData: 'Keine Datenübereinstimmung',
valid: 'Kann kopiert werden',
},
label: {
copy: 'Kopie in anderen IEDs ertellen',
},
},
add: 'Hinzufügen',
new: 'Neu',
Expand Down
23 changes: 16 additions & 7 deletions src/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,28 +289,28 @@ export const en = {
subscription: {
none: 'None',
publisherGoose: {
title: 'GOOSE publisher'
title: 'GOOSE publisher',
},
subscriberIed: {
title: 'Subscriber of {{ selected }}',
subscribed: 'Subscribed',
availableToSubscribe: 'Available to subscribe',
partiallySubscribed: 'Partially subscribed',
noGooseMessageSelected: 'No GOOSE message selected'
}
noGooseMessageSelected: 'No GOOSE message selected',
},
},
sampledvalues: {
none: 'none',
sampledValuesList: {
title: 'Sampled Values'
title: 'Sampled Values',
},
subscriberIed: {
title: 'Subscriber of {{ selected }}',
subscribed: 'Subscribed',
availableToSubscribe: 'Available to subscribe',
partiallySubscribed: 'Partially subscribed',
noSampledValuesSelected: 'No control block selected'
}
noSampledValuesSelected: 'No control block selected',
},
},
'enum-val': {
wizard: {
Expand Down Expand Up @@ -512,7 +512,8 @@ export const en = {
unreferencedDataSets: {
title: 'Unreferenced Datasets',
deleteButton: 'Remove Selected Datasets',
tooltip: 'Datasets without a reference to an associated GOOSE, Log, Report or Sampled Value Control Block'
tooltip:
'Datasets without a reference to an associated GOOSE, Log, Report or Sampled Value Control Block',
},
},
controlblock: {
Expand All @@ -521,6 +522,14 @@ export const en = {
remove:
'Removed {{type}} "{{name}}" and its referenced elements from IED {{iedName}}',
},
hints: {
source: 'Source IED',
missingServer: 'Not A Server',
exist: '{{type}} with name {{name}} already exist',
noMatchingData: 'No matching data',
valid: 'Can be copied',
},
label: { copy: 'Copy to other IEDs' },
},
add: 'Add',
new: 'New',
Expand Down
10 changes: 10 additions & 0 deletions src/wizards/foundation/finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ export function iEDPicker(doc: XMLDocument): TemplateResult {
></finder-list>`;
}

export function iEDsPicker(doc: XMLDocument): TemplateResult {
return html`<finder-list
multi
path="${JSON.stringify(['SCL: '])}"
.read=${getReader(doc.querySelector('SCL')!, getIED)}
danyill marked this conversation as resolved.
Show resolved Hide resolved
.getDisplayString=${getDisplayString}
.getTitle=${(path: string[]) => path[path.length - 1]}
></finder-list>`;
}

export function getDataModelChildren(parent: Element): Element[] {
if (['LDevice', 'Server'].includes(parent.tagName))
return Array.from(parent.children).filter(
Expand Down
Loading