Skip to content
Jonathan0823Public

About

FastAPI-based Modbus TCP/RTU gateway. Features database-driven config, dynamic device management, automated polling, caching, MQTT publishing, and hot-reload

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Repository files navigation

NexusBus

NexusBus: A robust FastAPI-based middleware for Modbus TCP/RTU, offering a database-driven gateway for seamless data integration. It provides dynamic device management via REST API, automated polling with in-memory caching, real-time MQTT publishing, and hot-reload capabilities for configurations.

Python FastAPI PostgreSQL SQLModel Pymodbus License


πŸ“š Documentation Navigation

Quick Start Device Management Polling MQTT Monitoring Migrations
Database Setup Device API Guide Polling Config MQTT Guide Metrics & Monitoring Migration Guide
  • βœ… Database-Driven Configuration - Store and manage Modbus devices in PostgreSQL
  • βœ… Dynamic Device Management - Add/update/remove devices via REST API without restart
  • βœ… Automatic Polling - Configure registers to poll automatically from database
  • βœ… Parallel Polling - Poll multiple devices concurrently for improved performance
  • βœ… Hot-Reload - Apply configuration changes without server restart
  • βœ… Connection Pooling - Efficiently manage Modbus TCP connections & shared gateways
  • βœ… Circuit Breaker - Automatic failure detection with fast-fail and auto-recovery
  • βœ… Request Timeout Handling - Automatic timeout and connection reset
  • βœ… REST API - Complete API for device interaction and management
  • βœ… Async Support - Full async/await with asyncpg for optimal performance
  • βœ… Smart Caching - Register value caching with TTL and automatic eviction
  • βœ… MQTT Integration - Real-time data publishing to MQTT brokers
  • βœ… Soft Delete - Deactivate devices/polling without losing configuration
  • βœ… Structured Logging - JSON-formatted logs for easy parsing and monitoring
  • βœ… Metrics Collection - Built-in metrics for performance monitoring
  • βœ… Enhanced Health Checks - Comprehensive health monitoring for all services
  • βœ… Input Validation - Robust validation for all API inputs

πŸš€ Quick Start

1. Installation

# Clone repository
git clone https://github.com/Jonathan0823/nexusbus.git
cd nexusbus

# Create virtual environment
python -m venv venv
.\venv\Scripts\Activate.ps1  # Windows PowerShell
# source venv/bin/activate    # Linux/Mac

# Install dependencies
pip install -r requirements.txt

2. Database Setup

Configure Environment:

cp .env.example .env
# Edit .env with your PostgreSQL credentials

Run Migrations:

python migrate.py

This creates:

  • βœ… modbus_devices table with sample devices
  • βœ… polling_targets table with sample polling configs

Full Migration Guide β†’

3. Start Application

uvicorn main:app --reload

Access:

4. Run with Docker (Recommended) 🐳

For easier setup and deployment, you can use Docker Compose to run the application and its PostgreSQL database.

docker-compose up -d

This command will:

  • Build the nexusbus_app Docker image and start the container.
  • Create and start a PostgreSQL database container (nexusbus_db).
  • Automatically run database migrations.
  • Expose the application on port 8000.

Access:

  • API: http://localhost:8000
  • Interactive Docs: http://localhost:8000/docs
  • Health Check: http://localhost:8000/health

To stop the services:

docker-compose down

πŸ“– API Quick Reference

Device Operations

Endpoint Method Description Docs
/api/devices GET List devices β†’
/api/devices/{id}/registers GET Read registers β†’
/api/devices/{id}/registers/write POST Write register β†’
/api/devices/gateways GET Gateway status β†’

Admin - Device Management

Endpoint Method Description Docs
/api/admin/devices GET List all devices β†’
/api/admin/devices POST Create device β†’
/api/admin/devices/{id} PUT Update device β†’
/api/admin/devices/{id} DELETE Soft delete β†’
/api/admin/devices/reload POST Hot-reload configs β†’

Admin - Polling Management

Endpoint Method Description Docs
/api/admin/polling GET List polling targets β†’
/api/admin/polling POST Create polling target β†’
/api/admin/polling/{id} PUT Update target β†’
/api/admin/polling/{id} DELETE Soft delete β†’

Admin - Cache Management

Endpoint Method Description Docs
/api/admin/cache GET Inspect all cache -
/api/admin/cache/stats GET Cache statistics -
/api/admin/cache/device/{id} GET Inspect device cache -
/api/admin/cache DELETE Clear all cache -

Metrics & Monitoring

Endpoint Method Description Docs
/api/metrics GET Get all application metrics -
/api/metrics/reset POST Reset metrics (testing) -
/health GET Comprehensive health check -

Complete API Documentation β†’


πŸ“¦ Configuration

Environment Variables

This application uses a .env file for configuration. Copy .env.example to .env to start.

Database Configuration

Variable Description Default
DATABASE_URL PostgreSQL connection string. postgresql+asyncpg://postgres:postgres@localhost:5432/modbus_db
DATABASE_ECHO If true, logs SQL queries. false

