예제 #1
0
 def calculateCommandEffects(self, state):
     """
     Calculates the (currently local) effect of a switch position change.
     :param state: Calculated State object with switch position
     :return: True if successful, False if calculation was not possible (missing values)
     """
     try:
         newPosition = state.retrieveValue(self.stateKey)
         if newPosition:
             # Switch close
             # No chance to calculate this??
             # Adverse effects possible? (yes, but not very probable?)
             return True
         else:
             # Switch open
             if self.connectedLine.startSwitch == self:
                 removedCurrent = state.retrieveValue(
                     self.connectedLine.startMeter.currentKey)
                 state.updateValue(self.connectedLine.startMeter.currentKey,
                                   0.0)
                 state.updateValue(self.connectedLine.endMeter.currentKey,
                                   0.0)
                 affectedNode = self.connectedLine.startNode
                 try:
                     affectedLines = [
                         l for l in affectedNode.linesOut
                         if state.retrieveValue(l.startSwitch.stateKey)
                     ]
                     endNodes = defaultdict(lambda: 0)
                     for l in affectedLines:
                         endNodes[
                             l.endNode.name] = endNodes[l.endNode.name] + 1
                     for l in affectedLines:
                         try:
                             measuredCurrent = state.retrieveValue(
                                 l.startMeter.currentKey)
                             # split between lines with same destination
                             if not isZero(measuredCurrent):
                                 state.updateValue(
                                     l.startMeter.currentKey,
                                     measuredCurrent + removedCurrent /
                                     endNodes[l.endNode.name])
                         except ValueNotStoredException, e:
                             pass
                 except:
                     for l in affectedNode.linesOut:
                         try:
                             measuredCurrent = state.retrieveValue(
                                 l.startMeter.currentKey)
                             # worst case for every line
                             if not isZero(measuredCurrent):
                                 state.updateValue(
                                     l.startMeter.currentKey,
                                     measuredCurrent + removedCurrent)
                         except ValueNotStoredException, e:
                             pass
             else:
                 removedCurrent = state.retrieveValue(
예제 #2
0
 def safetyCheckR2(self, state):
     """
     This safety rule checks that the voltage is within its allowed interval around the nominal voltage
     :param state: State object (observed or calculated)
     :return: True if safety rule holds, False otherwise (violation)
     """
     logCheckDescription("R2", indentation=3)
     passed = True
     for l in self.getAllConnectedLines():
         try:
             safeInterval = (l.nominalV * (1 - l.voltageBoundaryFactor),
                             l.nominalV * (1 + l.voltageBoundaryFactor))
             localVoltage = l.retrieveValue(state, self, "local", "voltage")
             if not isZero(localVoltage):
                 currentPassed = safeInterval[
                     0] <= localVoltage <= safeInterval[1]
                 passed = False if not currentPassed else passed
                 logDebugCheckValues(
                     "Line %s. Local: V=%f (in [%3.2f;%3.2f])." %
                     (l.name, localVoltage, safeInterval[0],
                      safeInterval[1]),
                     currentPassed,
                     indentation=3)
         except ValueNotStoredException, e:
             logDebugUnknownValues(e.message, l.name, indentation=3)
예제 #3
0
 def consistencyCheckP6b(self, state):
     """
     This consistency rule checks whether the transformation rate is consistent with the current measurement.
     :param state: State object (observed or calculated)
     :return: True if consistency rule holds, False otherwise (violation)
     """
     logCheckDescription("P6b", indentation=3)
     passed = True
     if callable(self.rateFunction):
         try:
             measuredInCurrent = self.linesIn[0].retrieveValue(
                 state, self, "local", "current")
             measuredOutCurrent = self.linesOut[0].retrieveValue(
                 state, self, "local", "current")
             currentTapPosition = state.retrieveValue(self.tapPositionKey)
             if isZero(measuredInCurrent):
                 passed = True
                 logDebugCheckValues(
                     "Transformer %s. No incoming or outgoing current." %
                     (self.name),
                     passed,
                     indentation=3)
             else:
                 try:
                     currentTransformerRate = self.rateFunction(
                         currentTapPosition)
                     expectedMeasuredTransformedOutCurrent = measuredInCurrent * float(
                         currentTransformerRate)
                     if isClose(expectedMeasuredTransformedOutCurrent,
                                measuredOutCurrent):
                         passed = True
                     else:
                         passed = False
                     logDebugCheckValues(
                         "Transformer %s. Measured input current: %fA. Measured output current: %fA. Expected output current: %fA."
                         %
                         (self.name, measuredInCurrent, measuredOutCurrent,
                          expectedMeasuredTransformedOutCurrent),
                         passed,
                         indentation=3)
                 except IndexError:
                     passed = False
                     logDebugCheckValues(
                         "Transformer %s. Discrete tap function, tap position %d has no rate defined."
                         % (self.name, int(round(currentTapPosition))),
                         passed,
                         indentation=3)
                 except ZeroDivisionError:
                     passed = False
                     logDebugCheckValues(
                         "Transformer %s. Measured input current: %fA. Measured output current: %fA. (Division by zero, not consistent)."
                         %
                         (self.name, measuredInCurrent, measuredOutCurrent),
                         passed,
                         indentation=3)
         except ValueNotStoredException, e:
             passed = True
             logDebugUnknownValues(e.message, indentation=3)
예제 #4
0
 def safetyCheckR5b(self, state):
     """
     This safety rule checks whether the transformer rate is safe on actual voltage
     :param state: State object (observed or calculated)
     :return: True if safety rule holds, False otherwise (violation)
     """
     logCheckDescription("R5b", indentation=3)
     passed = True
     if callable(self.rateFunction):
         try:
             measuredInVoltage = self.linesIn[0].retrieveValue(
                 state, self, "local", "voltage")
             nominalOutVoltage = self.linesOut[0].nominalV
             currentTapPosition = state.retrieveValue(self.tapPositionKey)
             if isZero(measuredInVoltage):
                 currentPassed = True
                 passed = False if not currentPassed else passed
                 logDebugCheckValues(
                     "Transformer %s. Actual input voltage: %fV. Nominal output voltage: %fV. Input voltage is zero."
                     % (self.name, measuredInVoltage, nominalOutVoltage),
                     currentPassed,
                     indentation=3)
             else:
                 try:
                     currentTransformerRate = self.rateFunction(
                         currentTapPosition)
                     actualTransformedOutVoltage = measuredInVoltage / float(
                         currentTransformerRate)
                     nominalSafeInterval = (
                         nominalOutVoltage *
                         (1 - self.linesOut[0].voltageBoundaryFactor),
                         nominalOutVoltage *
                         (1 + self.linesOut[0].voltageBoundaryFactor))
                     if nominalSafeInterval[
                             0] <= actualTransformedOutVoltage <= nominalSafeInterval[
                                 1]:
                         currentPassed = True
                     else:
                         currentPassed = False
                     passed = False if not currentPassed else passed
                     logDebugCheckValues(
                         "Transformer %s. Actual input voltage: %fV. Nominal output voltage: %fV. Transformed actual output voltage: %fV (should be in [%3.2f;%3.2f])."
                         % (self.name, measuredInVoltage, nominalOutVoltage,
                            actualTransformedOutVoltage,
                            nominalSafeInterval[0], nominalSafeInterval[1]),
                         currentPassed,
                         indentation=3)
                 except IndexError:
                     currentPassed = False
                     passed = False if not currentPassed else passed
                     logDebugCheckValues(
                         "Transformer %s. Discrete tap function, tap position %d has no rate defined."
                         % (self.name, int(round(currentTapPosition))),
                         currentPassed,
                         indentation=3)
         except ValueNotStoredException, e:
             passed = True
             logDebugUnknownValues(e.message, indentation=3)
예제 #5
0
 def safetyCheckR6(self, state):
     """
     This safety rule checks whether all consumers are connected to the power grid
     :param state: State object (observed or calculated)
     :return: True if safety rule holds, False otherwise (violation)
     """
     logCheckDescription("R6", indentation=2)
     passed = True
     for l in getAllComponentsOfType(Consumer):
         if len(l.linesIn) == 0:
             try:
                 consumedPower = (-1) * state.retrieveValue(l.consumedPowerKey)
                 if isZero(consumedPower):
                     currentPassed = True
                     passed = False if not currentPassed else passed
                     logDebugCheckValues("Consumer %s connected to no line, and no power consumed. %fW" % (l.name, consumedPower), currentPassed, indentation=3)
                 else:
                     currentPassed = False
                     passed = False if not currentPassed else passed
                     logDebugCheckValues("Consumer %s connected to no line, but power consumed. %fW" % (l.name, consumedPower), currentPassed, indentation=3)
             except ValueNotStoredException, e:
                 logDebugUnknownValues(e.message, l.name, indentation=3)
         elif len(l.linesIn) == 1:
             try:
                 consumedPower = (-1) * state.retrieveValue(l.consumedPowerKey)
                 localVoltage = l.linesIn[0].retrieveValue(state, l, "local", "voltage")
                 localSwitch = l.linesIn[0].retrieveValue(state, l, "local", "switchState")
                 remoteSwitch = l.linesIn[0].retrieveValue(state, l, "remote", "switchState")
                 currentPassed = localSwitch and remoteSwitch and not isZero(localVoltage)
                 passed = False if not currentPassed else passed
                 logDebugCheckValues("Consumer %s connected to power supply. Local Switch: %s (== True). Remote Switch: %s (== True). V=%f (>0) P=%fW." %
                                     (l.name, localSwitch, remoteSwitch, localVoltage, consumedPower), currentPassed, indentation=3)
             except ValueNotStoredException, e:
                 logDebugUnknownValues(e.message, l.name, indentation=3)
                 try:
                     consumedPower = (-1) * state.retrieveValue(l.consumedPowerKey)
                     localVoltage = l.linesIn[0].retrieveValue(state, l, "local", "voltage")
                     localSwitch = l.linesIn[0].retrieveValue(state, l, "local", "switchState")
                     currentPassed = localSwitch and not isZero(localVoltage)
                     passed = False if not currentPassed else passed
                     logDebugCheckValues("Consumer %s connected to power supply. Local Switch: %s (== True). Remote Switch unknown. V=%f (>0) P=%fW." %
                                         (l.name, localSwitch, localVoltage, consumedPower), currentPassed, indentation=3)
                 except ValueNotStoredException, e:
                     pass
예제 #6
0
def sendValue(sock, rtuTags, eventType, k, v):
    apdu = None
    try:
        if eventType == "C102":
            apdu = APDUType102(RTU_NUMBER, rtuTags[k].addresses[1])
        else:
            if type(v) == float:
                if not isZero(rtuTags[k].lowerBound) and not isZero(
                        rtuTags[k].lowerBound):
                    v = normalizeValue(v, rtuTags[k].lowerBound,
                                       rtuTags[k].upperBound)
                    if eventType == "COMMAND":
                        apdu = APDUType61(RTU_NUMBER, rtuTags[k].addresses[2],
                                          v, datetime.datetime.now())
                    elif eventType == "MEASUREMENT":
                        apdu = APDUType34(RTU_NUMBER, rtuTags[k].addresses[1],
                                          v, datetime.datetime.now())
                    else:
                        assert False
                else:
                    if eventType == "COMMAND":
                        apdu = APDUType63(RTU_NUMBER, rtuTags[k].addresses[2],
                                          v, datetime.datetime.now())
                    elif eventType == "MEASUREMENT":
                        apdu = APDUType36(RTU_NUMBER, rtuTags[k].addresses[1],
                                          v, datetime.datetime.now())
                    else:
                        assert False
            elif type(v) == bool:
                if eventType == "COMMAND":
                    apdu = APDUType58(RTU_NUMBER, rtuTags[k].addresses[2], v,
                                      datetime.datetime.now())
                elif eventType == "MEASUREMENT":
                    apdu = APDUType30(RTU_NUMBER, rtuTags[k].addresses[1], v,
                                      datetime.datetime.now())
                else:
                    assert False
            else:
                print "Value type not valid. (Allowed: Bool, Float)"
                assert False
    except Exception, e:
        print "Exception while creating APDUs: %s" % e.message
        assert False
예제 #7
0
 def consistencyCheckP6a(self, state):
     """
     This consistency rule checks whether the transformation rate is consistent with the voltage measurement.
     :param state: State object (observed or calculated)
     :return: True if consistency rule holds, False otherwise (violation)
     """
     logCheckDescription("P6a", indentation=3)
     passed = True
     if callable(self.rateFunction):
         try:
             measuredInVoltage = self.linesIn[0].retrieveValue(
                 state, self, "local", "voltage")
             measuredOutVoltage = self.linesOut[0].retrieveValue(
                 state, self, "local", "voltage")
             currentTapPosition = state.retrieveValue(self.tapPositionKey)
             if isZero(measuredOutVoltage):
                 passed = True
                 logDebugCheckValues(
                     "Transformer %s. Measured input voltage: %fV. Measured output voltage: %fV. Output voltage zero!"
                     % (self.name, measuredInVoltage, measuredOutVoltage),
                     passed,
                     indentation=3)
             else:
                 try:
                     currentTransformerRate = self.rateFunction(
                         currentTapPosition)
                     expectedMeasuredTransformedOutVoltage = measuredInVoltage / float(
                         currentTransformerRate)
                     if isClose(expectedMeasuredTransformedOutVoltage,
                                measuredOutVoltage):
                         passed = True
                     else:
                         passed = False
                     logDebugCheckValues(
                         "Transformer %s. Measured input voltage: %fV. Measured output voltage: %fV. Expected output voltage: %fV."
                         %
                         (self.name, measuredInVoltage, measuredOutVoltage,
                          expectedMeasuredTransformedOutVoltage),
                         passed,
                         indentation=3)
                 except IndexError:
                     passed = False
                     logDebugCheckValues(
                         "Transformer %s. Discrete tap function, tap position %d has no rate defined. "
                         % (self.name, int(round(currentTapPosition))),
                         passed,
                         indentation=3)
         except ValueNotStoredException, e:
             passed = True
             logDebugUnknownValues(e.message, indentation=3)
예제 #8
0
class AbstractNode(AbstractComponent):
    def __init__(self, name, linesIn, linesOut):
        """
        Initialize a node type.
        :param name: Name of the node.
        :param linesIn: List of ingoing lines
        :param linesOut: List of outgoing lines
        """
        super(AbstractNode, self).__init__(name)
        assert isinstance(linesIn, list)
        assert isinstance(linesOut, list)
        self.linesIn = linesIn
        self.linesOut = linesOut
        for l in linesIn:
            assert isinstance(l, PowerLine)
            l.setEndNode(self)
        for l in linesOut:
            assert isinstance(l, PowerLine)
            l.setStartNode(self)

    def consistencyCheckP3(self, state):
        """
        This consistency rule checks that the current is zero if a switch, fuse or protective relay has an open circuit.
        :param state: State object (observed or calculated)
        :return: True if consistency rule holds, False otherwise (violation)
        """
        logCheckDescription("P3", indentation=3)
        passed = True
        openSwitchedLines = []
        for l in self.getAllConnectedLines():
            try:
                if l.getLocalComponent(
                        self, "local", "switch") and not l.retrieveValue(
                            state, self, "local", "switchState"):
                    openSwitchedLines.append(l)
                elif l.getLocalComponent(
                        self, "remote", "switch") and not l.retrieveValue(
                            state, self, "remote", "switchState"):
                    openSwitchedLines.append(l)
                elif l.getLocalComponent(
                        self, "local", "fuse") and not l.retrieveValue(
                            state, self, "local", "fuseState"):
                    openSwitchedLines.append(l)
                elif l.getLocalComponent(
                        self, "remote", "fuse") and not l.retrieveValue(
                            state, self, "remote", "fuseState"):
                    openSwitchedLines.append(l)
                elif l.getLocalComponent(
                        self, "local",
                        "protectiveRelay") and not l.retrieveValue(
                            state, self, "local", "protectiveRelayState"):
                    openSwitchedLines.append(l)
                elif l.getLocalComponent(
                        self, "remote",
                        "protectiveRelay") and not l.retrieveValue(
                            state, self, "remote", "protectiveRelayState"):
                    openSwitchedLines.append(l)
            except ValueNotStoredException, e:
                logDebugUnknownValues(e.message, l.name, indentation=3)
        if len(openSwitchedLines) > 0:
            for l in openSwitchedLines:
                try:
                    # localVoltage = l.retrieveValue(state, self, "local", "voltage")
                    localCurrent = l.retrieveValue(state, self, "local",
                                                   "current")
                    # remoteVoltage = l.retrieveValue(state, self, "remote", "voltage")
                    remoteCurrent = l.retrieveValue(state, self, "remote",
                                                    "current")
                    # currentPassed = isZero(localVoltage) and isZero(localCurrent) and isZero(remoteVoltage) and isZero(
                    #    remoteCurrent)
                    currentPassed = isZero(localCurrent) and isZero(
                        remoteCurrent)
                    passed = False if not currentPassed else passed
                    # logDebugCheckValues(
                    #    "Open circuit (switch/fuse/protectiveRelay) on line %s. Local: V=%f (==0.0) AND A=%f (==0.0). Remote: V=%f (==0.0) AND A=%f (==0.0). %s" % (
                    #        l.name, localVoltage, localCurrent, remoteVoltage, remoteCurrent, str(currentPassed)),
                    #    indentation=3)
                    logDebugCheckValues(
                        "Open circuit (switch/fuse/protectiveRelay) on line %s. Local: A=%f (==0.0). Remote: A=%f (==0.0)."
                        % (l.name, localCurrent, remoteCurrent),
                        currentPassed,
                        indentation=3)
                except ValueNotStoredException, e:
                    logDebugUnknownValues(e.message, l.name, indentation=3)
                    try:
                        # localVoltage = l.retrieveValue(state, self, "local", "voltage")
                        localCurrent = l.retrieveValue(state, self, "local",
                                                       "current")
                        # currentPassed = isZero(localVoltage) and isZero(localCurrent)
                        currentPassed = isZero(localCurrent)
                        passed = False if not currentPassed else passed
                        # logDebugCheckValues(
                        #    "Open circuit (switch/fuse/protectiveRelay) on line %s. Local: V=%f (==0.0) AND A=%f (==0.0). (Remote values unknown) %s" % (
                        #        l.name, localVoltage, localCurrent, str(currentPassed)), indentation=3)
                        logDebugCheckValues(
                            "Open circuit (switch/fuse/protectiveRelay) on line %s. Local: A=%f (==0.0). Remote values unknown."
                            % (l.name, localCurrent),
                            currentPassed,
                            indentation=3)
                    except ValueNotStoredException, e:
                        pass
예제 #9
0
class Switch(AbstractDecorator):
    switchesByTags = defaultdict(lambda: None)

    def __init__(self, name, stateKey=None):
        """
        Initialize a switch.
        :param name: Name of the meter.
        :param stateKey: Key for retrieving switch state
        """
        super(Switch, self).__init__(name)
        self.stateKey = stateKey if stateKey else "%s_STATE" % self.name.upper(
        )
        Switch.switchesByTags[self.stateKey] = self
        self.interlocks = []

    def calculateCommandEffects(self, state):
        """
        Calculates the (currently local) effect of a switch position change.
        :param state: Calculated State object with switch position
        :return: True if successful, False if calculation was not possible (missing values)
        """
        try:
            newPosition = state.retrieveValue(self.stateKey)
            if newPosition:
                # Switch close
                # No chance to calculate this??
                # Adverse effects possible? (yes, but not very probable?)
                return True
            else:
                # Switch open
                if self.connectedLine.startSwitch == self:
                    removedCurrent = state.retrieveValue(
                        self.connectedLine.startMeter.currentKey)
                    state.updateValue(self.connectedLine.startMeter.currentKey,
                                      0.0)
                    state.updateValue(self.connectedLine.endMeter.currentKey,
                                      0.0)
                    affectedNode = self.connectedLine.startNode
                    try:
                        affectedLines = [
                            l for l in affectedNode.linesOut
                            if state.retrieveValue(l.startSwitch.stateKey)
                        ]
                        endNodes = defaultdict(lambda: 0)
                        for l in affectedLines:
                            endNodes[
                                l.endNode.name] = endNodes[l.endNode.name] + 1
                        for l in affectedLines:
                            try:
                                measuredCurrent = state.retrieveValue(
                                    l.startMeter.currentKey)
                                # split between lines with same destination
                                if not isZero(measuredCurrent):
                                    state.updateValue(
                                        l.startMeter.currentKey,
                                        measuredCurrent + removedCurrent /
                                        endNodes[l.endNode.name])
                            except ValueNotStoredException, e:
                                pass
                    except:
                        for l in affectedNode.linesOut:
                            try:
                                measuredCurrent = state.retrieveValue(
                                    l.startMeter.currentKey)
                                # worst case for every line
                                if not isZero(measuredCurrent):
                                    state.updateValue(
                                        l.startMeter.currentKey,
                                        measuredCurrent + removedCurrent)
                            except ValueNotStoredException, e:
                                pass
                else:
                    removedCurrent = state.retrieveValue(
                        self.connectedLine.endMeter.currentKey)
                    state.updateValue(self.connectedLine.startMeter.currentKey,
                                      0.0)
                    state.updateValue(self.connectedLine.endMeter.currentKey,
                                      0.0)
                    affectedNode = self.connectedLine.endNode
                    try:
                        affectedLines = [
                            l for l in affectedNode.linesIn
                            if state.retrieveValue(l.endSwitch.stateKey)
                        ]
                        startNodes = defaultdict(lambda: 0)
                        for l in affectedLines:
                            startNodes[l.startNode.
                                       name] = startNodes[l.startNode.name] + 1
                        for l in affectedLines:
                            try:
                                measuredCurrent = state.retrieveValue(
                                    l.endMeter.currentKey)
                                # split between lines with same destination
                                if not isZero(measuredCurrent):
                                    state.updateValue(
                                        l.endMeter.currentKey,
                                        measuredCurrent + removedCurrent /
                                        startNodes[l.startNode.name])
                            except ValueNotStoredException, e:
                                pass
                    except:
                        for l in affectedNode.linesIn:
                            try:
                                measuredCurrent = state.retrieveValue(
                                    l.endMeter.currentKey)
                                # worst case for every line
                                if not isZero(measuredCurrent):
                                    state.updateValue(
                                        l.endMeter.currentKey,
                                        measuredCurrent + removedCurrent)
                            except ValueNotStoredException, e:
                                pass