I’m trying to create a PMU simulator for my uni project. I connected to the PMU Connection tester and trying to send Config Frame 2 in PMU Connction tester, but it says: ‘Command “SendConfigurationFrame2” requested at 21.04.2025 17:16:52’ and nothing happens. Still ‘awaiting for configuration frame…’. This is my code:
const net = require('net');
const crc = require('crc');
const HOST = '127.0.0.1';
const PORT = 4712;
const DEVICE_ID = 2;
const FRAMES_PER_SECOND = 60;
// Helper func for big-endian values
function writeUInt16BE(val) {
const buf = Buffer.alloc(2);
buf.writeUInt16BE(val);
return buf;
}
function writeUInt32BE(val) {
const buf = Buffer.alloc(4);
buf.writeUInt32BE(val);
return buf;
}
// CRC-16-CCITT calculation
function calcCRC(buf) {
const crcVal = crc.crc16ccitt(buf, 0xFFFF);
const crcBuf = Buffer.alloc(2);
crcBuf.writeUInt16BE(crcVal);
return crcBuf;
}
// Build some config frame for tests
function buildConfigFrame() {
const now = new Date();
const soc = Math.floor(now.getTime() / 1000); // Current Unix timestamp
const fracsec = Math.floor((now.getMilliseconds() * 1000000) / 1000); // Microseconds
const payloadParts = [
writeUInt16BE(DEVICE_ID), // IDCODE
writeUInt32BE(soc), // SOC
writeUInt32BE(fracsec), // FRACSEC
writeUInt16BE(0x0004), // Frame type = CONFIG-2
writeUInt32BE(1000000), // TIME_BASE (1,000,000 µs)
writeUInt16BE(1), // NUM_PMU
Buffer.from('PMU1'.padEnd(16, ' ')), // Station name
writeUInt16BE(DEVICE_ID), // PMU ID
writeUInt16BE(0x0001), // FMT: floating-point, rectangular
writeUInt16BE(1), // PHNMR: 1 phasor
writeUInt16BE(0), // ANNMR: 0 analogs
writeUInt16BE(0), // DGNMR: 0 digitals
writeUInt16BE(FRAMES_PER_SECOND), // DATA_RATE (60 Hz)
Buffer.from('VA'.padEnd(16, ' ')), // Phasor name
writeUInt32BE(0x00010000), // Phasor conversion factor
writeUInt16BE(60), // Nominal frequency
writeUInt16BE(1), // CFGCNT
];
const payload = Buffer.concat(payloadParts);
const sync = Buffer.from([ 0xAA, 0x01 ]); // SYNC for CONFIG
const frameSize = 2 + 2 + payload.length + 2; // SYNC + FRAMESIZE + payload + CRC
const frameWithoutCRC = Buffer.concat([ sync, writeUInt16BE(frameSize), payload ]);
const crcBuf = calcCRC(frameWithoutCRC);
return Buffer.concat([ frameWithoutCRC, crcBuf ]);
}
// Server
const server = net.createServer(socket => {
console.log('✅ Tester connected');
// Send initial CONFIG-2 frame
const configFrame = buildConfigFrame();
socket.write(configFrame);
console.log(`📡 Sent initial CONFIG-2 frame: ${configFrame.toString('hex')}`);
socket.on('data', data => {
console.log(`📥 Received from tester: ${data.toString('hex')}`);
if ( data.length >= 16 ) {
const commandCode = data.readUInt16BE(14);
if ( commandCode === 0x0001 ) {
console.log('Received START command - configuration accepted!');
} else if ( commandCode === 0x0005 ) {
console.log('Received request for CONFIG-2 frame');
const newConfigFrame = buildConfigFrame();
socket.write(newConfigFrame);
console.log(`📡 Sent CONFIG-2 frame in response: ${newConfigFrame.toString('hex')}`);
} else {
console.log(`Unexpected command code: 0x${commandCode.toString(16)}`);
}
}
});
socket.on('end', () => console.log('🔌 Connection closed'));
});
server.listen(PORT, () => console.log(`📡 PMU Simulator running on port ${PORT}`));