MQTT Configuration (Optional)

Variable Description Default
MQTT_BROKER_HOST Broker hostname/IP. Set to enable MQTT. None
MQTT_BROKER_PORT Broker port number. 1883
MQTT_USERNAME MQTT Username. None
MQTT_PASSWORD MQTT Password. None
MQTT_TOPIC_PREFIX Prefix for published topics. modbus/data

Application Settings

Variable Description Default
APP_NAME Application name. NexusBus
APP_VERSION Application version. 0.1.0
POLL_INTERVAL_SECONDS Polling interval for background service. 5
CACHE_TTL_SECONDS Cache entry time-to-live in seconds. 300

Logging Configuration

Variable Description Default
LOG_LEVEL Logging level (DEBUG, INFO, WARNING, ERROR). INFO
LOG_JSON Output logs in JSON format (for production). false
LOG_INCLUDE_CALLER Include caller information in logs. true

Circuit Breaker Configuration

Variable Description Default
CIRCUIT_BREAKER_FAILURE_THRESHOLD Consecutive failures before opening. 5
CIRCUIT_BREAKER_RECOVERY_TIMEOUT Seconds before attempting recovery. 30

Device Parameters

Parameter Type Required Description Default
device_id string βœ… Unique device identifier -
host string βœ… IP address or hostname -
port integer βœ… TCP port (e.g., 502, 8899) -
slave_id integer βœ… Modbus slave ID (1-247) -
timeout integer ❌ Connection timeout (seconds) 10
framer string ❌ RTU, SOCKET, or ASCII RTU
max_retries integer ❌ Max retry attempts (0-10) 5
retry_delay float ❌ Delay between retries (seconds) 0.1

Note: All inputs are validated automatically:

  • slave_id: Must be between 1-247 (Modbus specification)
  • port: Must be between 1-65535
  • framer: Must be one of RTU, SOCKET, or ASCII
  • timeout: Must be between 1-300 seconds
  • max_retries: Must be between 0-10

Full Configuration Guide β†’


πŸ’‘ Usage Examples

Read Registers

# Read 10 holding registers starting at address 0
curl "http://localhost:8000/api/devices/office-eng/registers?address=0&count=10"

# Read from cache (faster, uses polling data)
curl "http://localhost:8000/api/devices/office-eng/registers?address=0&count=10&source=cache"

Write Register

curl -X POST http://localhost:8000/api/devices/office-eng/registers/write \
  -H "Content-Type: application/json" \
  -d '{"address": 10, "value": 123, "register_type": "holding"}'

Create Device

curl -X POST http://localhost:8000/api/admin/devices \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": "warehouse-1",
    "host": "192.168.1.100",
    "port": 502,
    "slave_id": 3,
    "framer": "SOCKET"
  }'

# Reload to apply changes
curl -X POST http://localhost:8000/api/admin/devices/reload

More Examples β†’

Configure Polling

# Create polling target
curl -X POST http://localhost:8000/api/admin/polling \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": "office-eng",
    "register_type": "holding",
    "address": 0,
    "count": 10,
    "description": "Main control registers"
  }'

# Changes apply automatically (hot-reload)
# Wait 5 seconds, then check cache
curl "http://localhost:8000/api/devices/office-eng/registers?address=0&count=10&source=cache"

Polling Guide β†’


πŸ—‚οΈ Project Structure

modbus_middleware/
β”œβ”€β”€ .env.example                       # Environment variables template
β”œβ”€β”€ DATABASE_SETUP.md                  # Setup guide & docs index
β”œβ”€β”€ main.py                            # Application entry point
β”œβ”€β”€ migrate.py                         # Main migration runner
β”œβ”€β”€ requirements.txt                   # Python dependencies
β”‚
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ dependencies.py               # Dependency injection
β”‚   β”œβ”€β”€ schemas.py                    # Pydantic schemas
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ admin_routes.py           # Admin device management
β”‚   β”‚   β”œβ”€β”€ cache_routes.py           # Admin cache inspection
β”‚   β”‚   β”œβ”€β”€ metrics_routes.py         # Metrics endpoint
β”‚   β”‚   β”œβ”€β”€ polling_routes.py         # Admin polling management
β”‚   β”‚   └── routes.py                 # Device API endpoints
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   └── devices.py                # Device configuration loader
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ cache.py                  # Register caching with TTL
β”‚   β”‚   β”œβ”€β”€ config.py                 # Application settings
β”‚   β”‚   β”œβ”€β”€ logging_config.py         # Structured logging configuration
β”‚   β”‚   β”œβ”€β”€ metrics.py                # Metrics collection
β”‚   β”‚   β”œβ”€β”€ modbus_client.py          # Modbus client manager
β”‚   β”‚   └── mqtt_client.py            # MQTT client manager
β”‚   β”œβ”€β”€ database/
β”‚   β”‚   β”œβ”€β”€ __init__.py
β”‚   β”‚   β”œβ”€β”€ connection.py             # Database connection
β”‚   β”‚   β”œβ”€β”€ crud.py                   # CRUD operations
β”‚   β”‚   └── models.py                 # SQLModel database models
β”‚   └── services/
β”‚       β”œβ”€β”€ __init__.py
β”‚       └── poller.py                 # Background polling service
β”‚
β”œβ”€β”€ docs/                              # Documentation
β”‚   β”œβ”€β”€ CACHE_INSPECTION_GUIDE.md     # Cache debugging guide
β”‚   β”œβ”€β”€ DEVICE_MANAGEMENT.md          # Device API guide
β”‚   β”œβ”€β”€ METRICS_AND_MONITORING.md     # Metrics and monitoring guide
β”‚   β”œβ”€β”€ MQTT_INTEGRATION.md           # MQTT integration guide
β”‚   β”œβ”€β”€ POLLING_CONFIGURATION.md      # Polling guide
β”‚   └── POLLING_QUICK_START.md        # Quick polling guide
β”‚
└── migrations/                        # Database migrations
    β”œβ”€β”€ README.md                     # Migration guide
    β”œβ”€β”€ base.py                       # Migration utilities
    β”œβ”€β”€ 001_initial_setup.py          # Migration: Create devices table
    └── 002_add_polling_targets.py    # Migration: Create polling table

