com.zepben.evolve.services.network.NetworkServiceComparator.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of evolve-sdk Show documentation
Show all versions of evolve-sdk Show documentation
SDK for interaction with the evolve platform
/*
* Copyright 2024 Zeppelin Bend Pty Ltd
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package com.zepben.evolve.services.network
import com.zepben.evolve.cim.iec61968.assetinfo.*
import com.zepben.evolve.cim.iec61968.assets.*
import com.zepben.evolve.cim.iec61968.common.Location
import com.zepben.evolve.cim.iec61968.infiec61968.infassetinfo.CurrentTransformerInfo
import com.zepben.evolve.cim.iec61968.infiec61968.infassetinfo.PotentialTransformerInfo
import com.zepben.evolve.cim.iec61968.infiec61968.infassetinfo.RelayInfo
import com.zepben.evolve.cim.iec61968.metering.EndDevice
import com.zepben.evolve.cim.iec61968.metering.Meter
import com.zepben.evolve.cim.iec61968.metering.UsagePoint
import com.zepben.evolve.cim.iec61968.operations.OperationalRestriction
import com.zepben.evolve.cim.iec61970.base.auxiliaryequipment.*
import com.zepben.evolve.cim.iec61970.base.core.*
import com.zepben.evolve.cim.iec61970.base.equivalents.EquivalentBranch
import com.zepben.evolve.cim.iec61970.base.equivalents.EquivalentEquipment
import com.zepben.evolve.cim.iec61970.base.meas.*
import com.zepben.evolve.cim.iec61970.base.protection.*
import com.zepben.evolve.cim.iec61970.base.scada.RemoteControl
import com.zepben.evolve.cim.iec61970.base.scada.RemotePoint
import com.zepben.evolve.cim.iec61970.base.scada.RemoteSource
import com.zepben.evolve.cim.iec61970.base.wires.*
import com.zepben.evolve.cim.iec61970.base.wires.generation.production.BatteryUnit
import com.zepben.evolve.cim.iec61970.base.wires.generation.production.PhotoVoltaicUnit
import com.zepben.evolve.cim.iec61970.base.wires.generation.production.PowerElectronicsUnit
import com.zepben.evolve.cim.iec61970.base.wires.generation.production.PowerElectronicsWindUnit
import com.zepben.evolve.cim.iec61970.infiec61970.feeder.Circuit
import com.zepben.evolve.cim.iec61970.infiec61970.feeder.Loop
import com.zepben.evolve.cim.iec61970.infiec61970.feeder.LvFeeder
import com.zepben.evolve.cim.iec61970.infiec61970.wires.generation.production.EvChargingUnit
import com.zepben.evolve.services.common.BaseServiceComparator
import com.zepben.evolve.services.common.ObjectDifference
import com.zepben.evolve.services.common.ValueDifference
import com.zepben.evolve.services.common.compareValues
/**
* @param options Indicates which optional checks to perform
*/
//
// NOTE: Unused functions have been suppressed for this class as they are access by reflection rather than directly. This
// means they are always flagged as unused. By suppressing the warning it also means you might not be testing every
// function, so make sure you check the code coverage
//
@Suppress("unused")
class NetworkServiceComparator @JvmOverloads constructor(
private var options: NetworkServiceComparatorOptions = NetworkServiceComparatorOptions.all()
) : BaseServiceComparator() {
/************ IEC61968 ASSET INFO ************/
private fun compareCableInfo(source: CableInfo, target: CableInfo): ObjectDifference =
ObjectDifference(source, target).apply { compareWireInfo() }
private fun compareNoLoadTest(source: NoLoadTest, target: NoLoadTest): ObjectDifference =
ObjectDifference(source, target).apply {
compareTransformerTest()
compareValues(NoLoadTest::energisedEndVoltage, NoLoadTest::excitingCurrent, NoLoadTest::excitingCurrentZero, NoLoadTest::loss, NoLoadTest::lossZero)
}
private fun compareOpenCircuitTest(source: OpenCircuitTest, target: OpenCircuitTest): ObjectDifference =
ObjectDifference(source, target).apply {
compareTransformerTest()
compareValues(
OpenCircuitTest::energisedEndStep,
OpenCircuitTest::energisedEndVoltage,
OpenCircuitTest::openEndStep,
OpenCircuitTest::openEndVoltage,
OpenCircuitTest::phaseShift
)
}
private fun compareOverheadWireInfo(source: OverheadWireInfo, target: OverheadWireInfo): ObjectDifference =
ObjectDifference(source, target).apply { compareWireInfo() }
private fun comparePowerTransformerInfo(source: PowerTransformerInfo, target: PowerTransformerInfo): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareIdReferenceCollections(PowerTransformerInfo::transformerTankInfos)
}
private fun compareShortCircuitTest(source: ShortCircuitTest, target: ShortCircuitTest): ObjectDifference =
ObjectDifference(source, target).apply {
compareTransformerTest()
compareValues(
ShortCircuitTest::current,
ShortCircuitTest::energisedEndStep,
ShortCircuitTest::groundedEndStep,
ShortCircuitTest::leakageImpedance,
ShortCircuitTest::leakageImpedanceZero,
ShortCircuitTest::loss,
ShortCircuitTest::lossZero,
ShortCircuitTest::power,
ShortCircuitTest::voltage,
ShortCircuitTest::voltageOhmicPart
)
}
private fun compareShuntCompensatorInfo(source: ShuntCompensatorInfo, target: ShuntCompensatorInfo): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareValues(
ShuntCompensatorInfo::maxPowerLoss,
ShuntCompensatorInfo::ratedCurrent,
ShuntCompensatorInfo::ratedReactivePower,
ShuntCompensatorInfo::ratedVoltage
)
}
private fun compareSwitchInfo(source: SwitchInfo, target: SwitchInfo): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareValues(SwitchInfo::ratedInterruptingTime)
}
private fun compareTransformerEndInfo(source: TransformerEndInfo, target: TransformerEndInfo): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareIdReferences(
TransformerEndInfo::transformerStarImpedance,
TransformerEndInfo::energisedEndNoLoadTests,
TransformerEndInfo::energisedEndShortCircuitTests,
TransformerEndInfo::groundedEndShortCircuitTests,
TransformerEndInfo::openEndOpenCircuitTests,
TransformerEndInfo::energisedEndOpenCircuitTests
)
compareValues(
TransformerEndInfo::connectionKind,
TransformerEndInfo::emergencyS,
TransformerEndInfo::endNumber,
TransformerEndInfo::insulationU,
TransformerEndInfo::phaseAngleClock,
TransformerEndInfo::r,
TransformerEndInfo::ratedS,
TransformerEndInfo::ratedU,
TransformerEndInfo::shortTermS
)
}
private fun compareTransformerTankInfo(source: TransformerTankInfo, target: TransformerTankInfo): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareIdReferenceCollections(TransformerTankInfo::transformerEndInfos)
}
private fun ObjectDifference.compareTransformerTest(): ObjectDifference =
apply {
compareIdentifiedObject()
compareValues(TransformerTest::basePower, TransformerTest::temperature)
}
private fun ObjectDifference.compareWireInfo(): ObjectDifference =
apply {
compareAssetInfo()
compareValues(WireInfo::ratedCurrent, WireInfo::material)
}
/************ IEC61968 ASSETS ************/
private fun ObjectDifference.compareAsset(): ObjectDifference =
apply {
compareIdentifiedObject()
compareIdReferences(Asset::location)
compareIdReferenceCollections(Asset::organisationRoles)
}
private fun ObjectDifference.compareAssetContainer(): ObjectDifference =
apply { compareAsset() }
private fun ObjectDifference.compareAssetInfo(): ObjectDifference =
apply { compareIdentifiedObject() }
private fun ObjectDifference.compareAssetOrganisationRole(): ObjectDifference =
apply { compareOrganisationRole() }
private fun compareAssetOwner(source: AssetOwner, target: AssetOwner): ObjectDifference =
ObjectDifference(source, target).apply { compareAssetOrganisationRole() }
private fun ObjectDifference.compareStructure(): ObjectDifference =
apply { compareAssetContainer() }
private fun comparePole(source: Pole, target: Pole): ObjectDifference =
ObjectDifference(source, target).apply {
compareStructure()
compareValues(Pole::classification)
compareIdReferenceCollections(Pole::streetlights)
}
private fun compareStreetlight(source: Streetlight, target: Streetlight): ObjectDifference =
ObjectDifference(source, target).apply {
compareAsset()
compareValues(Streetlight::lightRating, Streetlight::lampKind)
compareIdReferences(Streetlight::pole)
}
/************ IEC61968 COMMON ************/
private fun compareLocation(source: Location, target: Location): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareValues(Location::mainAddress)
compareIndexedValueCollections(Location::points)
}
/************ IEC61968 infIEC61968 InfAssetInfo ************/
private fun compareRelayInfo(source: RelayInfo, target: RelayInfo): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareValues(RelayInfo::curveSetting, RelayInfo::recloseFast)
compareIndexedValueCollections(RelayInfo::recloseDelays)
}
private fun compareCurrentTransformerInfo(source: CurrentTransformerInfo, target: CurrentTransformerInfo): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareValues(
CurrentTransformerInfo::accuracyClass,
CurrentTransformerInfo::accuracyLimit,
CurrentTransformerInfo::coreCount,
CurrentTransformerInfo::ctClass,
CurrentTransformerInfo::kneePointVoltage,
CurrentTransformerInfo::maxRatio,
CurrentTransformerInfo::nominalRatio,
CurrentTransformerInfo::primaryRatio,
CurrentTransformerInfo::ratedCurrent,
CurrentTransformerInfo::secondaryFlsRating,
CurrentTransformerInfo::secondaryRatio,
CurrentTransformerInfo::usage
)
}
private fun comparePotentialTransformerInfo(
source: PotentialTransformerInfo,
target: PotentialTransformerInfo
): ObjectDifference =
ObjectDifference(source, target).apply {
compareAssetInfo()
compareValues(
PotentialTransformerInfo::accuracyClass,
PotentialTransformerInfo::nominalRatio,
PotentialTransformerInfo::primaryRatio,
PotentialTransformerInfo::ptClass,
PotentialTransformerInfo::ratedVoltage,
PotentialTransformerInfo::secondaryRatio
)
}
/************ IEC61968 METERING ************/
private fun ObjectDifference.compareEndDevice(): ObjectDifference =
apply {
compareAssetContainer()
if (options.compareLvSimplification)
compareIdReferenceCollections(EndDevice::usagePoints)
compareValues(EndDevice::customerMRID)
compareIdReferences(EndDevice::serviceLocation)
}
private fun compareMeter(source: Meter, target: Meter): ObjectDifference =
ObjectDifference(source, target).apply { compareEndDevice() }
private fun compareUsagePoint(source: UsagePoint, target: UsagePoint): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareIdReferences(UsagePoint::usagePointLocation)
compareValues(
UsagePoint::isVirtual,
UsagePoint::connectionCategory,
UsagePoint::ratedPower,
UsagePoint::approvedInverterCapacity,
UsagePoint::phaseCode
)
if (options.compareLvSimplification)
compareIdReferenceCollections(UsagePoint::equipment, UsagePoint::endDevices)
}
/************ IEC61968 OPERATIONS ************/
private fun compareOperationalRestriction(source: OperationalRestriction, target: OperationalRestriction): ObjectDifference =
ObjectDifference(source, target).apply {
compareDocument()
compareIdReferenceCollections(OperationalRestriction::equipment)
}
/************ IEC61970 BASE AUXILIARY EQUIPMENT ************/
private fun ObjectDifference.compareAuxiliaryEquipment(): ObjectDifference =
apply {
compareEquipment()
if (options.compareTerminals)
compareIdReferences(AuxiliaryEquipment::terminal)
}
private fun compareCurrentTransformer(source: CurrentTransformer, target: CurrentTransformer): ObjectDifference =
ObjectDifference(source, target).apply {
compareSensor()
compareValues(CurrentTransformer::coreBurden)
}
private fun compareFaultIndicator(source: FaultIndicator, target: FaultIndicator): ObjectDifference =
ObjectDifference(source, target).apply { compareAuxiliaryEquipment() }
private fun comparePotentialTransformer(source: PotentialTransformer, target: PotentialTransformer): ObjectDifference =
ObjectDifference(source, target).apply {
compareSensor()
compareValues(PotentialTransformer::type)
}
private fun ObjectDifference.compareSensor(): ObjectDifference =
apply {
compareAuxiliaryEquipment()
compareIdReferenceCollections(Sensor::relayFunctions)
}
/************ IEC61970 BASE CORE ************/
private fun ObjectDifference.compareAcDcTerminal(): ObjectDifference =
apply { compareIdentifiedObject() }
private fun compareBaseVoltage(source: BaseVoltage, target: BaseVoltage): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareValues(BaseVoltage::nominalVoltage)
}
private fun ObjectDifference.compareConductingEquipment(): ObjectDifference =
apply {
compareEquipment()
compareIdReferences(ConductingEquipment::baseVoltage)
if (options.compareTerminals)
compareIndexedIdReferenceCollections(ConductingEquipment::terminals)
}
private fun compareConnectivityNode(source: ConnectivityNode, target: ConnectivityNode): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareIdReferenceCollections(ConnectivityNode::terminals)
}
private fun ObjectDifference.compareConnectivityNodeContainer(): ObjectDifference =
apply { comparePowerSystemResource() }
private fun ObjectDifference.compareCurve(): ObjectDifference =
apply {
compareIdentifiedObject()
compareIndexedValueCollections(Curve::data)
}
private fun ObjectDifference.compareEquipment(): ObjectDifference =
apply {
comparePowerSystemResource()
compareValues(Equipment::inService, Equipment::normallyInService, Equipment::commissionedDate)
if (options.compareEquipmentContainers)
compareIdReferenceCollections(Equipment::containers)
if (options.compareLvSimplification)
compareIdReferenceCollections(Equipment::usagePoints)
compareIdReferenceCollections(Equipment::operationalRestrictions)
if (options.compareEquipmentContainers)
compareIdReferenceCollections(Equipment::currentContainers)
}
private fun ObjectDifference.compareEquipmentContainer(): ObjectDifference =
apply {
compareConnectivityNodeContainer()
compareIdReferenceCollections(EquipmentContainer::equipment)
}
private fun compareFeeder(source: Feeder, target: Feeder): ObjectDifference =
ObjectDifference(source, target).apply {
compareEquipmentContainer()
compareIdReferences(Feeder::normalHeadTerminal, Feeder::normalEnergizingSubstation)
compareIdReferenceCollections(Feeder::normalEnergizedLvFeeders)
if (options.compareFeederEquipment)
compareIdReferenceCollections(Feeder::currentEquipment)
}
private fun compareGeographicalRegion(source: GeographicalRegion, target: GeographicalRegion): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareIdReferenceCollections(GeographicalRegion::subGeographicalRegions)
}
private fun ObjectDifference.comparePowerSystemResource(): ObjectDifference =
apply {
compareIdentifiedObject()
compareIdReferences(PowerSystemResource::assetInfo, PowerSystemResource::location)
compareValues(PowerSystemResource::numControls)
}
private fun compareSite(source: Site, target: Site): ObjectDifference =
ObjectDifference(source, target).apply {
if (options.compareEquipmentContainers) {
compareEquipmentContainer()
}
}
private fun compareSubGeographicalRegion(source: SubGeographicalRegion, target: SubGeographicalRegion): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareIdReferences(SubGeographicalRegion::geographicalRegion)
compareIdReferenceCollections(SubGeographicalRegion::substations)
}
private fun compareSubstation(source: Substation, target: Substation): ObjectDifference =
ObjectDifference(source, target).apply {
compareEquipmentContainer()
compareIdReferences(Substation::subGeographicalRegion)
compareIdReferenceCollections(Substation::feeders)
}
private fun compareTerminal(source: Terminal, target: Terminal): ObjectDifference =
ObjectDifference(source, target).apply {
compareAcDcTerminal()
compareIdReferences(Terminal::conductingEquipment, Terminal::connectivityNode)
compareValues(Terminal::phases, Terminal::sequenceNumber, Terminal::normalFeederDirection, Terminal::currentFeederDirection)
addIfDifferent(Terminal::normalPhases.name, Terminal::normalPhases.compareValues(source, target) { it.phaseStatusInternal })
addIfDifferent(Terminal::currentPhases.name, Terminal::currentPhases.compareValues(source, target) { it.phaseStatusInternal })
}
/************ IEC61970 BASE EQUIVALENTS ************/
private fun compareEquivalentBranch(source: EquivalentBranch, target: EquivalentBranch): ObjectDifference =
ObjectDifference(source, target).apply {
compareEquivalentEquipment()
compareValues(
EquivalentBranch::negativeR12,
EquivalentBranch::negativeR21,
EquivalentBranch::negativeX12,
EquivalentBranch::negativeX21,
EquivalentBranch::positiveR12,
EquivalentBranch::positiveR21,
EquivalentBranch::positiveX12,
EquivalentBranch::positiveX21,
EquivalentBranch::r,
EquivalentBranch::r21,
EquivalentBranch::x,
EquivalentBranch::x21,
EquivalentBranch::zeroR12,
EquivalentBranch::zeroR21,
EquivalentBranch::zeroX12,
EquivalentBranch::zeroX21
)
}
private fun ObjectDifference.compareEquivalentEquipment(): ObjectDifference =
apply { compareConductingEquipment() }
/************ IEC61970 BASE MEAS ************/
private fun compareAccumulator(source: Accumulator, target: Accumulator): ObjectDifference =
ObjectDifference(source, target).apply {
compareMeasurement()
}
private fun compareAnalog(source: Analog, target: Analog): ObjectDifference =
ObjectDifference(source, target).apply {
compareMeasurement()
compareValues(Analog::positiveFlowIn)
}
private fun compareControl(source: Control, target: Control): ObjectDifference =
ObjectDifference(source, target).apply {
compareIoPoint()
compareValues(Control::powerSystemResourceMRID)
compareIdReferences(Control::remoteControl)
}
private fun compareDiscrete(source: Discrete, target: Discrete): ObjectDifference =
ObjectDifference(source, target).apply {
compareMeasurement()
}
private fun ObjectDifference.compareIoPoint(): ObjectDifference =
apply { compareIdentifiedObject() }
private fun ObjectDifference.compareMeasurement(): ObjectDifference =
apply {
compareIdentifiedObject()
compareValues(Measurement::powerSystemResourceMRID, Measurement::unitSymbol, Measurement::phases, Measurement::terminalMRID)
compareIdReferences(Measurement::remoteSource)
}
/************ IEC61970 Base Protection ************/
private fun compareCurrentRelay(source: CurrentRelay, target: CurrentRelay): ObjectDifference =
ObjectDifference(source, target).apply {
compareProtectionRelayFunction()
compareValues(CurrentRelay::currentLimit1, CurrentRelay::inverseTimeFlag, CurrentRelay::timeDelay1)
}
private fun compareDistanceRelay(source: DistanceRelay, target: DistanceRelay): ObjectDifference =
ObjectDifference(source, target).apply {
compareProtectionRelayFunction()
compareValues(
DistanceRelay::backwardBlind,
DistanceRelay::backwardReach,
DistanceRelay::backwardReactance,
DistanceRelay::forwardBlind,
DistanceRelay::forwardReach,
DistanceRelay::forwardReactance,
DistanceRelay::operationPhaseAngle1,
DistanceRelay::operationPhaseAngle2,
DistanceRelay::operationPhaseAngle3
)
}
private fun ObjectDifference.compareProtectionRelayFunction(): ObjectDifference =
apply {
comparePowerSystemResource()
compareValues(
ProtectionRelayFunction::model,
ProtectionRelayFunction::reclosing,
ProtectionRelayFunction::relayDelayTime,
ProtectionRelayFunction::protectionKind,
ProtectionRelayFunction::directable,
ProtectionRelayFunction::powerDirection
)
compareIndexedValueCollections(ProtectionRelayFunction::timeLimits, ProtectionRelayFunction::thresholds)
compareIdReferenceCollections(
ProtectionRelayFunction::protectedSwitches,
ProtectionRelayFunction::sensors,
ProtectionRelayFunction::schemes
)
}
private fun compareProtectionRelayScheme(source: ProtectionRelayScheme, target: ProtectionRelayScheme) =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareIdReferences(ProtectionRelayScheme::system)
compareIdReferenceCollections(ProtectionRelayScheme::functions)
}
private fun compareProtectionRelaySystem(source: ProtectionRelaySystem, target: ProtectionRelaySystem) =
ObjectDifference(source, target).apply {
compareEquipment()
compareValues(ProtectionRelaySystem::protectionKind)
compareIdReferenceCollections(ProtectionRelaySystem::schemes)
}
private fun compareVoltageRelay(source: VoltageRelay, target: VoltageRelay) =
ObjectDifference(source, target).apply {
compareProtectionRelayFunction()
}
/************ IEC61970 BASE SCADA ************/
private fun compareRemoteControl(source: RemoteControl, target: RemoteControl): ObjectDifference =
ObjectDifference(source, target).apply {
compareRemotePoint()
compareIdReferences(RemoteControl::control)
}
private fun ObjectDifference.compareRemotePoint(): ObjectDifference =
apply { compareIdentifiedObject() }
private fun compareRemoteSource(source: RemoteSource, target: RemoteSource): ObjectDifference =
ObjectDifference(source, target).apply {
compareRemotePoint()
compareIdReferences(RemoteSource::measurement)
}
/************ IEC61970 BASE WIRES GENERATION PRODUCTION ************/
private fun compareBatteryUnit(source: BatteryUnit, target: BatteryUnit): ObjectDifference =
ObjectDifference(source, target).apply {
comparePowerElectronicsUnit()
compareValues(BatteryUnit::batteryState, BatteryUnit::ratedE, BatteryUnit::storedE)
}
private fun comparePhotoVoltaicUnit(source: PhotoVoltaicUnit, target: PhotoVoltaicUnit): ObjectDifference =
ObjectDifference(source, target).apply {
comparePowerElectronicsUnit()
}
private fun ObjectDifference.comparePowerElectronicsUnit(): ObjectDifference =
apply {
compareEquipment()
compareIdReferences(PowerElectronicsUnit::powerElectronicsConnection)
compareValues(PowerElectronicsUnit::maxP, PowerElectronicsUnit::minP)
}
private fun comparePowerElectronicsWindUnit(
source: PowerElectronicsWindUnit,
target: PowerElectronicsWindUnit
): ObjectDifference =
ObjectDifference(source, target).apply {
comparePowerElectronicsUnit()
}
/************ IEC61970 BASE WIRES ************/
private fun compareAcLineSegment(source: AcLineSegment, target: AcLineSegment): ObjectDifference =
ObjectDifference(source, target).apply {
compareConductor()
compareIdReferences(AcLineSegment::perLengthSequenceImpedance)
}
private fun compareBreaker(source: Breaker, target: Breaker): ObjectDifference =
ObjectDifference(source, target).apply {
compareProtectedSwitch()
compareValues(Breaker::inTransitTime)
}
private fun compareLoadBreakSwitch(source: LoadBreakSwitch, target: LoadBreakSwitch): ObjectDifference =
ObjectDifference(source, target).apply { compareProtectedSwitch() }
private fun compareBusbarSection(source: BusbarSection, target: BusbarSection): ObjectDifference =
ObjectDifference(source, target).apply { compareConnector() }
private fun ObjectDifference.compareConductor(): ObjectDifference =
apply {
compareConductingEquipment()
compareValues(Conductor::length, Conductor::designTemperature, Conductor::designRating)
}
private fun ObjectDifference.compareConnector(): ObjectDifference =
apply { compareConductingEquipment() }
private fun compareDisconnector(source: Disconnector, target: Disconnector): ObjectDifference =
ObjectDifference(source, target).apply { compareSwitch() }
private fun ObjectDifference.compareEarthFaultCompensator(): ObjectDifference =
apply {
compareConductingEquipment()
compareValues(EarthFaultCompensator::r)
}
private fun ObjectDifference.compareEnergyConnection(): ObjectDifference =
apply { compareConductingEquipment() }
private fun compareEnergyConsumer(source: EnergyConsumer, target: EnergyConsumer): ObjectDifference =
ObjectDifference(source, target).apply {
compareEnergyConnection()
compareIdReferenceCollections(EnergyConsumer::phases)
compareValues(
EnergyConsumer::customerCount,
EnergyConsumer::grounded,
EnergyConsumer::p,
EnergyConsumer::pFixed,
EnergyConsumer::phaseConnection,
EnergyConsumer::q,
EnergyConsumer::qFixed
)
}
private fun compareEnergyConsumerPhase(source: EnergyConsumerPhase, target: EnergyConsumerPhase): ObjectDifference =
ObjectDifference(source, target).apply {
comparePowerSystemResource()
compareIdReferences(EnergyConsumerPhase::energyConsumer)
compareValues(EnergyConsumerPhase::phase, EnergyConsumerPhase::p, EnergyConsumerPhase::pFixed, EnergyConsumerPhase::q, EnergyConsumerPhase::qFixed)
}
private fun compareEnergySource(source: EnergySource, target: EnergySource): ObjectDifference =
ObjectDifference(source, target).apply {
compareEnergyConnection()
compareIdReferenceCollections(EnergySource::phases)
compareValues(
EnergySource::activePower,
EnergySource::reactivePower,
EnergySource::voltageAngle,
EnergySource::voltageMagnitude,
EnergySource::pMax,
EnergySource::pMin,
EnergySource::r,
EnergySource::r0,
EnergySource::rn,
EnergySource::x,
EnergySource::x0,
EnergySource::xn,
EnergySource::isExternalGrid,
EnergySource::rMin,
EnergySource::rnMin,
EnergySource::r0Min,
EnergySource::xMin,
EnergySource::xnMin,
EnergySource::x0Min,
EnergySource::rMax,
EnergySource::rnMax,
EnergySource::r0Max,
EnergySource::xMax,
EnergySource::xnMax,
EnergySource::x0Max
)
}
private fun compareEnergySourcePhase(source: EnergySourcePhase, target: EnergySourcePhase): ObjectDifference =
ObjectDifference(source, target).apply {
comparePowerSystemResource()
compareIdReferences(EnergySourcePhase::energySource)
compareValues(EnergySourcePhase::phase)
}
private fun compareFuse(source: Fuse, target: Fuse): ObjectDifference =
ObjectDifference(source, target).apply {
compareSwitch()
compareIdReferences(Fuse::function)
}
private fun compareGround(source: Ground, target: Ground): ObjectDifference =
ObjectDifference(source, target).apply {
compareConductingEquipment()
}
private fun compareGroundDisconnector(source: GroundDisconnector, target: GroundDisconnector): ObjectDifference =
ObjectDifference(source, target).apply {
compareSwitch()
}
private fun compareGroundingImpedance(source: GroundingImpedance, target: GroundingImpedance): ObjectDifference =
ObjectDifference(source, target).apply {
compareEarthFaultCompensator()
compareValues(GroundingImpedance::x)
}
private fun compareJumper(source: Jumper, target: Jumper): ObjectDifference =
ObjectDifference(source, target).apply { compareSwitch() }
private fun compareJunction(source: Junction, target: Junction): ObjectDifference =
ObjectDifference(source, target).apply { compareConnector() }
private fun ObjectDifference.compareLine(): ObjectDifference =
apply {
compareEquipmentContainer()
}
private fun compareLinearShuntCompensator(source: LinearShuntCompensator, target: LinearShuntCompensator): ObjectDifference =
ObjectDifference(source, target).apply {
compareShuntCompensator()
compareValues(
LinearShuntCompensator::b0PerSection,
LinearShuntCompensator::bPerSection,
LinearShuntCompensator::g0PerSection,
LinearShuntCompensator::gPerSection
)
}
private fun ObjectDifference.comparePerLengthImpedance(): ObjectDifference =
apply { comparePerLengthLineParameter() }
private fun ObjectDifference.comparePerLengthLineParameter(): ObjectDifference =
apply { compareIdentifiedObject() }
private fun comparePerLengthSequenceImpedance(
source: PerLengthSequenceImpedance,
target: PerLengthSequenceImpedance
): ObjectDifference =
ObjectDifference(source, target).apply {
comparePerLengthImpedance()
compareValues(
PerLengthSequenceImpedance::r,
PerLengthSequenceImpedance::x,
PerLengthSequenceImpedance::bch,
PerLengthSequenceImpedance::gch,
PerLengthSequenceImpedance::r0,
PerLengthSequenceImpedance::x0,
PerLengthSequenceImpedance::b0ch,
PerLengthSequenceImpedance::g0ch
)
}
private fun comparePetersenCoil(source: PetersenCoil, target: PetersenCoil): ObjectDifference =
ObjectDifference(source, target).apply {
compareEarthFaultCompensator()
compareValues(PetersenCoil::xGroundNominal)
}
private fun comparePowerElectronicsConnection(
source: PowerElectronicsConnection,
target: PowerElectronicsConnection
): ObjectDifference =
ObjectDifference(source, target).apply {
compareRegulatingCondEq()
compareIdReferenceCollections(PowerElectronicsConnection::units, PowerElectronicsConnection::phases)
compareValues(
PowerElectronicsConnection::maxIFault,
PowerElectronicsConnection::maxQ,
PowerElectronicsConnection::minQ,
PowerElectronicsConnection::p,
PowerElectronicsConnection::q,
PowerElectronicsConnection::ratedS,
PowerElectronicsConnection::ratedU,
PowerElectronicsConnection::inverterStandard,
PowerElectronicsConnection::sustainOpOvervoltLimit,
PowerElectronicsConnection::stopAtOverFreq,
PowerElectronicsConnection::stopAtUnderFreq,
PowerElectronicsConnection::invVoltWattRespMode,
PowerElectronicsConnection::invWattRespV1,
PowerElectronicsConnection::invWattRespV2,
PowerElectronicsConnection::invWattRespV3,
PowerElectronicsConnection::invWattRespV4,
PowerElectronicsConnection::invWattRespPAtV1,
PowerElectronicsConnection::invWattRespPAtV2,
PowerElectronicsConnection::invWattRespPAtV3,
PowerElectronicsConnection::invWattRespPAtV4,
PowerElectronicsConnection::invVoltVarRespMode,
PowerElectronicsConnection::invVarRespV1,
PowerElectronicsConnection::invVarRespV2,
PowerElectronicsConnection::invVarRespV3,
PowerElectronicsConnection::invVarRespV4,
PowerElectronicsConnection::invVarRespQAtV1,
PowerElectronicsConnection::invVarRespQAtV2,
PowerElectronicsConnection::invVarRespQAtV3,
PowerElectronicsConnection::invVarRespQAtV4,
PowerElectronicsConnection::invReactivePowerMode,
PowerElectronicsConnection::invFixReactivePower
)
}
private fun comparePowerElectronicsConnectionPhase(
source: PowerElectronicsConnectionPhase,
target: PowerElectronicsConnectionPhase
): ObjectDifference =
ObjectDifference(source, target).apply {
comparePowerSystemResource()
compareIdReferences(PowerElectronicsConnectionPhase::powerElectronicsConnection)
compareValues(PowerElectronicsConnectionPhase::p, PowerElectronicsConnectionPhase::phase, PowerElectronicsConnectionPhase::q)
}
private fun comparePowerTransformer(source: PowerTransformer, target: PowerTransformer): ObjectDifference =
ObjectDifference(source, target).apply {
compareConductingEquipment()
compareIndexedIdReferenceCollections(PowerTransformer::ends)
compareValues(
PowerTransformer::vectorGroup,
PowerTransformer::transformerUtilisation,
PowerTransformer::constructionKind,
PowerTransformer::function
)
}
private fun comparePowerTransformerEnd(source: PowerTransformerEnd, target: PowerTransformerEnd): ObjectDifference =
ObjectDifference(source, target).apply {
compareTransformerEnd()
compareIdReferences(PowerTransformerEnd::powerTransformer)
compareValues(
PowerTransformerEnd::b,
PowerTransformerEnd::b0,
PowerTransformerEnd::connectionKind,
PowerTransformerEnd::g,
PowerTransformerEnd::g0,
PowerTransformerEnd::phaseAngleClock,
PowerTransformerEnd::r,
PowerTransformerEnd::r0,
PowerTransformerEnd::ratedS,
PowerTransformerEnd::ratedU,
PowerTransformerEnd::x,
PowerTransformerEnd::x0
)
compareIndexedValueCollections(PowerTransformerEnd::sRatings)
}
private fun ObjectDifference.compareProtectedSwitch(): ObjectDifference =
apply {
compareSwitch()
compareValues(ProtectedSwitch::breakingCapacity)
compareIdReferenceCollections(ProtectedSwitch::relayFunctions)
}
private fun compareRatioTapChanger(source: RatioTapChanger, target: RatioTapChanger): ObjectDifference =
ObjectDifference(source, target).apply {
compareTapChanger()
compareIdReferences(RatioTapChanger::transformerEnd)
compareValues(RatioTapChanger::stepVoltageIncrement)
}
private fun compareRecloser(source: Recloser, target: Recloser): ObjectDifference =
ObjectDifference(source, target).apply { compareProtectedSwitch() }
private fun ObjectDifference.compareRegulatingCondEq(): ObjectDifference =
apply {
compareEnergyConnection()
compareValues(RegulatingCondEq::controlEnabled)
compareIdReferences(RegulatingCondEq::regulatingControl)
}
private fun ObjectDifference.compareRegulatingControl(): ObjectDifference =
apply {
comparePowerSystemResource()
compareValues(
RegulatingControl::discrete,
RegulatingControl::mode,
RegulatingControl::monitoredPhase,
RegulatingControl::targetDeadband,
RegulatingControl::targetValue,
RegulatingControl::enabled,
RegulatingControl::maxAllowedTargetValue,
RegulatingControl::minAllowedTargetValue,
RegulatingControl::ratedCurrent
)
compareIdReferences(RegulatingControl::terminal)
compareIdReferenceCollections(RegulatingControl::regulatingCondEqs)
}
private fun compareReactiveCapabilityCurve(source: ReactiveCapabilityCurve, target: ReactiveCapabilityCurve): ObjectDifference =
ObjectDifference(source, target).apply { compareCurve() }
private fun ObjectDifference.compareRotatingMachine(): ObjectDifference =
apply {
compareRegulatingCondEq()
compareValues(RotatingMachine::ratedPowerFactor, RotatingMachine::ratedS, RotatingMachine::ratedU, RotatingMachine::p, RotatingMachine::q)
}
private fun compareSeriesCompensator(source: SeriesCompensator, target: SeriesCompensator): ObjectDifference =
ObjectDifference(source, target).apply {
compareConductingEquipment()
compareValues(
SeriesCompensator::r,
SeriesCompensator::r0,
SeriesCompensator::x,
SeriesCompensator::x0,
SeriesCompensator::varistorRatedCurrent,
SeriesCompensator::varistorVoltageThreshold
)
}
private fun ObjectDifference.compareShuntCompensator(): ObjectDifference =
apply {
compareRegulatingCondEq()
compareValues(ShuntCompensator::grounded, ShuntCompensator::nomU, ShuntCompensator::phaseConnection, ShuntCompensator::sections)
}
private fun ObjectDifference.compareSwitch(): ObjectDifference =
apply {
compareConductingEquipment()
compareValues(Switch::ratedCurrent)
addIfDifferent("isNormallyOpen", compareOpenStatus(source, target, Switch::isNormallyOpen))
addIfDifferent("isOpen", compareOpenStatus(source, target, Switch::isOpen))
}
private fun ObjectDifference.compareTapChanger(): ObjectDifference =
apply {
comparePowerSystemResource()
compareValues(
TapChanger::controlEnabled,
TapChanger::neutralU,
TapChanger::highStep,
TapChanger::lowStep,
TapChanger::neutralStep,
TapChanger::normalStep,
TapChanger::step
)
compareIdReferences(TapChanger::tapChangerControl)
}
private fun compareSynchronousMachine(source: SynchronousMachine, target: SynchronousMachine): ObjectDifference =
ObjectDifference(source, target).apply {
compareRotatingMachine()
compareValues(
SynchronousMachine::baseQ,
SynchronousMachine::condenserP,
SynchronousMachine::earthing,
SynchronousMachine::earthingStarPointR,
SynchronousMachine::earthingStarPointX,
SynchronousMachine::ikk,
SynchronousMachine::maxQ,
SynchronousMachine::maxU,
SynchronousMachine::minQ,
SynchronousMachine::minU,
SynchronousMachine::mu,
SynchronousMachine::r,
SynchronousMachine::r0,
SynchronousMachine::r2,
SynchronousMachine::satDirectSubtransX,
SynchronousMachine::satDirectSyncX,
SynchronousMachine::satDirectTransX,
SynchronousMachine::x0,
SynchronousMachine::x2,
SynchronousMachine::type,
SynchronousMachine::operatingMode
)
compareIdReferenceCollections(SynchronousMachine::curves)
}
private fun compareTapChangerControl(source: TapChangerControl, target: TapChangerControl): ObjectDifference =
ObjectDifference(source, target).apply {
compareRegulatingControl()
compareValues(
TapChangerControl::limitVoltage,
TapChangerControl::lineDropCompensation,
TapChangerControl::lineDropR,
TapChangerControl::lineDropX,
TapChangerControl::reverseLineDropR,
TapChangerControl::reverseLineDropX,
TapChangerControl::forwardLDCBlocking,
TapChangerControl::timeDelay,
TapChangerControl::coGenerationEnabled
)
}
private fun ObjectDifference.compareTransformerEnd(): ObjectDifference =
apply {
compareIdentifiedObject()
compareValues(TransformerEnd::grounded, TransformerEnd::rGround, TransformerEnd::xGround, TransformerEnd::endNumber)
compareIdReferences(TransformerEnd::baseVoltage, TransformerEnd::ratioTapChanger, TransformerEnd::terminal, TransformerEnd::starImpedance)
}
private fun compareTransformerStarImpedance(
source: TransformerStarImpedance,
target: TransformerStarImpedance
): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareValues(TransformerStarImpedance::r, TransformerStarImpedance::r0, TransformerStarImpedance::x, TransformerStarImpedance::x0)
compareIdReferences(TransformerStarImpedance::transformerEndInfo)
}
/************ IEC61970 InfIEC61970 Feeder ************/
private fun compareCircuit(source: Circuit, target: Circuit): ObjectDifference =
ObjectDifference(source, target).apply {
compareLine()
compareIdReferences(Circuit::loop)
compareIdReferenceCollections(Circuit::endTerminals, Circuit::endSubstations)
}
private fun compareLoop(source: Loop, target: Loop): ObjectDifference =
ObjectDifference(source, target).apply {
compareIdentifiedObject()
compareIdReferenceCollections(Loop::circuits, Loop::substations, Loop::energizingSubstations)
}
private fun compareLvFeeder(source: LvFeeder, target: LvFeeder): ObjectDifference =
ObjectDifference(source, target).apply {
compareEquipmentContainer()
compareIdReferences(LvFeeder::normalHeadTerminal)
compareIdReferenceCollections(LvFeeder::normalEnergizingFeeders)
if (options.compareFeederEquipment)
compareIdReferenceCollections(LvFeeder::currentEquipment)
}
/************ IEC61970 InfIEC61970 WIRES GENERATION PRODUCTION ************/
private fun compareEvChargingUnit(source: EvChargingUnit, target: EvChargingUnit): ObjectDifference =
ObjectDifference(source, target).apply {
comparePowerElectronicsUnit()
}
private fun compareOpenStatus(source: Switch, target: Switch, openTest: (Switch, SinglePhaseKind) -> Boolean): ValueDifference? {
val sourceStatus = PhaseCode.ABCN.singlePhases.associateWith { openTest(source, it) }
val targetStatus = PhaseCode.ABCN.singlePhases.associateWith { openTest(target, it) }
return if (sourceStatus != targetStatus) {
ValueDifference(sourceStatus, targetStatus)
} else {
null
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy