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(plugins/Subscription): Create 'Subscription' plugin for GOOSE subscriptions #549

Merged
merged 33 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
562f7ba
Added Subscription ABB plugin
Flurb Feb 15, 2022
2796596
Fix test
Flurb Feb 15, 2022
a611c2f
Added Published GOOSE messages
Flurb Feb 15, 2022
93867d6
First version
Flurb Feb 17, 2022
e313166
Added more fancy UI
Flurb Feb 17, 2022
76a71bf
Refactor
Flurb Feb 17, 2022
cbe324c
Added IED icon
Flurb Feb 20, 2022
c483d2f
Added 3rd group for partially subscribed IEDs
Flurb Feb 21, 2022
eee4738
Small refactoring
Flurb Feb 21, 2022
9492214
Small refactoring
Flurb Feb 21, 2022
2b1af8f
Refactoring
Flurb Feb 21, 2022
44a7274
Added goose message unit test
Flurb Feb 21, 2022
f114ee9
Added unit tests
Flurb Feb 21, 2022
ace3abb
Refactoring
Flurb Feb 22, 2022
d8012fe
Fixing unit test
Flurb Feb 22, 2022
ee8f02e
Merge branch 'main' into subscriber-plugin
Flurb Feb 22, 2022
6db5c50
Merge branch 'main' into subscriber-plugin
Flurb Feb 22, 2022
e1d63f7
Bugfix
Flurb Feb 23, 2022
11e0856
Another bug fix
Flurb Feb 23, 2022
34d8f64
Made both lists scrollable
Flurb Feb 23, 2022
969a6d2
Review comments
Flurb Feb 24, 2022
739a6fc
Review comments
Flurb Feb 24, 2022
3138936
Review comments
Flurb Feb 24, 2022
7910be6
Review comments
Flurb Feb 24, 2022
3270b66
Fixing tests
Flurb Feb 24, 2022
240a076
Adjusted styling
Flurb Feb 24, 2022
74a405a
Small refactoring
Flurb Feb 25, 2022
e65ee85
Added German translations
Flurb Feb 28, 2022
9074b43
Review comments
Flurb Feb 28, 2022
d24117c
Review comments
Flurb Mar 4, 2022
adf73bf
Renaming
Flurb Mar 4, 2022
204e6bb
feat(plugins/Subscription): Manage GOOSE service connections (#569)
Flurb Mar 17, 2022
66b3674
Merge with main
Flurb Mar 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions public/js/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ export const officialPlugins = [
default: false,
kind: 'editor',
},
{
name: 'Subscription',
src: '/src/editors/Subscription.js',
icon: 'link',
default: true,
kind: 'editor',
},
{
name: 'Sampled Values Subscriber',
src: '/src/editors/SampledValues.js',
Expand Down
4 changes: 2 additions & 2 deletions src/editors/SampledValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { LitElement, html, TemplateResult, property, css } from 'lit-element';

import '@material/mwc-fab';

import './sampledvalues/subscriber-ied-list.js';
import './sampledvalues/subscriber-ied-list-smv.js';
import './sampledvalues/sampled-values-list.js';

/** An editor [[`plugin`]] for subscribing IEDs to Sampled Values. */
Expand All @@ -18,7 +18,7 @@ export default class SampledValuesPlugin extends LitElement {
<sampled-values-list .doc=${this.doc}></sampled-values-list>
</section>
<section>
<subscriber-ied-list .doc=${this.doc}></subscriber-ied-list>
<subscriber-ied-list-smv .doc=${this.doc}></subscriber-ied-list-smv>
</section>
</div>`;
}
Expand Down
49 changes: 49 additions & 0 deletions src/editors/Subscription.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { LitElement, html, TemplateResult, property, css } from 'lit-element';

import '@material/mwc-fab';

import './subscription/subscriber-ied-list-goose.js';
import './subscription/publisher-goose-list.js';

/** An editor [[`plugin`]] for subscribing IEDs to GOOSE messages using the ABB subscription method. */
export default class SubscriptionABBPlugin extends LitElement {
Flurb marked this conversation as resolved.
Show resolved Hide resolved
/** The document being edited as provided to plugins by [[`OpenSCD`]]. */
@property()
doc!: XMLDocument;

render(): TemplateResult {
return html`
<div id="containerTemplates">
<section>
<publisher-goose-list .doc=${this.doc}></publisher-goose-list>
</section>
<section>
<subscriber-ied-list-goose .doc=${this.doc}></subscriber-ied-list-goose>
</section>
</div>`;
}

static styles = css`
:host {
width: 100vw;
}

section {
width: 49vw;
}

#containerTemplates {
display: grid;
grid-gap: 12px;
padding: 8px 12px 16px;
box-sizing: border-box;
grid-template-columns: repeat(auto-fit, minmax(316px, auto));
}

@media (max-width: 387px) {
#containerTemplates {
grid-template-columns: repeat(auto-fit, minmax(196px, auto));
}
}
`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import '@material/mwc-list/mwc-list-item';

import { newIEDSampledValuesSubscriptionEvent, SubscribeStatus } from '../foundation.js';

@customElement('ied-element')
export class IEDElement extends LitElement {
@customElement('ied-element-smv')
export class IEDElementSmv extends LitElement {
/** Holding the IED element */
@property({ attribute: false })
element!: Element;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import '@material/mwc-icon';
import '@material/mwc-list';
import '@material/mwc-list/mwc-list-item';

import './elements/ied-element.js';
import './elements/ied-element-smv.js';
import {
Create,
createElement,
Expand Down Expand Up @@ -97,8 +97,8 @@ const localState: State = {
};

/** An sub element for subscribing and unsubscribing IEDs to Sampled Values messages. */
@customElement('subscriber-ied-list')
export class SubscriberIEDList extends LitElement {
@customElement('subscriber-ied-list-smv')
export class SubscriberIEDListSmv extends LitElement {
@property({ attribute: false })
doc!: XMLDocument;

Expand Down Expand Up @@ -128,6 +128,7 @@ export class SubscriberIEDList extends LitElement {
* @param event - Incoming event.
*/
private async onSampledValuesDataSetEvent(event: SampledValuesSelectEvent) {
console.log('onSMVSelect')
localState.currentSampledValuesControl = event.detail.sampledValuesControl;
localState.currentDataset = event.detail.dataset;
localState.currentSampledValuesIEDName = localState.currentSampledValuesControl
Expand Down Expand Up @@ -195,6 +196,7 @@ export class SubscriberIEDList extends LitElement {
* @param event - Incoming event.
*/
private async onIEDSubscriptionEvent(event: IEDSampledValuesSubscriptionEvent) {
console.log('onSMVIEDSub')
switch (event.detail.subscribeStatus) {
case SubscribeStatus.Full: {
this.unsubscribe(event.detail.ied);
Expand Down Expand Up @@ -377,10 +379,10 @@ export class SubscriberIEDList extends LitElement {
${localState.subscribedIeds.length > 0
? localState.subscribedIeds.map(
ied =>
html`<ied-element
html`<ied-element-smv
.status=${SubscribeStatus.Full}
.element=${ied.element}
></ied-element>`
></ied-element-smv>`
)
: html`<mwc-list-item graphic="avatar" noninteractive>
<span>${translate('sampledvalues.none')}</span>
Expand All @@ -398,10 +400,10 @@ export class SubscriberIEDList extends LitElement {
${partialSubscribedIeds.length > 0
? partialSubscribedIeds.map(
ied =>
html`<ied-element
html`<ied-element-smv
.status=${SubscribeStatus.Partial}
.element=${ied.element}
></ied-element>`
></ied-element-smv>`
)
: html`<mwc-list-item graphic="avatar" noninteractive>
<span>${translate('sampledvalues.none')}</span>
Expand All @@ -419,10 +421,10 @@ export class SubscriberIEDList extends LitElement {
${availableIeds.length > 0
? availableIeds.map(
ied =>
html`<ied-element
html`<ied-element-smv
.status=${SubscribeStatus.None}
.element=${ied.element}
></ied-element>`
></ied-element-smv>`
)
: html`<mwc-list-item graphic="avatar" noninteractive>
<span>${translate('sampledvalues.none')}</span>
Expand Down
35 changes: 35 additions & 0 deletions src/editors/subscription/elements/goose-message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
customElement,
html,
LitElement,
property,
TemplateResult,
} from 'lit-element';

import '@material/mwc-icon';
import '@material/mwc-list/mwc-list-item';

import { newGOOSESelectEvent } from '../foundation.js';
import { gooseIcon } from '../../../icons/icons.js';

@customElement('goose-message')
export class GOOSEMessage extends LitElement {
/** Holding the GSEControl element */
@property({ attribute: false })
element!: Element;

private onGooseSelect = () => {
const ln = this.element.parentElement;
const dataset = ln?.querySelector(
`DataSet[name=${this.element.getAttribute('datSet')}]`
);
this.dispatchEvent(newGOOSESelectEvent(this.element, dataset!));
};

render(): TemplateResult {
return html`<mwc-list-item @click=${this.onGooseSelect} graphic="large">
<span>${this.element.getAttribute('name')}</span>
<mwc-icon slot="graphic">${gooseIcon}</mwc-icon>
</mwc-list-item>`;
}
}
43 changes: 43 additions & 0 deletions src/editors/subscription/elements/ied-element-goose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
customElement,
html,
LitElement,
property,
TemplateResult,
} from 'lit-element';

import '@material/mwc-icon';
import '@material/mwc-list/mwc-list-item';

import { newIEDSubscriptionEvent, SubscribeStatus } from '../foundation.js';

@customElement('ied-element-goose')
export class IEDElementGoose extends LitElement {
/** Holding the IED element */
@property({ attribute: false })
element!: Element;

@property({ attribute: false })
status!: SubscribeStatus;

private onIedSelect = () => {
this.dispatchEvent(
newIEDSubscriptionEvent(this.element, this.status ?? SubscribeStatus.None)
);
};

render(): TemplateResult {
return html`<mwc-list-item
@click=${this.onIedSelect}
graphic="avatar"
hasMeta
>
<span>${this.element.getAttribute('name')}</span>
<mwc-icon slot="graphic"
>${this.status == SubscribeStatus.Full
? html`clear`
: html`add`}</mwc-icon
>
</mwc-list-item>`;
}
}
115 changes: 115 additions & 0 deletions src/editors/subscription/foundation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { css } from 'lit-element';

/**
* Enumeration stating the Subscribe status of a IED to a GOOSE.
*/
export enum SubscribeStatus {
Full,
Partial,
None,
}

export interface GOOSESelectDetail {
gseControl: Element;
dataset: Element;
}
export type GOOSESelectEvent = CustomEvent<GOOSESelectDetail>;
export function newGOOSESelectEvent(
gseControl: Element,
dataset: Element,
eventInitDict?: CustomEventInit<GOOSESelectDetail>
): GOOSESelectEvent {
return new CustomEvent<GOOSESelectDetail>('goose-dataset', {
bubbles: true,
composed: true,
...eventInitDict,
detail: { gseControl, dataset, ...eventInitDict?.detail },
});
}

export interface IEDSubscriptionDetail {
element: Element;
subscribeStatus: SubscribeStatus;
}
export type IEDSubscriptionEvent = CustomEvent<IEDSubscriptionDetail>;
export function newIEDSubscriptionEvent(
element: Element,
subscribeStatus: SubscribeStatus
): IEDSubscriptionEvent {
return new CustomEvent<IEDSubscriptionDetail>('ied-subscription', {
bubbles: true,
composed: true,
detail: { element, subscribeStatus },
});
}

/** Common `CSS` styles used by DataTypeTemplate subeditors */
export const styles = css`
:host(.moving) section {
opacity: 0.3;
}

section {
background-color: var(--mdc-theme-surface);
transition: all 200ms linear;
outline-color: var(--mdc-theme-primary);
outline-style: solid;
outline-width: 0px;
opacity: 1;
}

section:focus {
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
}

section:focus-within {
outline-width: 2px;
transition: all 250ms linear;
}

h1,
h2,
h3 {
color: var(--mdc-theme-on-surface);
font-family: 'Roboto', sans-serif;
font-weight: 300;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin: 0px;
line-height: 48px;
padding-left: 0.3em;
transition: background-color 150ms linear;
}

section:focus-within > h1,
section:focus-within > h2,
section:focus-within > h3 {
color: var(--mdc-theme-surface);
background-color: var(--mdc-theme-primary);
transition: background-color 200ms linear;
}

h1 > nav,
h2 > nav,
h3 > nav,
h1 > abbr > mwc-icon-button,
h2 > abbr > mwc-icon-button,
h3 > abbr > mwc-icon-button {
float: right;
}

abbr[title] {
border-bottom: none !important;
cursor: inherit !important;
text-decoration: none !important;
}
`;

declare global {
interface ElementEventMap {
['goose-dataset']: GOOSESelectEvent;
['ied-subscription']: IEDSubscriptionEvent;
}
}
Loading