🎯 Key Features Explained

Hot-Reload Configuration

No restart needed!

# 1. Add device
curl -X POST /api/admin/devices -d '{...}'

# 2. Reload (applies instantly)
curl -X POST /api/admin/devices/reload

# 3. Use immediately
curl "http://localhost:8000/api/devices/new-device/registers?..."

Polling auto-reloads every cycle (default: 5 seconds).

Learn More β†’

Automatic Polling

Configure registers to poll automatically and serve from cache:

# Configure polling via database
POST /api/admin/polling

# Data polled every 5 seconds
# Access cached data (fast!)
GET /api/devices/{id}/registers?source=cache

Polling Guide β†’

Connection Management

  • Shared Gateways: Multiple devices on same gateway share one connection
  • Circuit Breaker: After 5 failures, requests fast-fail with 503 for 30s, then auto-retry
  • Auto Recovery: Timeout handling with automatic reconnection
  • Request Serialization: Prevents slave ID conflicts
  • Thread Pooling: Non-blocking Modbus operations

Architecture Details β†’


πŸ§ͺ Testing

# 1. Check health
curl http://localhost:8000/health

# 2. List devices
curl http://localhost:8000/api/admin/devices

# 3. Test read
curl "http://localhost:8000/api/devices/office-eng/registers?address=0&count=10"

# 4. Check gateway status
curl http://localhost:8000/api/devices/gateways

Full Testing Guide β†’


πŸ”§ Development

Running in Development

uvicorn main:app --reload --log-level debug

Creating New Migrations

# Create migration file
cp migrations/001_initial_setup.py migrations/003_my_feature.py

# Edit the migration
# Update migrate.py to include it

# Run it
python migrate.py --migration 003

Migration Guide β†’


⚠️ Important Notes

Always Reload After Device Changes

# ❌ WRONG - changes won't apply
curl -X POST /api/admin/devices -d '{...}'

# βœ… CORRECT - reload to apply
curl -X POST /api/admin/devices -d '{...}'
curl -X POST /api/admin/devices/reload

Polling Auto-Reloads

Polling configuration reloads automatically every polling cycle. No manual reload needed for polling!

Soft Delete

  • DELETE endpoints set is_active=false (preserves data)
  • Reactivate with /activate endpoint
  • Data remains in database for audit trail

πŸ“š Learn More

By Topic

By Task

I want to... Read this
Set up the database DATABASE_SETUP.md
Add a new device Device Creation Guide
Configure polling Polling Configuration
Monitor performance Metrics & Monitoring
Set up logging Metrics & Monitoring
Create a migration Migration Guide
Troubleshoot issues Troubleshooting

🚨 Troubleshooting

Database Connection Issues

Check .env configuration:

DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/modbus_db

If database is unavailable, app falls back to hardcoded configs in app/config/devices.py.

More Help β†’

Device Not Found

Did you forget to reload?

curl -X POST http://localhost:8000/api/admin/devices/reload

Modbus Timeout

  1. Check device connectivity: ping {host}
  2. Verify port is open
  3. Confirm slave_id is correct
  4. Check gateway status: GET /api/devices/gateways
  5. Increase timeout via Admin API

Troubleshooting Guide β†’


πŸ“ License

Apache License 2.0 (Copyright (c) 2025 Eguin Jonathan)


πŸ”— Quick Links


Built with ❀️ using FastAPI, PostgreSQL, SQLModel, pymodbus, and MQTT

About

FastAPI-based Modbus TCP/RTU gateway. Features database-driven config, dynamic device management, automated polling, caching, MQTT publishing, and hot-reload

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages