You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi all,
I have a pyPMU and a pyPDC instance running on the same windows virtual machine. Essentially they are synchronized to the same clock. The pyPMU instance receives phasor data from another source and sends the data as synchrophasor packets to the pyPDC. The pyPDC parses the synchrophasor data, extracts the time stamp (data['time']) and then compares with the current time (time.time()).
The results for this comparison is as follows for data rates 10,25,50,100 fps. RR = reporting rate or Data Rate in frames per sec
RR
Transmission time (avg)
fps
ms
10
99.59
25
39.23
50
19.5
100
9.43
As seen in the table the time difference between the synchrophasor time stamp from the PMU, and the time when it is being parsed in the PDC is same as 1\RR. I do not understand why? Any insight? I was under the impression that some random or constant delay will take place in the communication.
The codes are as follows pyPMU
## Import necessary libraries
import math
import numpy as np
import socket
import struct
from synchrophasor.frame import ConfigFrame2
from synchrophasor.pmu import Pmu
import time
# from synchrophasor.frame import ConfigFrame2
# from time import time
from synchrophasor.frame import CommandFrame
from datetime import datetime
##
"""
randomPMU will listen on ip:port for incoming connections.
After request to start sending measurements - random
values and values from OPAL RT model. It will also receive RR from OPAL RT
and configure frame rate accordingly.
"""
if __name__ == "__main__":
## Configure socket for Phasor data ##
UDP_IP = "10.10.114.22"
UDP_PORT = 8201 #UDP phasor values 32 bytes (V,phi,P)
sock_ph = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock_ph.bind((UDP_IP, UDP_PORT))
print("socket bound, waiting for data...")
## Configure socket for RR Value ##
UDP_PORT2 = 600 # OPAL sends RR to this port
sock_rr = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock_rr.bind((UDP_IP, UDP_PORT2)) # binding is required for receiving not sending
sock_rr.settimeout(1 / 10000) # you dont want to wait forever a data that might not come
flag = False
## Configure socket for RR Value send to CA algorithm ##
UDP_PORT3 = 9901
sock_rr_send = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
## PMU configuration ##
pmu = Pmu(ip="10.10.114.22", port=1410) #original port config
## connect to another VM 10.10.114.23
#pmu = Pmu(ip="10.10.114.22", port=1410)
pmu.logger.setLevel("DEBUG")
cfg = ConfigFrame2(1, # PMU_ID
1000000, # TIME_BASE
1, # Number of PMUs included in data frame
"PDAS_bus2", # Station name
1410, # Data-stream ID(s)
(True, True, True, True), # Data format - POLAR; PH - REAL; AN - REAL; FREQ - REAL;
3, # Number of phasors(was 3)
1, # Number of analog values
1, # Number of digital status words
["VA", "VB", "VC", "ANALOG1", "BREAKER 1 STATUS",
"BREAKER 2 STATUS", "BREAKER 3 STATUS", "BREAKER 4 STATUS", "BREAKER 5 STATUS",
"BREAKER 6 STATUS", "BREAKER 7 STATUS", "BREAKER 8 STATUS", "BREAKER 9 STATUS",
"BREAKER A STATUS", "BREAKER B STATUS", "BREAKER C STATUS", "BREAKER D STATUS",
"BREAKER E STATUS", "BREAKER F STATUS", "BREAKER G STATUS"], # Channel Names
[(0, "v"), (0, "v"),
(0, "v")], # Conversion factor for phasor channels - (float representation, not important)
[(1, "pow")], # Conversion factor for analog channels
[(0x0000, 0xffff)], # Mask words for digital status words
50, # Nominal frequency
1, # Configuration change count
50) # Rate of phasor data transmission) 50 default here
pmu.set_configuration(cfg)
pmu.set_header("Random PMU: Modified by Pratyush")
pmu.run()
############## C37.118 Reporting Rates #########################
rr_list = [5, 10, 25, 50, 100] # list of available RR as per standard
First = True
phasor_list = []
flag = False
while True:
#print(pmu.cfg2,type(pmu.cfg2))
cframe = pmu.cfg2
config_rr = cframe.get_data_rate()
pmu_rr = str(config_rr).encode("ascii") # int to bytes e.g. 50 to b'50'
sock_rr_send.sendto(pmu_rr, (UDP_IP, UDP_PORT3))
#print(pmu_rr)
try:
aware_rr = sock_rr.recv(1024)
#drr = int(struct.unpack('d', aware_rr[8:16])[0]) # if coming from OPAL
del_rr = int(aware_rr.decode("utf-8")) # the received value is +1 or -1
#drr = crr + del_rr
drr=del_rr
flag = True
except socket.timeout: # to catch the error essentially it will only store drr if there is something to store and set the flag
pass
if pmu.clients:
## Socket Values
## Listen to the socket
raw = sock_ph.recv(32)
if First:
tm_strt = datetime.now()
First = False
else:
pass
#print(raw)
header, mag, angle = struct.unpack('ddd', raw)
phasor = (mag, angle)
Vol_A=raw
VA = float(mag)
phi_A = float(angle)
VB = VA
phi_B = phi_A+(math.pi) * 2 / 3
VC = VA
phi_C = phi_A-(math.pi) * 2 / 3
phasor_list.append([VA, phi_A, VB, phi_B, VC, phi_C])
# print(len(phasor_list))
if len(phasor_list) >= (1000 / config_rr):
phasor_array = np.array(phasor_list)
#y = np.mean(phasor_array, axis=0)
y = phasor_array[-1] #latest value
time_stp = datetime.now()
sim_time = (time_stp - tm_strt).total_seconds()
# print(y, time_stp, sim_time)
phasor_list = []
pmu.send_data(phasors=[(y[0], y[1]), (y[2], y[3]), (y[4], y[5])], analog=[9.91], digital=[0x0001])
# print([(VA,phi_A),(VB,phi_B),(VC,phi_C),datetime.now()])
#if len(phasor_list) > (1000 / config_rr):
if flag: # if it received something it changes the RR
pmu.set_data_rate(drr)
#time.sleep(1/ 1000)
flag=False
pmu.join()
pyPDC
from synchrophasor.pdc import Pdc
from synchrophasor.frame import DataFrame
from synchrophasor.frame import ConfigFrame2
import time
from synchrophasor.frame import CommandFrame
import copy
import pickle
import sys
import socket
import struct
"""
PDC will connect to pmu_ip:pmu_port and send request
for header message, configuration and eventually
to start sending measurements.
Here it receives data from PMUs, calculates FPS and Data Rate.
Prints and Saves Configured FPS, actual measured FPS and Data Rate along with phasor measurements
"""
if __name__ == "__main__":
tt_list = []
############## Measured Reporting Rates send to OPAL #########################
UDP_IP_OPAL = "10.10.114.21"
# UDP_PORT1fps_send = 8301
# sock_rr_send1 = socket.socket(socket.AF_INET, # Internet
# socket.SOCK_DGRAM) # UDP
UDP_PORT1fps_send = 8301
sock_rr_send1 = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
#init_time = int(time())
#time_delay = 5
pdc = Pdc(pdc_id=7, pmu_ip="10.10.114.22", pmu_port=1410)
pdc.logger.setLevel("DEBUG")
pdc.run() # Connect to PMU
header = pdc.get_header() # Get header message from PMU
config = pdc.get_config() # Get configuration from PMU
cnfg_fps_default = config.get_data_rate()
fps = cnfg_fps_default
pdc.start() # Request to start sending measurements
# print(fps)
timestamps = []
alldata = []
first = True
i = 0
# ## Configure socket for RR Value Change status##
# UDP_IP = "10.10.114.22"
# UDP_PORT = 603 # whether RR is changed or not, if = 1, RR change initiated else 0
# sock_ch = socket.socket(socket.AF_INET, # Internet
# socket.SOCK_DGRAM) # UDP
# sock_ch.bind((UDP_IP, UDP_PORT)) # binding is required for receiving not sending
# sock_ch.settimeout(1 / 100) # you dont want to wait forever a data that might not come
# change = 0
try:
while True:
# try:
# # listening to rr change signal
# change = sock_ch.recv(1024)
# change = int(change.decode("utf-8"))
# #print(change)
# except socket.timeout: # if nothing comes
# pass
# # timing asking each 60s or 1 minute:
# if change == 1: #time() >= (init_time + time_delay) or
# #init_time += time_delay # this is not a pretty way to do it but i think is clear what is happening
#
# # asking the CFG2:
# pdc.pmu_socket.sendto(CommandFrame(pdc.pdc_id, 'cfg2').convert2bytes(), pdc.pmu_address)
# change = 0
#print("Config frame received")
# config = pdc.get_config()
data = pdc.get() # Keep receiving data
if type(data) == ConfigFrame2:
# config = pdc.get_config() # version="cfg2"
cnfg_fps = data.get_data_rate()
print("config frame received and data rate is %f" %cnfg_fps)
if type(data) == DataFrame:
data = data.get_measurements()
# print(type(data),sys.getsizeof(data)) # Type and size of object in bytes
# i+=1
timestamps.append(data['time'])
if first:
timestrt = data["time"] # unix timestamp; gives time in seconds
cnfg_fps = copy.copy(cnfg_fps_default)
first = False
data_size = 9999
data_rate = 9999
else:
timestp = data["time"]
pdc_time = time.time()
transmission_time = (pdc_time-timestp)*1000
tt_list.append(transmission_time)
acctual_fps = 1 / (timestp - timestrt)
data_size = sys.getsizeof(data) # in bits
data_rate = ((data_size) * 8) / (1024 * 1024 * (timestp - timestrt)) # in Mbps
timestrt = timestp
#print("Transmission time is %f ms"%transmission_time)
# print(cnfg_fps, "fps",acctual_fps,"fps",data_rate,"Mbps")
print("Configured FPS = %s ; Actual FPS = %f, Data Rate = %f Mbps" %
(cnfg_fps, acctual_fps, data_rate),"PMU time=",timestp,"pdc time=",time.time())
fps = acctual_fps
timestamp = time.time()
dev_id = 91
msg_id = i
msg_len = 16
send_opal = struct.pack('=hihdd', dev_id, msg_id, msg_len, timestamp, fps)
sock_rr_send1.sendto(send_opal, (UDP_IP_OPAL, UDP_PORT1fps_send)) # send actual fps to OPAL
i = i + 1
alldata.extend((data, fps, cnfg_fps,data_rate,data_size))
if not data:
#pdc.quit() # Close connection
print("Data not coming. Warning !!")
# print(data,type(data))
# break
except ConnectionResetError:
# pdc.stop()
# pdc.quit()
print(tt_list)
timestring = time.strftime("%Y%m%d-%H%M")
with open("sync2_%s.pickle"%timestring, "wb+")as handle:
pickle.dump(alldata, handle)
print("A file has been written....")
The text was updated successfully, but these errors were encountered:
Hi all,
I have a pyPMU and a pyPDC instance running on the same windows virtual machine. Essentially they are synchronized to the same clock. The pyPMU instance receives phasor data from another source and sends the data as synchrophasor packets to the pyPDC. The pyPDC parses the synchrophasor data, extracts the time stamp
(data['time'])
and then compares with the current time (time.time()
).The results for this comparison is as follows for data rates 10,25,50,100 fps. RR = reporting rate or Data Rate in frames per sec
As seen in the table the time difference between the synchrophasor time stamp from the PMU, and the time when it is being parsed in the PDC is same as 1\RR. I do not understand why? Any insight? I was under the impression that some random or constant delay will take place in the communication.
The codes are as follows
pyPMU
pyPDC
The text was updated successfully, but these errors were encountered: