Files
thor-emitter/docs/API.md

13 KiB

SLMM API Documentation

REST API for controlling Rion NL-43/NL-53 Sound Level Meters via TCP and FTP.

Base URL: http://localhost:8000/api/nl43

All endpoints require a unit_id parameter identifying the device.

Device Configuration

Get Device Config

GET /{unit_id}/config

Returns the device configuration including host, port, and enabled protocols.

Response:

{
  "status": "ok",
  "data": {
    "unit_id": "nl43-1",
    "host": "192.168.1.100",
    "tcp_port": 2255,
    "tcp_enabled": true,
    "ftp_enabled": false,
    "web_enabled": false
  }
}

Update Device Config

PUT /{unit_id}/config

Update device configuration.

Request Body:

{
  "host": "192.168.1.100",
  "tcp_port": 2255,
  "tcp_enabled": true,
  "ftp_enabled": false,
  "ftp_username": "admin",
  "ftp_password": "password",
  "web_enabled": false
}

Important: When TCP is enabled and connection details are provided, sleep mode will be automatically disabled on the device. This is necessary because sleep/eco mode turns off TCP communications, which would prevent remote monitoring and control.

Device Status

Get Cached Status

GET /{unit_id}/status

Returns the last cached measurement snapshot from the database.

Get Live Status

GET /{unit_id}/live

Requests fresh DOD (Display On Demand) data from the device and returns current measurements.

Response:

{
  "status": "ok",
  "data": {
    "unit_id": "nl43-1",
    "measurement_state": "Measure",
    "lp": "65.2",
    "leq": "68.4",
    "lmax": "82.1",
    "lmin": "42.3",
    "lpeak": "89.5",
    "battery_level": "80",
    "power_source": "Battery",
    "sd_remaining_mb": "2048",
    "sd_free_ratio": "50"
  }
}

Stream Live Data (WebSocket)

WS /{unit_id}/live

Opens a WebSocket connection and streams continuous DRD (Display Real-time Data) from the device.

Measurement Control

Start Measurement

POST /{unit_id}/start

Starts measurement on the device.

Important: Before starting the measurement, sleep mode is automatically disabled to ensure TCP communications remain active throughout the measurement session.

Stop Measurement

POST /{unit_id}/stop

Stops measurement on the device.

Pause Measurement

POST /{unit_id}/pause

Pauses the current measurement.

Resume Measurement

POST /{unit_id}/resume

Resumes a paused measurement.

Reset Measurement

POST /{unit_id}/reset

Resets the measurement data.

Get Measurement State

GET /{unit_id}/measurement-state

Gets the current measurement state to determine if the device is actively measuring.

Response:

{
  "status": "ok",
  "measurement_state": "Start",
  "is_measuring": true
}

Values:

  • measurement_state: "Start" (measuring) or "Stop" (not measuring)
  • is_measuring: Boolean convenience field (true if measuring, false otherwise)

Note: Elapsed time and interval counts are displayed on the device OSD but not available via command. Track elapsed time in your application by recording the start time when you call the /start endpoint.

Manual Store

POST /{unit_id}/store

Manually stores the current measurement data.

Device Information

Get Battery Level

GET /{unit_id}/battery

Returns the battery level.

Response:

{
  "status": "ok",
  "battery_level": "80"
}

Get Clock

GET /{unit_id}/clock

Returns the device clock time.

Response:

{
  "status": "ok",
  "clock": "2025/12/24,02:30:15"
}

Set Clock

PUT /{unit_id}/clock

Sets the device clock time.

Request Body:

{
  "datetime": "2025/12/24,02:30:15"
}

Measurement Settings

Get Frequency Weighting

GET /{unit_id}/frequency-weighting?channel=Main

Gets the frequency weighting (A, C, or Z) for a channel.

Query Parameters:

  • channel (optional): Main, Sub1, Sub2, or Sub3 (default: Main)

Response:

{
  "status": "ok",
  "frequency_weighting": "A",
  "channel": "Main"
}

Set Frequency Weighting

PUT /{unit_id}/frequency-weighting

Sets the frequency weighting.

Request Body:

{
  "weighting": "A",
  "channel": "Main"
}

Get Time Weighting

GET /{unit_id}/time-weighting?channel=Main

Gets the time weighting (F, S, or I) for a channel.

Query Parameters:

  • channel (optional): Main, Sub1, Sub2, or Sub3 (default: Main)

Response:

{
  "status": "ok",
  "time_weighting": "F",
  "channel": "Main"
}

Set Time Weighting

PUT /{unit_id}/time-weighting

Sets the time weighting.

Request Body:

{
  "weighting": "F",
  "channel": "Main"
}

Values:

  • F - Fast (125ms)
  • S - Slow (1s)
  • I - Impulse (35ms)

Timing and Interval Configuration

Get Measurement Time

GET /{unit_id}/measurement-time

Gets the current measurement time preset.

Response:

{
  "status": "ok",
  "measurement_time": "1h"
}

Set Measurement Time

PUT /{unit_id}/measurement-time

Sets the measurement time preset.

Request Body:

{
  "preset": "1h"
}

Preset Values:

  • 10s, 1m, 5m, 10m, 15m, 30m, 1h, 8h, 24h
  • Custom format: HH:MM:SS (e.g., 00:05:30 for 5.5 minutes)

Get Leq Calculation Interval

GET /{unit_id}/leq-interval

Gets the current Leq calculation interval.

Response:

{
  "status": "ok",
  "leq_interval": "1m"
}

Set Leq Calculation Interval

PUT /{unit_id}/leq-interval

Sets the Leq calculation interval preset.

Request Body:

{
  "preset": "1m"
}

Preset Values:

  • Off, 10s, 1m, 5m, 10m, 15m, 30m, 1h, 8h, 24h
  • Custom format: HH:MM:SS (e.g., 00:05:30 for 5.5 minutes)

Get Lp Store Interval

GET /{unit_id}/lp-interval

Gets the current Lp store interval.

Response:

{
  "status": "ok",
  "lp_interval": "1s"
}

Set Lp Store Interval

PUT /{unit_id}/lp-interval

Sets the Lp store interval.

Request Body:

{
  "preset": "1s"
}

Preset Values:

  • Off, 10ms, 25ms, 100ms, 200ms, 1s

Get Index Number

GET /{unit_id}/index-number

Gets the current index number for file numbering.

Response:

{
  "status": "ok",
  "index_number": "0042"
}

Set Index Number

PUT /{unit_id}/index-number

Sets the index number for file numbering. This number is incremented with each measurement and used in file names.

Request Body:

{
  "index": 42
}

Valid Range: 0000 to 9999

Device Settings Query

Get All Settings

GET /{unit_id}/settings/all

Retrieves all current device settings for verification. This is useful for confirming device configuration before starting measurements.

Response:

{
  "status": "ok",
  "settings": {
    "measurement_state": "Stop",
    "frequency_weighting": "A",
    "time_weighting": "F",
    "measurement_time": "1h",
    "leq_interval": "1m",
    "lp_interval": "1s",
    "index_number": "0042",
    "battery_level": "80",
    "clock": "2025/12/24,02:30:15",
    "sleep_mode": "Off",
    "ftp_status": "Off"
  }
}

Note: If any setting query fails, the error message will be included in the response for that setting (e.g., "frequency_weighting": "Error: Connection timeout").

Data Retrieval

Get Final Results

GET /{unit_id}/results

Retrieves the final calculation results (DLC) from the last completed measurement.

Response:

{
  "status": "ok",
  "data": {
    "leq": "68.4",
    "lmax": "82.1",
    "lmin": "42.3",
    "lpeak": "89.5"
  }
}

Power Management

Sleep Device

POST /{unit_id}/sleep

Enables Sleep Mode on the device. When enabled, the device will automatically enter sleep mode between Timer Auto measurements.

Note: This is a SETTING, not a command to sleep immediately. Sleep Mode only applies when using Timer Auto measurements.

Warning: Sleep/eco mode turns off TCP communications, which will prevent remote monitoring and control. For this reason, SLMM automatically disables sleep mode when:

  • Device configuration is created or updated with TCP enabled
  • Measurements are started

If you need to enable sleep mode for battery conservation, be aware that TCP connectivity will be lost until the device is physically accessed or wakes for a scheduled measurement.

Wake Device

POST /{unit_id}/wake

Disables Sleep Mode on the device.

Get Sleep Status

GET /{unit_id}/sleep/status

Gets the current Sleep Mode status.

Response:

{
  "status": "ok",
  "sleep_mode": "Off"
}

FTP File Management

Enable FTP

POST /{unit_id}/ftp/enable

Enables FTP server on the device.

Note: FTP and TCP are mutually exclusive. Enabling FTP will temporarily disable TCP control. As of v0.2.0, FTP and TCP are working fine in tandem. Just dont spam them a bunch.

Disable FTP

POST /{unit_id}/ftp/disable

Disables FTP server on the device.

Get FTP Status

GET /{unit_id}/ftp/status

Checks if FTP is enabled on the device.

Response:

{
  "status": "ok",
  "ftp_status": "On",
  "ftp_enabled": true
}

List Files

GET /{unit_id}/ftp/files?path=/

Lists files and directories at the specified path.

Query Parameters:

  • path (optional): Directory path to list (default: /)

Response:

{
  "status": "ok",
  "path": "/NL43_DATA/",
  "count": 3,
  "files": [
    {
      "name": "measurement_001.wav",
      "path": "/NL43_DATA/measurement_001.wav",
      "size": 102400,
      "modified": "Dec 24 2025",
      "is_dir": false
    },
    {
      "name": "folder1",
      "path": "/NL43_DATA/folder1",
      "size": 0,
      "modified": "Dec 23 2025",
      "is_dir": true
    }
  ]
}

Download File

POST /{unit_id}/ftp/download

Downloads a file from the device via FTP.

Request Body:

{
  "remote_path": "/NL43_DATA/measurement_001.wav"
}

Response: Returns the file as a binary download with appropriate Content-Disposition header.

Error Responses

All endpoints return standard HTTP status codes:

  • 200 - Success
  • 404 - Device config not found
  • 403 - TCP communication is disabled
  • 502 - Failed to communicate with device
  • 504 - Device communication timeout
  • 500 - Internal server error

Error Response Format:

{
  "detail": "Error message"
}

Common Patterns

Terra-view Integration Example

const devices = ['nl43-1', 'nl43-2', 'nl43-3'];

// Configure all devices before measurement
for (const device of devices) {
  // Set measurement time to 12 hours
  await fetch(`http://localhost:8000/api/nl43/${device}/measurement-time`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ preset: '12h' })
  });

  // Set Leq interval to 1 minute
  await fetch(`http://localhost:8000/api/nl43/${device}/leq-interval`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ preset: '1m' })
  });

  // Set index number for daily file organization
  const dayNumber = new Date().getDate();
  await fetch(`http://localhost:8000/api/nl43/${device}/index-number`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ index: dayNumber })
  });

  // Verify all settings are correct
  const settings = await fetch(`http://localhost:8000/api/nl43/${device}/settings/all`)
    .then(r => r.json());
  console.log(`Device ${device} settings:`, settings.settings);
}

// Start measurement on all devices at 7pm
await Promise.all(
  devices.map(id =>
    fetch(`http://localhost:8000/api/nl43/${id}/start`, { method: 'POST' })
  )
);

// Get live status from all devices
const statuses = await Promise.all(
  devices.map(id =>
    fetch(`http://localhost:8000/api/nl43/${id}/live`)
      .then(r => r.json())
  )
);

// Download files from all devices the next morning
for (const device of devices) {
  // Enable FTP
  await fetch(`http://localhost:8000/api/nl43/${device}/ftp/enable`, {
    method: 'POST'
  });

  // List files in device data directory
  const res = await fetch(`http://localhost:8000/api/nl43/${device}/ftp/files?path=/NL43_DATA`);
  const { files } = await res.json();

  // Download latest measurement file
  const latestFile = files
    .filter(f => !f.is_dir)
    .sort((a, b) => b.modified - a.modified)[0];

  if (latestFile) {
    const download = await fetch(`http://localhost:8000/api/nl43/${device}/ftp/download`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ remote_path: latestFile.path })
    });

    const blob = await download.blob();
    // Save to local storage or process...
  }

  // Disable FTP to re-enable TCP
  await fetch(`http://localhost:8000/api/nl43/${device}/ftp/disable`, {
    method: 'POST'
  });
}

Rate Limiting

The NL43 protocol requires ≥1 second between commands to the same device. The API automatically enforces this rate limit.

Notes

  • TCP and FTP protocols are mutually exclusive on the device
  • FTP uses active mode (requires device to connect back to server)
  • WebSocket streaming keeps a persistent connection - limit concurrent streams
  • All measurements are stored in the database for quick access via /status endpoint