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

tLN: Check if supervision can be created without passing a control block #80

Open
danyill opened this issue Jan 27, 2024 · 2 comments
Open
Labels
enhancement New feature or request
Milestone

Comments

@danyill
Copy link
Collaborator

danyill commented Jan 27, 2024

It would be generally useful to know if I can create supervisions without having to pass a control block.

As long as a supervision LN has been passed, this should be possible.

Although I worry canInstantiateSubscriptionSupervision is now quite complex, I'd like the control block to be an optional argument.

Then, as an end user if I want to check I also have to pass a supervision instance (I do not propose a rewrite but perhaps our API is not granular enough, I would prefer to just pass an IED and a type, e.g. 'LGOS' or 'LSVS'). But since the standard says this must exist I think it is OK.

This has two uses:

  • An IED could have LGOS and LSVS instances some of which are editable and others which are not. I wish to visually show which ones can and cannot be edited.
  • I wish to evaluate if an IED can have supervisions edited without having to try to actually carry out supervision of a control block.
@JakobVogelsang
Copy link
Contributor

Could you please tell what for you counts as can do supervision for IED and for LN. I think we have all the functions there, just need to combine those to export a check that fits your need.

@danyill
Copy link
Collaborator Author

danyill commented Jan 30, 2024

I think I should be able to create a new (empty) supervision LN in an IED (with no control block if):

  • there exists a first supervision.
  • either the first instance or the DTTs supports the appropriate valImport/valKind (checkEditableSrcRef)
  • check if within the supervision limits (maxGO/maxSV) (checkMaxSupervisionLimits)
  • check if a fixed LnInst is used that it does not already exist (fixedLnInst)

Currently what I'm using is the following:

/**
 * Searches for first instantiated LGOS/LSVS LN for presence of DOI>DAI[valKind=Conf/RO][valImport=true]
 * given a supervision type and if necessary then searches DataTypeTemplates for
 * DOType>DA[valKind=Conf/RO][valImport=true] to determine if modifications to supervision are allowed.
 * @param ied - SCL IED element.
 * @param supervisionType - either 'LGOS' or 'LSVS' supervision LN classes.
 * @returns boolean indicating if subscriptions are allowed.
 */
export function isSupervisionModificationAllowed(
  ied: Element,
  supervisionType: string
): boolean {
  const firstSupervisionLN = ied.querySelector(
    `LN[lnClass="${supervisionType}"]`
  );

  // no supervision logical nodes => no new supervision possible
  if (firstSupervisionLN === null) return false;

  // check if allowed to modify based on first instance properties
  const supervisionName = supervisionType === 'LGOS' ? 'GoCBRef' : 'SvCBRef';
  const instValKind = firstSupervisionLN!
    .querySelector(`DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]`)
    ?.getAttribute('valKind');
  const instValImport = firstSupervisionLN!
    .querySelector(`DOI[name="${supervisionName}"]>DAI[name="setSrcRef"]`)
    ?.getAttribute('valImport');

  if (
    (instValKind === 'RO' || instValKind === 'Conf') &&
    instValImport === 'true'
  )
    return true;

  // check if allowed to modify based on DataTypeTemplates for first instance
  const rootNode = firstSupervisionLN?.ownerDocument;
  const lNodeType = firstSupervisionLN.getAttribute('lnType');
  const lnClass = firstSupervisionLN.getAttribute('lnClass');
  const dObj = rootNode.querySelector(
    `DataTypeTemplates > LNodeType[id="${lNodeType}"][lnClass="${lnClass}"] > DO[name="${
      lnClass === 'LGOS' ? 'GoCBRef' : 'SvCBRef'
    }"]`
  );
  if (dObj) {
    const dORef = dObj.getAttribute('type');
    const daObj = rootNode.querySelector(
      `DataTypeTemplates > DOType[id="${dORef}"] > DA[name="setSrcRef"]`
    );
    if (daObj) {
      return (
        (daObj.getAttribute('valKind') === 'Conf' ||
          daObj.getAttribute('valKind') === 'RO') &&
        daObj.getAttribute('valImport') === 'true'
      );
    }
  }
  // definition missing
  return false;
}

For can instantiate a specific supervision (an LN with a control block is passed):

  • check if the source reference is editable as above (checkEditableSrcRef)
  • check if the control block reference is not already used in a supervision for that IED (checkDuplicateSupervisions) (possibly with a force, overwrite, or replace option).

WDYT? This is effectively splitting what we do in half depending on whether you're creating a new instance or allocating an existing instance.

I think it's still useful to be able to do both together...

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

Successfully merging a pull request may close this issue.

2 participants