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

Improve ExtRef identity function #1179

Closed
danyill opened this issue Feb 20, 2023 · 1 comment · Fixed by #1182
Closed

Improve ExtRef identity function #1179

danyill opened this issue Feb 20, 2023 · 1 comment · Fixed by #1182
Labels

Comments

@danyill
Copy link
Collaborator

danyill commented Feb 20, 2023

Describe the bug

Currently the ExtRef identity function is not stable for the case of:

  • An ExtRef is specified for later binding with an internal address
  • A subscription is made

If an IED has an ExtRef and an internal address and the user then does a subscription, then the identity is changed.

open-scd/src/foundation.ts

Lines 824 to 872 in e1b9568

function extRefIdentity(e: Element): string | number {
if (!e.parentElement) return NaN;
const parentIdentity = identity(e.parentElement);
const iedName = e.getAttribute('iedName');
const intAddr = e.getAttribute('intAddr');
const intAddrIndex = Array.from(
e.parentElement.querySelectorAll(`ExtRef[intAddr="${intAddr}"]`)
).indexOf(e);
if (!iedName) return `${parentIdentity}>${intAddr}[${intAddrIndex}]`;
const [
ldInst,
prefix,
lnClass,
lnInst,
doName,
daName,
serviceType,
srcLDInst,
srcPrefix,
srcLNClass,
srcLNInst,
srcCBName,
] = [
'ldInst',
'prefix',
'lnClass',
'lnInst',
'doName',
'daName',
'serviceType',
'srcLDInst',
'srcPrefix',
'srcLNClass',
'srcLNInst',
'srcCBName',
].map(name => e.getAttribute(name));
const cbPath = srcCBName
? `${serviceType}:${srcCBName} ${srcLDInst ?? ''}/${srcPrefix ?? ''} ${
srcLNClass ?? ''
} ${srcLNInst ?? ''}`
: '';
const dataPath = `${iedName} ${ldInst}/${prefix ?? ''} ${lnClass} ${
lnInst ?? ''
} ${doName} ${daName ? daName : ''}`;
return `${parentIdentity}>${cbPath ? cbPath + ' ' : ''}${dataPath}${
intAddr ? '@' + `${intAddr}` : ''
}`;
}

The identity function should return a stable reference.

If an internal address is specified, I think this should be the "primary key". It is also true that tne intAddr can be mapped multiple times but we already use the instance number to take this into account.

Expected behavior

@ca-d and I discussed, and tentatively propose:

function extRefIdentity(e: Element): string | number {
  if (!e.parentElement) return NaN;
  const parentIdentity = identity(e.parentElement);
  const iedName = e.getAttribute('iedName');
  const intAddr = e.getAttribute('intAddr');
  const intAddrIndex = Array.from(
    e.parentElement.querySelectorAll(`ExtRef[intAddr="${intAddr}"]`)
  ).indexOf(e);
-  if (!iedName) return `${parentIdentity}>${intAddr}[${intAddrIndex}]`;
+  if (intAddr) return `${parentIdentity}>${intAddr}[${intAddrIndex}]`;
  const [
    ldInst,
    prefix,
    lnClass,
    lnInst,
    doName,
    daName,
    serviceType,
    srcLDInst,
    srcPrefix,
    srcLNClass,
    srcLNInst,
    srcCBName,
  ] = [
    'ldInst',
    'prefix',
    'lnClass',
    'lnInst',
    'doName',
    'daName',
    'serviceType',
    'srcLDInst',
    'srcPrefix',
    'srcLNClass',
    'srcLNInst',
    'srcCBName',
  ].map(name => e.getAttribute(name));

  const cbPath = srcCBName
    ? `${serviceType}:${srcCBName} ${srcLDInst ?? ''}/${srcPrefix ?? ''} ${
        srcLNClass ?? ''
      } ${srcLNInst ?? ''}`
    : '';
  const dataPath = `${iedName} ${ldInst}/${prefix ?? ''} ${lnClass} ${
    lnInst ?? ''
  } ${doName} ${daName ? daName : ''}`;
  return `${parentIdentity}>${cbPath ? cbPath + ' ' : ''}${dataPath}${
    intAddr ? '@' + `${intAddr}` : ''
  }`;
}
@danyill
Copy link
Collaborator Author

danyill commented Feb 27, 2023

Cases to cover:

  1. intAddr there or not there
  2. Subscription there or not there.

But this seems OK we said at refinement...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant