OpenEnergyTools / scl-lib

5 stars 4 forks source link

tExtRef: Support Enum to INT32 mappings and ENx to INx mappings #98

Closed danyill closed 6 months ago

danyill commented 6 months ago

IEC 61850-6 I.2.1.2 indicates that the following mappings are allowed:

The change is only in the stVal otherwise the CDCs are identical, see IEC 61850-7-3 F.4.9.

Enumerations at 32-bit integers and so they can be mapped to INT32. This means that the basic types "Enum" and "INT32" should always be compatible.

This means, I think that:

The changes required is in tExtRef/doesFcdaMeetExtRefRestrictions and I think is something like:

/**
 * This function checks if restrictions of an `ExtRef` element given by
 * `pDO` and optionally by `pDA`, `pLN` and `pServT` are met by the FCDA/FCD
 * @param extRef - The `ExtRef` element to be checked against
 * @param data - The `FCDA` element to be checked
 * @param controlBlockType - The control block type to check back with `pServT`
 * @returns Whether the FCDA basic types meet the restrictions of the
 * ExtRef element
 */
export function doesFcdaMeetExtRefRestrictions(
  extRef: Element,
  fcda: Element,
  options: DoesFcdaMeetExtRefRestrictionsOptions = { checkOnlyBType: false }
): boolean {
  // Vendor does not provide data for the check so any FCDA meets restriction
  if (!extRef.hasAttribute("pDO")) return true;

  const fcdaTypes = fcdaBaseTypes(fcda);
  const extRefSpec = extRefTypeRestrictions(extRef);

  // Check cannot be performed assume restriction check to fail
  if (!extRefSpec || !fcdaTypes) return false;

  // If service type specified it must match
  if (
    extRef.getAttribute("pServT") &&
    options.controlBlockType &&
    options.controlBlockType !== extRef.getAttribute("pServT")
  )
    return false;

  // Some vendors allow subscribing of e.g. ACT to SPS, both bType BOOLEAN
  if (options.checkOnlyBType) return fcdaTypes.bType === extRefSpec.bType;

  if (
    extRef.getAttribute("pLN") &&
    extRef.getAttribute("pLN") !== fcda.getAttribute("lnClass")
  )
    return false;

  // Ed 1 to Ed 2 compatibility. The following are compatible:
  // ENS -> INS, ENC -> INC and ENG -> ING
  if (
    fcdaTypes.cdc !== extRefSpec.cdc &&
    !(fcdaTypes.cdc === "ENS" && extRefSpec.cdc === "INS") &&
    !(fcdaTypes.cdc === "INS" && extRefSpec.cdc === "ENS") &&
    !(fcdaTypes.cdc === "ENC" && extRefSpec.cdc === "INC") &&
    !(fcdaTypes.cdc === "INC" && extRefSpec.cdc === "ENC") &&
    !(fcdaTypes.cdc === "ENG" && extRefSpec.cdc === "ING") &&
    !(fcdaTypes.cdc === "ING" && extRefSpec.cdc === "ENG")
  )
    return false;

  if (
    extRef.getAttribute("pDA") &&
    // Basic types not the same
    fcdaTypes.bType != extRefSpec.bType &&
    // Enum to INT32 mappings specifically allowed, Ed 1 to Ed 2 compatibility
    !(fcdaTypes.bType === "INT32" && extRefSpec.bType === "Enum") &&
    !(fcdaTypes.bType === "Enum" && extRefSpec.bType === "INT32")
  )
    return false;

  return true;
}

I will prepare a PR and some tests.

See https://github.com/danyill/oscd-subscriber-later-binding/issues/52

danyill commented 6 months ago

That will need some further improvements as it doesn't cater for the basic type check.

danyill commented 6 months ago

I can't find an example of where an ENG/ING can be used in a GOOSE/SV dataset and I think it may be forbidden by IEC 61850-7-2 because ENG/ING doesn't have functional constraints, OR, MX or ST. So I won't implement this.

github-actions[bot] commented 4 days ago

:tada: This issue has been resolved in version 1.0.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: