modbus-server
v1.0.0
Published
TypeScript Modbus TCP Server Implementation
Maintainers
Readme
Modbus TCP Server
A TypeScript implementation of a Modbus TCP server for industrial automation and IoT applications.
Features
- Full Modbus TCP Protocol Support: Implements all standard Modbus TCP function codes
- TypeScript: Fully typed for better development experience
- Memory Management: Efficient data store for holding registers, input registers, coils, and discrete inputs
- Configurable: Flexible configuration for ports, address ranges, and limits
- Error Handling: Comprehensive error handling with proper Modbus exception codes
- Testing: Complete test suite with Jest
- Cross-Platform: Works on Windows, Linux, and macOS
Supported Function Codes
- 0x01 - Read Coils
- 0x02 - Read Discrete Inputs
- 0x03 - Read Holding Registers
- 0x04 - Read Input Registers
- 0x05 - Write Single Coil
- 0x06 - Write Single Register
- 0x0F - Write Multiple Coils
- 0x10 - Write Multiple Registers
Installation
npm installUsage
Basic Server
import { ModbusTCPServer } from 'modbus-tcp-server';
// Simple usage with defaults
const server = new ModbusTCPServer();
// Or customize specific settings
const server = new ModbusTCPServer({
port: 5020, // Custom port
minRegisterAddress: 40001, // Start at standard holding register range
maxRegisterAddress: 40100 // Limit to 100 registers
});
// Start the server
await server.start();
// Access the data store
const dataStore = server.getDataStore();
// Set some data
dataStore.setHoldingRegister(100, 1234);
dataStore.setCoil(200, true);
// Read data directly from server
console.log('Holding Register 100:', server.getHoldingRegisterValue(100));
console.log('Coil 200:', server.getCoilValue(200));
console.log('All data:', server.getAllData());
// Stop the server
await server.stop();Reading Data
The server provides convenient methods to read data directly:
// Read individual values
const holdingValue = server.getHoldingRegisterValue(100);
const inputValue = server.getInputRegisterValue(200);
const coilValue = server.getCoilValue(300);
const discreteValue = server.getDiscreteInputValue(400);
// Read ranges
const holdingRange = server.getHoldingRegisterValues(100, 5); // Read 5 registers starting at 100
const inputRange = server.getInputRegisterValues(200, 3); // Read 3 registers starting at 200
// Get all data
const allData = server.getAllData();
// Get data summary
const summary = server.getDataSummary();
console.log(`Holding: ${summary.holdingRegisters}, Input: ${summary.inputRegisters}`);Command Line Usage
# Start with default settings (port 502)
npm start
# Start with custom port
npm start -- --port=5020
# Start with custom address range
npm start -- --min-address=50000 --max-address=54000
# Show help
npm start -- --helpDefault Configuration
The server comes with sensible defaults:
const DEFAULT_CONFIG = {
port: 502, // Standard Modbus TCP port
host: '0.0.0.0', // Listen on all interfaces
unitId: 1, // Default unit ID
maxHoldingRegisters: 10000, // Memory limits
maxInputRegisters: 10000,
maxCoils: 10000,
maxDiscreteInputs: 10000,
minRegisterAddress: 1, // Address range
maxRegisterAddress: 65535
};Configuration Options
| Option | Environment Variable | Default | Description |
|--------|---------------------|---------|-------------|
| --port | MODBUS_PORT | 502 | Server port |
| --host | MODBUS_HOST | 0.0.0.0 | Server host |
| --unit | MODBUS_UNIT_ID | 1 | Unit ID |
| --min-address | MIN_REGISTER_ADDRESS | 50000 | Minimum register address |
| --max-address | MAX_REGISTER_ADDRESS | 54000 | Maximum register address |
| --max-holding | MAX_HOLDING_REGISTERS | 10000 | Max holding registers |
| --max-input | MAX_INPUT_REGISTERS | 10000 | Max input registers |
| --max-coils | MAX_COILS | 10000 | Max coils |
| --max-discrete | MAX_DISCRETE_INPUTS | 10000 | Max discrete inputs |
Development
Build
npm run buildDevelopment Mode
npm run devTesting
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverageLinting
# Check for linting errors
npm run lint
# Fix linting errors
npm run lint:fix
# Format code
npm run formatAPI Reference
ModbusTCPServer
Main server class for handling Modbus TCP connections.
Constructor
constructor(config: ModbusServerConfig)Methods
start(): Promise<void>- Start the serverstop(): Promise<void>- Stop the servergetDataStore(): ModbusDataStore- Get the data store instance
ModbusDataStore
Data store for managing Modbus registers and coils.
Holding Registers (Read/Write)
setHoldingRegister(address: number, value: number): voidgetHoldingRegister(address: number): numbersetHoldingRegisters(startAddress: number, values: number[]): voidgetHoldingRegisters(startAddress: number, quantity: number): number[]
Input Registers (Read Only)
setInputRegister(address: number, value: number): voidgetInputRegister(address: number): numbergetInputRegisters(startAddress: number, quantity: number): number[]
Coils (Read/Write)
setCoil(address: number, value: boolean): voidgetCoil(address: number): booleansetCoils(startAddress: number, values: boolean[]): voidgetCoils(startAddress: number, quantity: number): boolean[]
Discrete Inputs (Read Only)
setDiscreteInput(address: number, value: boolean): voidgetDiscreteInput(address: number): booleangetDiscreteInputs(startAddress: number, quantity: number): boolean[]
Utility Methods
getAllRegisters()- Get all register dataclearAllData()- Clear all data
Examples
Multiple Server Instances
For applications requiring multiple Modbus servers (e.g., different inverters):
# Terminal 1: First inverter
npm start -- --port=5020 --min-address=50000 --max-address=52000
# Terminal 2: Second inverter
npm start -- --port=5021 --min-address=52001 --max-address=54000Environment Variables
export MODBUS_PORT=5020
export MODBUS_HOST=127.0.0.1
export MIN_REGISTER_ADDRESS=50000
export MAX_REGISTER_ADDRESS=54000
npm startLicense
MIT
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
Support
For issues and questions, please use the GitHub issue tracker.
