SLMM - Sound Level Meter Manager

Backend API service for controlling and monitoring Rion NL-43/NL-53 Sound Level Meters via TCP and FTP protocols.

Overview

SLMM is a standalone backend module that provides REST API routing and command translation for NL43/NL53 sound level meters. This service acts as a bridge between the hardware devices and frontend applications, handling all device communication, data persistence, and protocol management.

Note: This is a backend-only service. Actual user interfacing is done via SFM/Terra-View frontend applications.

Features

  • Device Management: Configure and manage multiple NL43/NL53 devices
  • Real-time Monitoring: Stream live measurement data via WebSocket
  • Measurement Control: Start, stop, pause, resume, and reset measurements
  • Data Retrieval: Access current and historical measurement snapshots
  • FTP Integration: Download measurement files directly from devices
  • Device Configuration: Manage frequency/time weighting, clock sync, and more
  • Rate Limiting: Automatic 1-second delay enforcement between device commands
  • Persistent Storage: SQLite database for device configs and measurement cache

Architecture

┌─────────────────┐         ┌──────────────┐         ┌─────────────────┐
│  Terra-View UI  │◄───────►│  SLMM API    │◄───────►│  NL43/NL53      │
│  (Frontend)     │  HTTP   │  (Backend)   │  TCP    │  Sound Meters   │
└─────────────────┘         └──────────────┘         └─────────────────┘
                                    │
                                    ▼
                            ┌──────────────┐
                            │  SQLite DB   │
                            │  (Cache)     │
                            └──────────────┘

Quick Start

Prerequisites

  • Python 3.10+
  • pip package manager

Installation

  1. Clone the repository:
git clone <repository-url>
cd slmm
  1. Install dependencies:
pip install -r requirements.txt

Running the Server

# Development mode with auto-reload
uvicorn app.main:app --reload --port 8100

# Production mode
uvicorn app.main:app --host 0.0.0.0 --port 8100

The API will be available at http://localhost:8100

API Documentation

Once running, visit:

  • Swagger UI: http://localhost:8100/docs
  • ReDoc: http://localhost:8100/redoc
  • Health Check: http://localhost:8100/health

Configuration

Environment Variables

  • PORT: Server port (default: 8100)
  • CORS_ORIGINS: Comma-separated list of allowed origins (default: "*")

Database

The SQLite database is automatically created at data/slmm.db on first run.

Logging

Logs are written to:

API Endpoints

Device Configuration

Method Endpoint Description
GET /api/nl43/{unit_id}/config Get device configuration
PUT /api/nl43/{unit_id}/config Update device configuration

Device Status

Method Endpoint Description
GET /api/nl43/{unit_id}/status Get cached measurement snapshot
GET /api/nl43/{unit_id}/live Request fresh DOD data from device
WS /api/nl43/{unit_id}/stream WebSocket stream for real-time DRD data

Measurement Control

Method Endpoint Description
POST /api/nl43/{unit_id}/start Start measurement
POST /api/nl43/{unit_id}/stop Stop measurement
POST /api/nl43/{unit_id}/pause Pause measurement
POST /api/nl43/{unit_id}/resume Resume paused measurement
POST /api/nl43/{unit_id}/reset Reset measurement data
POST /api/nl43/{unit_id}/store Manually store data to SD card

Device Information

Method Endpoint Description
GET /api/nl43/{unit_id}/battery Get battery level
GET /api/nl43/{unit_id}/clock Get device clock time
PUT /api/nl43/{unit_id}/clock Set device clock time
GET /api/nl43/{unit_id}/results Get final calculation results (DLC)

Measurement Settings

Method Endpoint Description
GET /api/nl43/{unit_id}/settings Get all current device settings for verification
GET /api/nl43/{unit_id}/frequency-weighting Get frequency weighting (A/C/Z)
PUT /api/nl43/{unit_id}/frequency-weighting Set frequency weighting
GET /api/nl43/{unit_id}/time-weighting Get time weighting (F/S/I)
PUT /api/nl43/{unit_id}/time-weighting Set time weighting

Sleep Mode

Method Endpoint Description
POST /api/nl43/{unit_id}/sleep Put device into sleep mode
POST /api/nl43/{unit_id}/wake Wake device from sleep
GET /api/nl43/{unit_id}/sleep/status Get sleep mode status

FTP File Management

Method Endpoint Description
POST /api/nl43/{unit_id}/ftp/enable Enable FTP server on device
POST /api/nl43/{unit_id}/ftp/disable Disable FTP server on device
GET /api/nl43/{unit_id}/ftp/status Get FTP server status
GET /api/nl43/{unit_id}/ftp/files List files on device
POST /api/nl43/{unit_id}/ftp/download Download file from device

For detailed API documentation and examples, see API.md.

Project Structure

slmm/
├── app/
│   ├── __init__.py          # Package initialization
│   ├── main.py              # FastAPI application and startup
│   ├── routers.py           # API route definitions
│   ├── models.py            # SQLAlchemy database models
│   ├── services.py          # NL43Client and business logic
│   └── database.py          # Database configuration
├── data/
│   ├── slmm.db              # SQLite database (auto-created)
│   ├── slmm.log             # Application logs
│   └── downloads/           # Downloaded files from devices
├── templates/
│   └── index.html           # Simple web interface (optional)
├── manuals/                 # Device documentation
├── API.md                   # Detailed API documentation
├── COMMUNICATION_GUIDE.md   # NL43 protocol documentation
├── NL43_COMMANDS.md         # Command reference
├── requirements.txt         # Python dependencies
└── README.md                # This file

Database Schema

NL43Config Table

Stores device connection configuration:

  • unit_id (PK): Unique device identifier
  • host: Device IP address or hostname
  • tcp_port: TCP control port (default: 80)
  • tcp_enabled: Enable/disable TCP communication
  • ftp_enabled: Enable/disable FTP functionality
  • ftp_username: FTP authentication username
  • ftp_password: FTP authentication password
  • web_enabled: Enable/disable web interface access

NL43Status Table

Caches latest measurement snapshot:

  • unit_id (PK): Unique device identifier
  • last_seen: Timestamp of last update
  • measurement_state: Current state (Measure/Stop)
  • lp: Instantaneous sound pressure level
  • leq: Equivalent continuous sound level
  • lmax: Maximum sound level
  • lmin: Minimum sound level
  • lpeak: Peak sound level
  • battery_level: Battery percentage
  • power_source: Current power source
  • sd_remaining_mb: Free SD card space (MB)
  • sd_free_ratio: SD card free space ratio
  • raw_payload: Raw device response data

Protocol Details

TCP Communication

  • Uses ASCII command protocol over TCP
  • Enforces ≥1 second delay between commands to same device
  • Two-line response format:
    • Line 1: Result code (R+0000 for success)
    • Line 2: Data payload (for query commands)

FTP Communication

  • Uses active mode FTP (requires device to connect back)
  • TCP and FTP are mutually exclusive on the device
  • Credentials configurable per device

Data Formats

DOD (Data Output Display): Snapshot of current display values DRD (Data Real-time Display): Continuous streaming data DLC (Data Last Calculation): Final stored measurement results

Example Usage

Configure a Device

curl -X PUT http://localhost:8100/api/nl43/meter-001/config \
  -H "Content-Type: application/json" \
  -d '{
    "host": "192.168.1.100",
    "tcp_port": 2255,
    "tcp_enabled": true,
    "ftp_username": "admin",
    "ftp_password": "password"
  }'

Start Measurement

curl -X POST http://localhost:8100/api/nl43/meter-001/start

Get Live Status

curl http://localhost:8100/api/nl43/meter-001/live

Verify Device Settings

curl http://localhost:8100/api/nl43/meter-001/settings

This returns all current device configuration:

{
  "status": "ok",
  "unit_id": "meter-001",
  "settings": {
    "measurement_state": "Stop",
    "frequency_weighting": "A",
    "time_weighting": "F",
    "measurement_time": "00:01:00",
    "leq_interval": "1s",
    "lp_interval": "125ms",
    "index_number": "0",
    "battery_level": "100%",
    "clock": "2025/12/24,20:45:30",
    "sleep_mode": "Off",
    "ftp_status": "On"
  }
}

Stream Real-time Data (JavaScript)

const ws = new WebSocket('ws://localhost:8100/api/nl43/meter-001/stream');

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Live measurement:', data);
};

Download Files via FTP

# Enable FTP
curl -X POST http://localhost:8100/api/nl43/meter-001/ftp/enable

# List files
curl http://localhost:8100/api/nl43/meter-001/ftp/files?path=/NL43_DATA

# Download file
curl -X POST http://localhost:8100/api/nl43/meter-001/ftp/download \
  -H "Content-Type: application/json" \
  -d '{"remote_path": "/NL43_DATA/measurement.wav"}' \
  --output measurement.wav

# Disable FTP
curl -X POST http://localhost:8100/api/nl43/meter-001/ftp/disable

Integration with Terra-View

This backend is designed to be consumed by the Terra-View frontend application. The frontend should:

  1. Use the config endpoints to register and configure devices
  2. Poll or stream live status for real-time monitoring
  3. Use control endpoints to manage measurements
  4. Download files via FTP endpoints for analysis

See API.md for detailed integration examples.

Troubleshooting

Connection Issues

  • Verify device IP address and port in configuration
  • Ensure device is on the same network
  • Check firewall rules allow TCP/FTP connections
  • Verify RX55 network adapter is properly configured on device

Rate Limiting

  • API automatically enforces 1-second delay between commands
  • If experiencing delays, this is normal device behavior
  • Multiple devices can be controlled in parallel

FTP Active Mode

  • Ensure server can accept incoming connections from device
  • FTP uses active mode (device connects back to server)
  • May require firewall configuration for data channel

WebSocket Disconnects

  • WebSocket streams maintain persistent connection
  • Limit concurrent streams to avoid device overload
  • Connection will auto-close if device stops responding

Development

Running Tests

# Add test commands when implemented
pytest

Database Migrations

# Migrate existing database to add FTP credentials
python migrate_add_ftp_credentials.py

# Set FTP credentials for a device
python set_ftp_credentials.py <unit_id> <username> <password>

Contributing

This is a standalone module kept separate from the SFM/Terra-View codebase. When contributing:

  1. Maintain separation from frontend code
  2. Follow existing API patterns and error handling
  3. Update API documentation for new endpoints
  4. Ensure rate limiting is enforced for device commands

License

[Specify license here]

Support

For issues and questions:

  • Backend API issues: This repository
  • Frontend/UI issues: Terra-View repository
  • Device protocol questions: See COMMUNICATION_GUIDE.md
Description
Sound Level Meter Manager
Readme 502 KiB
Languages
Python 76.7%
HTML 21.1%
Shell 2%
Dockerfile 0.2%