I updadet my code to save data frame and now it’s working with pmu connection tester and openPDC. It’s not working with my custom adapter.
Code to send dataFrame:
function buildDataFrame(startTime) {
const now = new Date();
const soc = Math.floor(now.getTime() / 1000);
const fracsec = Math.floor(((now.getTime() % 1000) / 1000) * TIME_BASE); //
const deltaT = (Date.now() - startTime) / 1000; // time delta t
const Vrms = 230; // Voltage 230V (root-mean-square)
const Vpeak = Vrms * Math.sqrt(2); // peak Voltage
const Vscale = 1 / Math.sqrt(2); // from peak to rms based on ieee
const baseFreq = NOMINAL_FREQ; // 60 hz
const freq = baseFreq + (Math.random() - 0.5) * 0.02; // added random noise
const omega = 2 * Math.PI * freq;
const phaseAngles = [ 0, -2 * Math.PI / 3, 2 * Math.PI / 3 ]; // 0°, -120°, +120°
const phasors = phaseAngles.map(angle => {
const real = Vpeak * Vscale * Math.cos(omega * deltaT + angle); // Real part
const imag = Vpeak * Vscale * Math.sin(omega * deltaT + angle); // Imagine part
return [ writeFloatBE(real), writeFloatBE(imag) ];
}).flat();
const SYNC = 0xAA01; // SYNC word: 0xAA01 = data frame, not last frame
const STAT = 0b0000000000000000; // PMU time is synchronized
const payload = Buffer.concat([
writeUInt16BE(DEVICE_ID), // PMU ID
writeUInt32BE(soc), // SOC
writeUInt32BE(fracsec), // FRACSEC
writeUInt16BE(STAT), // STAT
...phasors, // 3 phasors → 6 floats → 24 bytes
writeFloatBE(freq), // Frequency (float)
writeFloatBE(0.0), // ROCOF = 0
]);
const syncBuf = writeUInt16BE(SYNC);
const frameSize = 2 + 2 + payload.length + 2; // SYNC + FRAMESIZE + payload + CRC
const frameSizeBuf = writeUInt16BE(frameSize);
const frameWithoutCRC = Buffer.concat([ syncBuf, frameSizeBuf, payload ]);
const crc = calcCRC(frameWithoutCRC);
return Buffer.concat([ frameWithoutCRC, crc ]);
}
Adapter:
using System;
using GSF;
using GSF.PhasorProtocols;
namespace DeviceToData
{
class Program
{
static MultiProtocolFrameParser parser;
static long frameCount;
static void Main(string[] args)
{
// Create a new protocol parser
parser = new MultiProtocolFrameParser();
// Attach to desired events
parser.ConnectionAttempt += parser_ConnectionAttempt;
parser.ConnectionEstablished += parser_ConnectionEstablished;
parser.ConnectionException += parser_ConnectionException;
parser.ParsingException += parser_ParsingException;
parser.ReceivedConfigurationFrame += parser_ReceivedConfigurationFrame;
parser.ReceivedDataFrame += parser_ReceivedDataFrame;
// Define the connection string
parser.ConnectionString =
"phasorProtocol=IeeeC37_118V2; accessID=2; transportprotocol=tcp; server=127.0.0.1; port=4713; islistener=false;";
// When connecting to a file based resource you may want to loop the data
parser.AutoRepeatCapturedPlayback = true;
// Start frame parser
parser.AutoStartDataParsingSequence = true;
parser.Start();
// Keep the console open while receiving live data; application will be terminated when the user presses the Enter key:
Console.ReadLine();
}
static void parser_ReceivedDataFrame(object sender, EventArgs<IDataFrame> e)
{
Console.WriteLine("Data Frame");
// Increase the frame count each time a frame is received
frameCount++;
// Print information each time we receive 60 frames (every 2 seconds for 30 frames per second)
// Also check to assure the DataFrame has at least one Cell
if ((frameCount % 60 == 0) && (e.Argument.Cells.Count > 0))
{
IDataCell device = e.Argument.Cells[0];
Console.WriteLine("Received {0} data frames so far...", frameCount);
Console.WriteLine(" Last frequency: {0}Hz", device.FrequencyValue.Frequency);
for (int x = 0; x < device.PhasorValues.Count; x++)
{
Console.WriteLine("PMU {0} Phasor {1} Angle = {2}", device.IDCode, x, device.PhasorValues[x].Angle);
Console.WriteLine("PMU {0} Phasor {1} Magnitude = {2}", device.IDCode, x, device.PhasorValues[x].Magnitude);
}
Console.WriteLine(" Last Timestamp: {0}", ((DateTime)e.Argument.Timestamp).ToString("yyyy-MM-dd HH:mm:ss.fff"));
}
}
static void parser_ReceivedConfigurationFrame(object sender, EventArgs<IConfigurationFrame> e)
{
// Notify the user when a configuration frame is received
Console.WriteLine("Config Frame");
Console.WriteLine(sender);
Console.WriteLine("Received configuration frame with {0} device(s)", e.Argument.Cells.Count);
}
static void parser_ParsingException(object sender, EventArgs<Exception> e)
{
// Output the exception to the user
Console.WriteLine("Parsing exception: {0}", e.Argument);
}
static void parser_ConnectionException(object sender, EventArgs<Exception, int> e)
{
// Display which connection attempt failed and the exception that occurred
Console.WriteLine("Connection attempt {0} failed due to exception: {1}",
e.Argument2, e.Argument1);
}
static void parser_ConnectionEstablished(object sender, EventArgs e)
{
// Notify the user when the connection is established
Console.WriteLine("Initiating {0} {1} based connection...",
parser.PhasorProtocol.GetFormattedProtocolName(),
parser.TransportProtocol.ToString().ToUpper());
}
static void parser_ConnectionAttempt(object sender, EventArgs e)
{
// Let the user know we are attempting to connect
Console.WriteLine("Attempting connection...");
}
}
}
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<RootNamespace>DeviceToData</RootNamespace>
<AssemblyName>DeviceToData</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="GSF.Communication">
<HintPath>libs\GSF.Communication.dll</HintPath>
</Reference>
<Reference Include="GSF.Core">
<HintPath>libs\GSF.Core.dll</HintPath>
</Reference>
<Reference Include="GSF.PhasorProtocols">
<HintPath>libs\GSF.PhasorProtocols.dll</HintPath>
</Reference>
<Reference Include="GSF.TimeSeries">
<HintPath>libs\GSF.TimeSeries.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
<Target Name="Build">
<Csc Sources="@(Compile)" References="@(Reference->'%(HintPath)')" OutputAssembly="DeviceToData.exe" />
</Target>
</Project>
I receive in logs only:
Attempting connection…
Initiating IEEE C37.118.2-2011 TCP based connection…
Config Frame
GSF.PhasorProtocols.MultiProtocolFrameParser
Received configuration frame with 1 device(s)
It sends the data frame to the openPDC and PMU Connection Tester, but not to adapter.