Skip to content

Commit

Permalink
feat(editor/subscriber): Subscribe and unsubscribe for Subscriber Log…
Browse files Browse the repository at this point in the history
…ical Nodes (GOOSE/SMV) (openscd#1039)

* Added plugin and show FCDA Elements including edit button
* Added plugin and show FCDA Elements including edit button
* Added plugin and show FCDA Elements including edit button + renaming other subscriber plugins
* Fixed plugin test
* Show connected and available LN + small fixes
* First version of subscribe and unsubscribe
* Added test for subscribing and unsubscribing logica node binding
* Processed review comments.
* Review comments processed
* Fixed tests.
  • Loading branch information
Dennis Labordus authored Oct 13, 2022
1 parent 971f0c1 commit 1c55aed
Show file tree
Hide file tree
Showing 12 changed files with 492 additions and 30 deletions.
10 changes: 5 additions & 5 deletions src/editors/subscription/goose/subscriber-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
property,
TemplateResult,
} from 'lit-element';
import { translate } from 'lit-translate';
import { get, translate } from 'lit-translate';

import '@material/mwc-icon';
import '@material/mwc-list';
Expand All @@ -20,9 +20,9 @@ import {
newActionEvent,
} from '../../../foundation.js';
import {
newGooseSubscriptionEvent,
GOOSESelectEvent,
GooseSubscriptionEvent,
newGooseSubscriptionEvent,
} from './foundation.js';
import {
emptyInputsDeleteActions,
Expand Down Expand Up @@ -266,7 +266,7 @@ export class SubscriberList extends SubscriberListContainer {
});

/** If the IED doesn't have a Inputs element, just append it to the first LN0 element. */
const title = 'Connect';
const title = get('subscription.connect');
if (inputsElement.parentElement) {
this.dispatchEvent(newActionEvent({ title, actions }));
} else {
Expand Down Expand Up @@ -295,7 +295,7 @@ export class SubscriberList extends SubscriberListContainer {

this.dispatchEvent(
newActionEvent({
title: 'Disconnect',
title: get('subscription.disconnect'),
actions: actions,
})
);
Expand Down Expand Up @@ -413,7 +413,7 @@ export class SubscriberList extends SubscriberListContainer {
}

protected firstUpdated(): void {
this.currentSelectedIed = undefined
this.currentSelectedIed = undefined;
}

render(): TemplateResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,15 @@ export class ExtRefLaterBindingList extends LitElement {
*
* @param extRefElement - The Ext Ref Element to clean from attributes.
*/
private unsubscribe(extRefElement: Element): Replace {
private unsubscribe(extRefElement: Element): Replace | null {
if (
!this.currentIedElement ||
!this.currentSelectedFcdaElement ||
!this.currentSelectedControlElement!
) {
return null;
}

const clonedExtRefElement = cloneElement(extRefElement, {
iedName: null,
ldInst: null,
Expand Down Expand Up @@ -215,9 +223,10 @@ export class ExtRefLaterBindingList extends LitElement {
graphic="large"
twoline
@click=${() => {
this.dispatchEvent(
newActionEvent(this.unsubscribe(extRefElement))
);
const replaceAction = this.unsubscribe(extRefElement);
if (replaceAction) {
this.dispatchEvent(newActionEvent(replaceAction));
}
}}
value="${identity(extRefElement)}"
>
Expand Down
98 changes: 95 additions & 3 deletions src/editors/subscription/later-binding/ext-ref-ln-binding-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,31 @@ import {
state,
TemplateResult,
} from 'lit-element';
import { translate } from 'lit-translate';
import { get, translate } from 'lit-translate';

import { identity } from '../../../foundation.js';
import {
ComplexAction,
Create,
createElement,
Delete,
identity,
newActionEvent,
} from '../../../foundation.js';
import { Nsdoc } from '../../../foundation/nsdoc.js';

import { FcdaSelectEvent, serviceTypes, styles } from '../foundation.js';
import {
canCreateValidExtRef,
createExtRefElement,
existExtRef,
FcdaSelectEvent,
serviceTypes,
styles,
} from '../foundation.js';
import { isSubscribedTo } from './foundation.js';
import {
emptyInputsDeleteActions,
getFcdaReferences,
} from '../../../foundation/ied.js';

/**
* A sub element for showing all Ext Refs from a FCDA Element.
Expand Down Expand Up @@ -106,6 +124,68 @@ export class ExtRefLnBindingList extends LitElement {
: undefined;
}

private subscribe(lnElement: Element): ComplexAction | null {
if (
!this.currentIedElement ||
!this.currentSelectedFcdaElement ||
!this.currentSelectedControlElement!
) {
return null;
}

const actions: Create[] = [];
let inputsElement = lnElement.querySelector(':scope > Inputs');
if (!inputsElement) {
inputsElement = createElement(lnElement.ownerDocument, 'Inputs', {});
actions.push({ new: { parent: lnElement, element: inputsElement } });
}

if (
!existExtRef(inputsElement!, this.currentSelectedFcdaElement) &&
canCreateValidExtRef(
this.currentSelectedFcdaElement,
this.currentSelectedControlElement
)
) {
const extRef = createExtRefElement(
this.currentSelectedControlElement,
this.currentSelectedFcdaElement
);
actions.push({ new: { parent: inputsElement, element: extRef } });
}

const title = get('subscription.connect');
return { title, actions };
}

private unsubscribe(lnElement: Element): ComplexAction | null {
if (
!this.currentIedElement ||
!this.currentSelectedFcdaElement ||
!this.currentSelectedControlElement!
) {
return null;
}

const actions: Delete[] = [];
const inputElement = lnElement.querySelector(':scope > Inputs')!;
const extRefElement = inputElement.querySelector(
`ExtRef[iedName=${this.currentIedElement.getAttribute('name')}]` +
`${getFcdaReferences(this.currentSelectedFcdaElement)}`
);
if (extRefElement) {
actions.push({ old: { parent: inputElement, element: extRefElement } });
}

// Check if empty Input Element should also be removed.
actions.push(...emptyInputsDeleteActions(actions));

return {
title: get('subscription.disconnect'),
actions: actions,
};
}

private bindingNotSupported(lnElement: Element): boolean {
const iedElement = lnElement.closest('IED')!;
return (
Expand Down Expand Up @@ -156,6 +236,12 @@ export class ExtRefLnBindingList extends LitElement {
?disabled=${this.bindingNotSupported(lnElement)}
twoline
value="${identity(lnElement)}"
@click=${() => {
const replaceAction = this.unsubscribe(lnElement);
if (replaceAction) {
this.dispatchEvent(newActionEvent(replaceAction));
}
}}
>
<span>${this.buildLNTitle(lnElement)}</span>
<span slot="secondary">
Expand Down Expand Up @@ -196,6 +282,12 @@ export class ExtRefLnBindingList extends LitElement {
?disabled=${this.bindingNotSupported(lnElement)}
twoline
value="${identity(lnElement)}"
@click=${() => {
const replaceAction = this.subscribe(lnElement);
if (replaceAction) {
this.dispatchEvent(newActionEvent(replaceAction));
}
}}
>
<span>${this.buildLNTitle(lnElement)}</span>
<span slot="secondary">
Expand Down
8 changes: 4 additions & 4 deletions src/editors/subscription/sampledvalues/subscriber-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
property,
TemplateResult,
} from 'lit-element';
import { translate } from 'lit-translate';
import { get, translate } from 'lit-translate';

import '@material/mwc-icon';
import '@material/mwc-list';
Expand Down Expand Up @@ -268,7 +268,7 @@ export class SubscriberList extends SubscriberListContainer {
});

/** If the IED doesn't have a Inputs element, just append it to the first LN0 element. */
const title = 'Connect';
const title = get('subscription.connect');
if (inputsElement.parentElement)
this.dispatchEvent(newActionEvent({ title, actions }));
else {
Expand Down Expand Up @@ -297,7 +297,7 @@ export class SubscriberList extends SubscriberListContainer {

this.dispatchEvent(
newActionEvent({
title: 'Disconnect',
title: get('subscription.disconnect'),
actions: actions,
})
);
Expand Down Expand Up @@ -415,7 +415,7 @@ export class SubscriberList extends SubscriberListContainer {
}

protected firstUpdated(): void {
this.currentSelectedIed = undefined
this.currentSelectedIed = undefined;
}

render(): TemplateResult {
Expand Down
2 changes: 2 additions & 0 deletions src/translations/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ export const de: Translations = {
},
subscription: {
none: 'Keine Verbindung vorhanden',
connect: 'Daten-Attribut verbunden',
disconnect: 'Daten-Attribute Verbindung gelöst',
subscriber: {
subscribed: 'Verbunden',
availableToSubscribe: 'Kann verbunden werden',
Expand Down
2 changes: 2 additions & 0 deletions src/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ export const en = {
},
subscription: {
none: 'None',
connect: 'Connect data attribute',
disconnect: 'Disconnect data attribute',
subscriber: {
subscribed: 'Subscribed',
availableToSubscribe: 'Available to subscribe',
Expand Down
Loading

0 comments on commit 1c55aed

Please sign in to comment.