Skip to content

Commit 0571329

Browse files
committed
feat: add IEC 61850 code components and NSD/NSDOC loading
1 parent 0f09072 commit 0571329

12 files changed

Lines changed: 438 additions & 604 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"IEC61850_code_components": {
3+
"Edition_1": {},
4+
"Edition_2": {},
5+
"Edition_2_1": {
6+
"7-2": {
7+
"NSD": "IEC_61850-7-2_2007B5.nsd",
8+
"NSDOC": "IEC_61850-7-2_2007B5-en.nsdoc"
9+
},
10+
"7-3": {
11+
"NSD": "IEC_61850-7-3_2007B5.nsd",
12+
"NSDOC": "IEC_61850-7-3_2007B5-en.nsdoc"
13+
},
14+
"7-4": {
15+
"NSD": "IEC_61850-7-4_2007B5.nsd",
16+
"NSDOC": "IEC_61850-7-4_2007B5-en.nsdoc"
17+
},
18+
"8-1": {
19+
"NSD": "IEC_61850-8-1_2003A2.nsd",
20+
"NSDOC": "IEC_61850-8-1_2003A2-en.nsdoc"
21+
}
22+
}
23+
}
24+
}

packages/compas-open-scd/src/addons/CompasSession.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import '../compas/CompasSessionExpiredDialog.js';
1616
import type { CompasSessionExpiringDialogElement } from '../compas/CompasSessionExpiringDialog.js';
1717
import type { CompasSessionExpiredDialogElement } from '../compas/CompasSessionExpiredDialog.js';
1818

19-
import { loadNsdocFiles } from '../compas/CompasNsdoc.js';
2019
import { retrieveUserInfo } from '../compas/CompasUserInfo.js';
20+
import { loadCodeComponentsJson } from '../compas-services/CompasCodeComponentsService.js';
2121

2222
/** Event to handle the Session Expire Timers value */
2323
export interface SetSessionTimeoutsDetail {
@@ -132,10 +132,13 @@ export class CompasSession extends LitElement {
132132
retrieveUserInfo(this).finally(() =>
133133
console.info('User info retrieved from CoMPAS')
134134
);
135-
// And we will start loading the Nsdoc Files from the Compas Backend Service.
136-
loadNsdocFiles(this).finally(() =>
137-
console.info('Nsdoc Files loaded from CoMPAS')
138-
);
135+
// Pre-fetch the code components JSON so it is cached before any project is opened.
136+
// Edition-specific NSD/NSDOC loading is triggered in open-scd.ts when a document is opened.
137+
loadCodeComponentsJson(this).then(components => {
138+
if (components) {
139+
console.info('IEC61850 code components JSON loaded.');
140+
}
141+
});
139142
});
140143
}
141144

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { get } from 'lit-translate';
2+
import { newLogEvent } from '@compas-oscd/core';
3+
4+
export type IEC61850Edition = 'Edition_1' | 'Edition_2' | 'Edition_2_1';
5+
6+
export interface CodeComponentEntry {
7+
NSD: string;
8+
NSDOC: string;
9+
}
10+
11+
export type EditionComponents = Partial<Record<string, CodeComponentEntry>>;
12+
13+
interface CodeComponentsJson {
14+
IEC61850_code_components: Partial<Record<IEC61850Edition, EditionComponents>>;
15+
}
16+
17+
const CODE_COMPONENTS_PATH = 'public/xml/IEC61850_code_components.json';
18+
19+
let cachedComponents: CodeComponentsJson | null = null;
20+
21+
/**
22+
* Fetches and caches the IEC61850_code_components.json file.
23+
*
24+
* The file is served from `public/xml/`. At deploy time the private repo
25+
* overwrites the bundled baseline with the latest version — so this is always
26+
* a single fetch against one location.
27+
*
28+
* Dispatches an error log event on the given element if the file cannot be
29+
* fetched or parsed.
30+
*
31+
* @param element - Element used for dispatching error log events.
32+
* @returns The parsed JSON, or null on failure.
33+
*/
34+
export async function loadCodeComponentsJson(
35+
element: Element
36+
): Promise<CodeComponentsJson | null> {
37+
if (cachedComponents !== null) {
38+
return cachedComponents;
39+
}
40+
41+
try {
42+
const response = await fetch(CODE_COMPONENTS_PATH);
43+
if (!response.ok) {
44+
dispatchCodeComponentsError(
45+
element,
46+
CODE_COMPONENTS_PATH,
47+
response.status
48+
);
49+
return null;
50+
}
51+
const json = (await response.json()) as CodeComponentsJson;
52+
cachedComponents = json;
53+
return json;
54+
} catch (err) {
55+
console.warn('Failed to fetch IEC61850 code components JSON:', err);
56+
dispatchCodeComponentsError(element, CODE_COMPONENTS_PATH);
57+
return null;
58+
}
59+
}
60+
61+
/**
62+
* Returns the code component file entries (NSD + NSDOC filenames) for the
63+
* given IEC 61850 edition, or null if the JSON hasn't been loaded or the
64+
* edition is not yet populated.
65+
*
66+
* @param components - The parsed code components JSON.
67+
* @param edition - The edition key to look up.
68+
*/
69+
export function getEditionComponents(
70+
components: CodeComponentsJson,
71+
edition: IEC61850Edition
72+
): EditionComponents | null {
73+
const editionData = components.IEC61850_code_components[edition];
74+
if (!editionData || Object.keys(editionData).length === 0) {
75+
return null;
76+
}
77+
return editionData;
78+
}
79+
80+
function dispatchCodeComponentsError(
81+
element: Element,
82+
path: string,
83+
status?: number
84+
): void {
85+
const detail = get('compas.codeComponents.errorDetails', {
86+
path,
87+
status: status === undefined ? 'network error' : String(status),
88+
});
89+
90+
element.dispatchEvent(
91+
newLogEvent({
92+
kind: 'error',
93+
title: get('compas.codeComponents.error'),
94+
message: detail,
95+
})
96+
);
97+
}

0 commit comments

Comments
 (0)