Esempio n. 1
0
def pmuThread(pmuID, pmu_ip, port, buffer_size, setTS):
    pmu = Pmu(pmu_id=int(pmuID),
              port=int(port),
              ip=pmu_ip,
              buffer_size=int(buffer_size),
              set_timestamp=setTS)
    # pmu.logger.setLevel("DEBUG")

    pmu.set_configuration(
        cybergridCfg
    )  # This will load PMU configuration specified in IEEE C37.118.2 -Annex D (Table D.2)
    pmu.set_header()
    phaseAng1 = 0
    phaseAng2 = 2.09439
    phaseAng3 = -2.09439
    pmu.run()  # PMU starts listening for incoming connections

    while True:
        try:
            if pmu.clients:  # Check if there is any connected PDCs
                sleep(1 / pmu.cfg2.get_data_rate())
                cybergrid_data_sample.set_phasors([(120.0, phaseAng1),
                                                   (120.0, phaseAng2),
                                                   (120.0, phaseAng3)])
                # pmu.send_data(phasors=[(120.0, 3.14),
                #                        (120.0, 3.14),
                #                        (120.0, 3.14)],
                #               analog=[9.91],
                #               digital=[0x0001])
                pmu.send(
                    cybergrid_data_sample
                )  # Sending sample data frame specified in IEEE C37.118.2 - Annex D (Table D.1)

                phaseAng1 = phaseIncrem(phaseAng1)
                phaseAng2 = phaseIncrem(phaseAng2)
                phaseAng3 = phaseIncrem(phaseAng3)
        except EnvironmentError as e:
            print(e)
            sys.exit()

    pmu.join()
Esempio n. 2
0
        60,  # Nominal frequency
        1,  # Configuration change count
        240)  # Rate of phasor data transmission)

    hf = HeaderFrame(
        7,  # PMU_ID
        "Hello I'm nanoPMU!")  # Header Message

    df = DataFrame(
        7,  # PMU_ID
        ("ok", True, "timestamp", False, False, False, 0, "<10",
         0),  # STAT WORD - Check DataFrame set_stat()
        [(14635, 0), (-7318, -12676), (-7318, 12675),
         (1092, 0)],  # PHASORS (3 - v, 1 - i)
        2500,  # Frequency deviation from nominal in mHz
        0,  # Rate of Change of Frequency
        [100, 1000, 10000],  # Analog Values
        [0x3c12],  # Digital status word
        cfg)  # Data Stream Configuration

    pmu.set_configuration(cfg)
    pmu.set_header(hf)

    pmu.run()

    while True:
        if pmu.clients:
            pmu.send(df)

    pmu.join()
Esempio n. 3
0
                       [(ph_v_conversion, "v"), (ph_v_conversion, "v"),
                        (ph_v_conversion, "v"), (ph_i_conversion, "i")],  # Conversion factor for phasor channels
                       [(1, "pow"), (1, "rms"), (1, "peak")],  # Conversion factor for analog channels
                       [(0x0000, 0xffff)],  # Mask words for digital status words
                       60,  # Nominal frequency
                       1,  # Configuration change count
                       240)  # Rate of phasor data transmission)

    hf = HeaderFrame(7,  # PMU_ID
                     "Hello I'm nanoPMU!")  # Header Message

    df = DataFrame(7,  # PMU_ID
                   ("ok", True, "timestamp", False, False, False, 0, "<10", 0),  # STAT WORD - Check DataFrame set_stat()
                   [(14635, 0), (-7318, -12676), (-7318, 12675), (1092, 0)],  # PHASORS (3 - v, 1 - i)
                   2500,  # Frequency deviation from nominal in mHz
                   0,  # Rate of Change of Frequency
                   [100, 1000, 10000],  # Analog Values
                   [0x3c12],  # Digital status word
                   cfg)  # Data Stream Configuration

    pmu.set_configuration(cfg)
    pmu.set_header(hf)

    pmu.run()

    while True:
        if pmu.clients:
            pmu.send(df)

    pmu.join()
Esempio n. 4
0
class MyPmu:
    '''
    Implements the communication protocol of the IEEE C37.118 synchrofphasor standard (IEC 61850) 
    using "pypmu" lib (synchrophasor in the imports).
    This class acts like a wrapper interfacing the lib. 
    Uses a callback function to handle the PPS as a trigger event on the GPIO 18 of the raspberry.
    '''

    def __init__(self, channelNames, nFreq = 50):
        '''
        channelNames = list of the Channels' Names
        nFreq = Nominal Frequency is needed for the configuration frame!
        '''
        self.pmu = Pmu(ip="127.0.0.1", port=1411)
        self.pmu.logger.setLevel("DEBUG")
        self.nFreq = nFreq

        ph_v_conversion = [(100000, "v")]*len(channelNames)  # Voltage phasor conversion factor

        self.cfg = ConfigFrame2(7,  # PMU_ID
                       1000000,  # TIME_BASE
                       1,  # Number of PMUs included in data frame
                       "Station A",  # Station name
                       7734,  # Data-stream ID(s)
                       15,  # Data format - Check ConfigFrame2 set_data_format()
                       len(channelNames),  # Number of phasors
                       0,  # Number of analog values
                       0,  # Number of digital status words
                       channelNames,  # Channel Names
                       ph_v_conversion,  # Conversion factor for phasor channels
                       [],  # Conversion factor for analog channels
                       [],  # Mask words for digital status words
                       nFreq,  # Nominal frequency
                       1,  # Configuration change count
                       1)  # Rate of phasor data transmission)

        self.hf = HeaderFrame(7,  # PMU_ID
                        "Hello I'm MyPMU!")  # Header Message
        
        self.current_dataframe = None

        self.pmu.set_configuration(self.cfg)
        self.pmu.set_header(self.hf)

    def run(self):
        '''
        Create TCP socket, bind port and listen for incoming connections
        '''

        self.pmu.run()
        while True:
            pass    
        self.pmu.join()


    def set_dataframe(self, synchrophasors, soc):
        '''
        Sets the new dataframe to be sent.
        '''

        sph = []
        rocof = []
        freq_dev = []
        for chan in synchrophasors: #for every chan is given a synchrophasor
            sph.append((synchrophasors[chan]['amplitude'], synchrophasors[chan]['phase']))

            if abs(self.nFreq-synchrophasors[chan]['avg_freq']) > 32.767:
                rocof.append(0)
            else:
                rocof.append(synchrophasors[chan]['rocof']) #1 rocof for the whole datagram, the first is given
                freq_dev.append(synchrophasors[chan]['avg_freq']-self.nFreq)# average frequency deviation from nominal
       
        if len(freq_dev) == 0:
            freq_dev.append(0)
        
        self.current_dataframe = DataFrame(7,  # PMU_ID
            ("ok", True, "timestamp", False, False, False, 0, "<10", 0),  # STAT WORD - Check DataFrame set_stat()
            sph,  # PHASORS
            np.average(freq_dev),  # Frequency deviation from nominal in mHz
            np.average(rocof),  # Rate of Change of Frequency
            [],  # Analog Values
            [],  # Digital status word
            self.cfg,  # Data Stream Configuration
            soc=soc)  
            
    
    def send(self, redlab, sph, timestamp):
        '''
        This interface function for the lib sets the dataframe with the given arguments and if the PDC is connected start the communication.
        '''
        
        myPmu.set_dataframe(sph, timestamp)
        if myPmu.pmu.clients: #if PDC asked for frame / is connected
            myPmu.pmu.send(myPmu.current_dataframe)