@raydotac/mcprotocol
v1.0.4
Published
Mitsubishi MC Protocol implementation for Node.js - TypeScript and JavaScript versions. Inspired by pymcprotocol with support for iQ-R, Q, iQ-L, L, and QnA series PLCs.
Downloads
239
Maintainers
Readme
MC Protocol Library for Node.js
A comprehensive Node.js library for communicating with Mitsubishi PLCs using the MC Protocol. This library provides both JavaScript and TypeScript implementations, inspired by the popular Python pymcprotocol library.
Features
✅ Dual Implementation: Both JavaScript and TypeScript versions
✅ Multiple PLC Support: iQ-R, Q, iQ-L, L, and QnA series
✅ Frame Support: 3E and 4E frame types
✅ Hexadecimal Addresses: Full support for hex addresses like B41A, XFF, Y1A0
✅ Type Safety: Full TypeScript support with type definitions
✅ Modern API: Promise-based with async/await
✅ Batch Operations: Optimized reading/writing of multiple registers
✅ Error Handling: Comprehensive error reporting
✅ Production Ready: Inspired by proven pymcprotocol library
Installation
npm install @raydotac/mcprotocolQuick Start
TypeScript Usage (Recommended)
import { MCProtocol } from '@raydotac/mcprotocol';
async function main() {
const plc = new MCProtocol({
host: '192.168.1.100',
port: 5002,
plcType: 'iQ-R'
});
try {
await plc.connect();
// Read single register
const value = await plc.readRegister('D', 100);
console.log('D100:', value);
// Read hex address registers
const hexValue = await plc.readRegister('B', '41A');
console.log('B41A:', hexValue);
// Read multiple registers (pymcprotocol style) - supports hex!
const values = await plc.plcRead(['D0', 'D1', 'B41A', 'B23B', 'XFF']);
console.log('Values:', values);
// Batch read (optimized)
const batchResult = await plc.batchReadWordUnits([
{ device: 'D', address: 100 },
{ device: 'D', address: 101 },
{ device: 'M', address: 0 }
]);
// Write register
await plc.writeRegister('D', 200, 12345);
} finally {
await plc.disconnect();
}
}JavaScript Usage
const { Type4E, PLC_TYPES } = require('@raydotac/mcprotocol');
async function main() {
const plc = new Type4E(PLC_TYPES.iQR);
try {
await plc.connect('192.168.1.100', 5002);
// Read 10 registers starting from D0
const values = await plc.batchread_wordunits('D0', 10);
console.log('D0-D9:', values);
} finally {
plc.close();
}
}API Reference
TypeScript API (MCProtocol class)
Constructor Options
interface MCProtocolOptions {
host: string; // PLC IP address
port: number; // PLC port (usually 5002)
timeout?: number; // Connection timeout (default: 5000ms)
plcType?: 'Q' | 'iQ-R' | 'iQ-L' | 'L' | 'QnA'; // PLC series
frame?: '3E' | '4E'; // Frame type (default: '3E')
}Methods
connect(): Promise<void>- Connect to PLCdisconnect(): Promise<void>- Disconnect from PLCreadRegister(device: string, address: number | string): Promise<number>- Read single registerwriteRegister(device: string, address: number | string, value: number): Promise<void>- Write single registerplcRead(registers: string[]): Promise<number[]>- Read multiple registers (pymcprotocol style)batchReadWordUnits(addresses: DeviceAddress[]): Promise<ReadResult>- Optimized batch readbatchWriteWordUnits(data: WriteData[]): Promise<void>- Optimized batch write
JavaScript API (Type4E class)
Constructor
const plc = new Type4E(plcType); // plcType: PLC_TYPES.iQR or PLC_TYPES.QMethods
connect(ip: string, port: number): Promise<void>- Connect to PLCclose(): void- Close connectionbatchread_wordunits(device: string, count: number): Promise<number[]>- Read word units
Supported Devices
| Device | Description | Address Format | Example | |--------|-------------|----------------|---------| | D | Data registers | Decimal | D0, D100, D1000 | | R | File registers | Decimal | R0, R100 | | ZR | Extension file registers | Hexadecimal | ZR0, ZR100 | | M | Internal relays | Decimal | M0, M100 | | X | Input contacts | Hexadecimal | X0, XFF, X1A0 | | Y | Output contacts | Hexadecimal | Y0, YFF, Y1A0 | | B | Link relays | Hexadecimal | B0, B41A, B23B | | W | Link registers | Hexadecimal | W0, WFF, W1000 |
Hexadecimal Address Support 🆕
This library now supports hexadecimal addresses commonly used in real-world PLC applications. Many device types (like B, X, Y, W) use hexadecimal addressing in practice.
Address Formats
// Numeric addresses (traditional)
await plc.readRegister('D', 100); // D100 (decimal)
await plc.readRegister('B', 1050); // B1050 (decimal)
// String addresses with automatic base detection
await plc.readRegister('D', '100'); // D100 (decimal string)
await plc.readRegister('B', '41A'); // B41A (hex string → decimal 1050)
// Register strings (pymcprotocol style)
await plc.plcRead(['D100', 'B41A', 'B23B', 'XFF', 'Y1A0']);Supported Hex Devices
Devices that use hexadecimal addressing (base 16):
- X, Y: Input/Output contacts -
XFF,Y1A0 - B: Link relays -
B41A,B23B - W: Link registers -
WFF,W1000 - SB, SW: Special registers -
SBFF,SWFF - DX, DY: Direct I/O -
DXFF,DYFF - ZR: Extension file registers -
ZR1000
Devices that use decimal addressing (base 10):
- D, R: Data/File registers -
D100,R200 - M: Internal relays -
M100 - T, C: Timers/Counters -
T100,C200
Examples
// Real-world hexadecimal addresses
const values = await plc.plcRead([
'B41A', // Link relay at hex 41A (decimal 1050)
'B23B', // Link relay at hex 23B (decimal 571)
'XFF', // Input contact at hex FF (decimal 255)
'Y1A0', // Output contact at hex 1A0 (decimal 416)
'D100' // Data register at decimal 100
]);
// Batch operations with mixed formats
await plc.batchReadWordUnits([
{ device: 'B', address: '41A' }, // Hex string
{ device: 'D', address: 100 }, // Numeric
{ device: 'X', address: 'FF' }, // Hex string
{ device: 'D', address: '200' } // Decimal string
]);
// Case-insensitive hex addresses
await plc.readRegister('B', '41a'); // Same as 'B41A'
await plc.readRegister('B', '41A'); // Same as 'B41a'Supported PLC Series
- iQ-R Series: High-performance PLCs (default)
- Q Series: Standard PLCs
- iQ-L Series: Compact PLCs
- L Series: Basic PLCs
- QnA Series: Legacy PLCs
Error Handling
import { MCProtocolError } from '@raydotac/mcprotocol';
try {
await plc.readRegister('D', 0);
} catch (error) {
if (error instanceof MCProtocolError) {
console.log('PLC Error:', error.message);
console.log('Error Code:', error.errorCode);
}
}Examples
Reading Multiple Device Types
const results = await plc.batchReadWordUnits([
{ device: 'D', address: 0 }, // Data register
{ device: 'M', address: 0 }, // Internal relay
{ device: 'X', address: 0 }, // Input contact
{ device: 'Y', address: 0 } // Output contact
]);Batch Writing
await plc.batchWriteWordUnits([
{ device: 'D', address: 100, value: 1234 },
{ device: 'D', address: 101, value: 5678 },
{ device: 'D', address: 102, value: 9012 }
]);Using with Different PLC Types
// For Q Series PLC
const qPlc = new MCProtocol({
host: '192.168.1.100',
port: 5002,
plcType: 'Q',
frame: '3E'
});
// For iQ-L Series PLC
const iqlPlc = new MCProtocol({
host: '192.168.1.101',
port: 5002,
plcType: 'iQ-L'
});Network Configuration
Ensure your PLC has MC Protocol enabled:
- iQ-R Series: Enable "MC Protocol" in the Ethernet module settings
- Q Series: Configure the Ethernet module for MC Protocol communication
- Default Port: 5002 (can be configured in PLC settings)
Comparison with pymcprotocol
This library provides similar functionality to the Python pymcprotocol:
| Feature | pymcprotocol (Python) | This Library (Node.js) | |---------|----------------------|------------------------| | Device Support | ✅ D, M, X, Y, R, etc. | ✅ D, M, X, Y, R, etc. | | PLC Series | ✅ iQ-R, Q, L | ✅ iQ-R, Q, iQ-L, L, QnA | | Frame Types | ✅ 3E, 4E | ✅ 3E, 4E | | Batch Operations | ✅ | ✅ Enhanced | | Type Safety | ❌ | ✅ Full TypeScript | | Error Handling | ✅ | ✅ Enhanced |
Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests.
License
MIT License - see LICENSE file for details.
Acknowledgments
- Inspired by the excellent Python
pymcprotocollibrary - Mitsubishi Electric for MC Protocol specifications
- Community feedback and contributions
Note: This library requires an actual Mitsubishi PLC with MC Protocol enabled for real communication. For testing without hardware, consider using a PLC simulator.
