diff --git a/src/Setting.ts b/src/Setting.ts index 5cf7f2b66..e190c0aa5 100644 --- a/src/Setting.ts +++ b/src/Setting.ts @@ -18,6 +18,8 @@ import { Language, languages, loader } from './translations/loader.js'; import './WizardDivider.js'; import { WizardDialog } from './wizard-dialog.js'; +import { iec6185072, iec6185073, iec6185074, iec6185081 } from "./validators/templates/foundation.js"; + export type Settings = { language: Language; theme: 'light' | 'dark'; @@ -39,6 +41,19 @@ export const defaults: Settings = { 'IEC 61850-8-1': undefined }; +type NsdVersion = { + version: string | undefined, + revision: string | undefined, + release: string | undefined +} + +type NsdVersions = { + 'IEC 61850-7-2': NsdVersion; + 'IEC 61850-7-3': NsdVersion; + 'IEC 61850-7-4': NsdVersion; + 'IEC 61850-8-1': NsdVersion; +} + /** Mixin that saves [[`Settings`]] to `localStorage`, reflecting them in the * `settings` property, setting them through `setSetting(setting, value)`. */ export type SettingElement = Mixin; @@ -60,6 +75,38 @@ export function Setting(Base: TBase) { }; } + /** + * Get the versions of the current OpenSCD NSD files. + * @returns Current version, revision and release for all current OpenSCD NSD files. + */ + private async nsdVersions(): Promise { + const [nsd72, nsd73, nsd74, nsd81] = await Promise.all([iec6185072, iec6185073, iec6185074, iec6185081]); + const [nsd72Ns, nsd73Ns, nsd74Ns, nsd81Ns] = [nsd72.querySelector('NS'), nsd73.querySelector('NS'), nsd74.querySelector('NS'), nsd81.querySelector('ServiceNS')]; + + return { + 'IEC 61850-7-2': { + version: nsd72Ns?.getAttribute('version') ?? undefined, + revision: nsd72Ns?.getAttribute('revision') ?? undefined, + release: nsd72Ns?.getAttribute('release') ?? undefined, + }, + 'IEC 61850-7-3': { + version: nsd73Ns?.getAttribute('version') ?? undefined, + revision: nsd73Ns?.getAttribute('revision') ?? undefined, + release: nsd73Ns?.getAttribute('release') ?? undefined, + }, + 'IEC 61850-7-4': { + version: nsd74Ns?.getAttribute('version') ?? undefined, + revision: nsd74Ns?.getAttribute('revision') ?? undefined, + release: nsd74Ns?.getAttribute('release') ?? undefined, + }, + 'IEC 61850-8-1': { + version: nsd81Ns?.getAttribute('version') ?? undefined, + revision: nsd81Ns?.getAttribute('revision') ?? undefined, + release: nsd81Ns?.getAttribute('release') ?? undefined, + } + } + } + @query('#settings') settingsUI!: Dialog; @query('#language') @@ -133,6 +180,7 @@ export function Setting(Base: TBase) { } private async loadNsdocFile(evt: Event): Promise { + const nsdVersions = await this.nsdVersions(); const files = Array.from( (evt.target)?.files ?? [] ); @@ -140,7 +188,8 @@ export function Setting(Base: TBase) { if (files.length == 0) return; files.forEach(async file => { const text = await file.text(); - const id = this.parseToXmlObject(text).querySelector('NSDoc')?.getAttribute('id'); + const nsdocElement = this.parseToXmlObject(text).querySelector('NSDoc'); + const id = nsdocElement?.getAttribute('id'); if (!id) { document .querySelector('open-scd')! @@ -149,6 +198,25 @@ export function Setting(Base: TBase) { ); return; } + const nsdVersion = nsdVersions[id as keyof NsdVersions]; + const nsdocVersion = { + version: nsdocElement!.getAttribute('version') ?? undefined, + revision: nsdocElement!.getAttribute('revision') ?? undefined, + release: nsdocElement!.getAttribute('release') ?? undefined + } + + if (!this.isEqual(nsdVersion, nsdocVersion)) { + document + .querySelector('open-scd')! + .dispatchEvent( + newLogEvent({ kind: 'error', title: get('settings.invalidNsdocVersion', { + id: id, + nsdVersion: `${nsdVersion.version}${nsdVersion.revision}${nsdVersion.release}`, + nsdocVersion: `${nsdocVersion.version}${nsdocVersion.revision}${nsdocVersion.release}` + }) }) + ); + return; + } this.setSetting(id as keyof Settings, text); }) @@ -157,6 +225,16 @@ export function Setting(Base: TBase) { this.requestUpdate(); } + /** + * Check the equality of two NsdVersions. + * @param versionA - First version to compare. + * @param versionB - Second version to compare. + * @returns Are they equal or not. + */ + private isEqual(versionA: NsdVersion, versionB: NsdVersion): boolean { + return versionA.version == versionB.version && versionA.revision == versionB.revision && versionA.release == versionB.release; + } + /** * Render one .nsdoc item in the Settings wizard * @param key - The key of the nsdoc file in the settings. diff --git a/src/translations/de.ts b/src/translations/de.ts index c2d17f67c..217a46839 100644 --- a/src/translations/de.ts +++ b/src/translations/de.ts @@ -50,7 +50,8 @@ export const de: Translations = { showieds: 'Zeige IEDs im Substation-Editor', selectFileButton: 'Datei auswählen', loadNsdTranslations: 'NSDoc-Dateien hochladen', - invalidFileNoIdFound: 'Ungültiges NSDoc; kein \'id\'-Attribut in der Datei gefunden' + invalidFileNoIdFound: 'Ungültiges NSDoc; kein \'id\'-Attribut in der Datei gefunden', + invalidNsdocVersion: '???' }, menu: { new: 'Neues projekt', diff --git a/src/translations/en.ts b/src/translations/en.ts index db79dd4e1..bc86ea5f7 100644 --- a/src/translations/en.ts +++ b/src/translations/en.ts @@ -48,7 +48,8 @@ export const en = { showieds: 'Show IEDs in substation editor', selectFileButton: 'Select file', loadNsdTranslations: 'Uploading NSDoc files', - invalidFileNoIdFound: 'Invalid NSDoc; no \'id\' attribute found in file' + invalidFileNoIdFound: 'Invalid NSDoc; no \'id\' attribute found in file', + invalidNsdocVersion: 'The version of {{ id }} NSD ({{ nsdVersion }}) does not correlate with the version of the corresponding NSDoc ({{ nsdocVersion }})' }, menu: { new: 'New project',