modbus-server
Version:
TypeScript Modbus TCP Server Implementation
271 lines (192 loc) • 6.69 kB
Markdown
# 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
```bash
npm install
```
## Usage
### Basic Server
```typescript
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:
```typescript
// 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
```bash
# 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 -- --help
```
### Default Configuration
The server comes with sensible defaults:
```typescript
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
```bash
npm run build
```
### Development Mode
```bash
npm run dev
```
### Testing
```bash
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
```
### Linting
```bash
# Check for linting errors
npm run lint
# Fix linting errors
npm run lint:fix
# Format code
npm run format
```
## API Reference
### ModbusTCPServer
Main server class for handling Modbus TCP connections.
#### Constructor
```typescript
constructor(config: ModbusServerConfig)
```
#### Methods
- `start(): Promise<void>` - Start the server
- `stop(): Promise<void>` - Stop the server
- `getDataStore(): ModbusDataStore` - Get the data store instance
### ModbusDataStore
Data store for managing Modbus registers and coils.
#### Holding Registers (Read/Write)
- `setHoldingRegister(address: number, value: number): void`
- `getHoldingRegister(address: number): number`
- `setHoldingRegisters(startAddress: number, values: number[]): void`
- `getHoldingRegisters(startAddress: number, quantity: number): number[]`
#### Input Registers (Read Only)
- `setInputRegister(address: number, value: number): void`
- `getInputRegister(address: number): number`
- `getInputRegisters(startAddress: number, quantity: number): number[]`
#### Coils (Read/Write)
- `setCoil(address: number, value: boolean): void`
- `getCoil(address: number): boolean`
- `setCoils(startAddress: number, values: boolean[]): void`
- `getCoils(startAddress: number, quantity: number): boolean[]`
#### Discrete Inputs (Read Only)
- `setDiscreteInput(address: number, value: boolean): void`
- `getDiscreteInput(address: number): boolean`
- `getDiscreteInputs(startAddress: number, quantity: number): boolean[]`
#### Utility Methods
- `getAllRegisters()` - Get all register data
- `clearAllData()` - Clear all data
## Examples
### Multiple Server Instances
For applications requiring multiple Modbus servers (e.g., different inverters):
```bash
# 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=54000
```
### Environment Variables
```bash
export MODBUS_PORT=5020
export MODBUS_HOST=127.0.0.1
export MIN_REGISTER_ADDRESS=50000
export MAX_REGISTER_ADDRESS=54000
npm start
```
## License
MIT
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request
## Support
For issues and questions, please use the GitHub issue tracker.