#beacon #server-api #usb #patlite

app patlite-beacon-serv

RESTful API server for controlling PATLITE USB beacons with comprehensive light patterns, sequences, and buzzer control

1 unstable release

Uses new Rust 2024

0.1.0 Sep 12, 2025

#343 in HTTP server

Download history 128/week @ 2025-09-10 12/week @ 2025-09-17 1/week @ 2025-09-24 13/week @ 2025-10-01

154 downloads per month

MIT license

63KB
1K SLoC

PATLITE Beacon Server

A RESTful API server for controlling PATLITE USB beacons using the rust-patlite-beacon crate.

Features

  • Complete RESTful API for all PATLITE beacon functions
  • Optional API key authentication for secure access
  • Single light control with 5 colors (Red, Yellow, Green, Blue, White)
  • 6 light patterns including solid, blink, flash, and custom patterns
  • Sequential light commands with precise timing control
  • Looping or one-shot sequences for complex light shows
  • 8 buzzer patterns including melodies (London Bridge, Shining Star)
  • Automatic timeouts for both lights and buzzers
  • Real-time status monitoring via REST endpoints
  • Touch sensor support - Press the beacon button to instantly clear all outputs
  • Background task management for sequences and timeouts
  • Test sequence functionality for hardware validation

Requirements

  • PATLITE USB beacon device (USB HID)
  • Rust 1.70 or later
  • Linux/macOS/Windows with USB support

Installation

From Source

git clone https://github.com/yourusername/patlite-beacon-serv.git
cd patlite-beacon-serv
cargo build --release

The compiled binary will be in target/release/patlite-beacon-serv

Usage

Basic Usage

Run the server with default settings (localhost:38861):

cargo run
# or
./target/release/patlite-beacon-serv

Command Line Options

patlite-beacon-serv [OPTIONS]

Options:
  --host <HOST>          Host address to bind to [default: 127.0.0.1]
  --port <PORT>          Port to listen on [default: 38861]
  --api-key <API_KEY>    API key for authentication (optional)
  -h, --help             Print help
  -V, --version          Print version

Examples

Run on all interfaces with custom port:

./patlite-beacon-serv --host 0.0.0.0 --port 8080

Run with API key authentication:

./patlite-beacon-serv --api-key my-secret-key

Docker Support (Optional)

FROM rust:1.70 as builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y libusb-1.0-0 && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/patlite-beacon-serv /usr/local/bin/
EXPOSE 38861
CMD ["patlite-beacon-serv", "--host", "0.0.0.0"]

Quick Start

  1. Connect your PATLITE USB beacon to your computer
  2. Build and run the server:
    cargo run
    
  3. Test the connection:
    # Turn on red light
    curl -X PUT http://localhost:38861/light \
      -H "Content-Type: application/json" \
      -d '{"color": "red", "mode": "on"}'
    
    # Play a melody
    curl -X PUT http://localhost:38861/buzzer \
      -H "Content-Type: application/json" \
      -d '{"pattern": "london_bridge", "volume": 60}'
    
    # Clear everything
    curl -X POST http://localhost:38861/clear
    

API Documentation

Base URL

http://localhost:38861

Authentication

All endpoints support optional API key authentication via the ?apiKey=<key> query parameter if the server was started with an API key.

Example:

curl http://localhost:38861/status?apiKey=my-secret-key

Status Endpoints

GET / or GET /status

Returns the current status of the light, sequence, and buzzer.

Response:

{
  "light": {
    "color": "red",
    "mode": "on",
    "active": true,
    "remaining_ms": 5000
  },
  "sequence": {
    "commands": [
      {"color": "red", "mode": "on", "duration_ms": 3000},
      {"color": "blue", "mode": "flash", "duration_ms": 3000}
    ],
    "current_index": 0,
    "loop_sequence": true,
    "active": true
  },
  "buzzer": {
    "active": false,
    "pattern": null,
    "volume": 50
  },
  "connected": true,
  "last_updated": "2025-01-10T12:00:00Z"
}

Light Control Endpoints

PUT /light

Set the light to a specific color and mode with optional duration.

Request Body:

{
  "color": "red",  // One of: red, yellow, amber, green, blue, white, clear
  "mode": "pattern3",  // One of: off, on, solid, pattern1-6, blink, flash
  "duration_ms": 5000  // Optional, in milliseconds
}

Available Modes:

  • off - Light is off
  • on or solid - Light is continuously on
  • pattern1 or blink - Pattern 1 (slow blink)
  • pattern2 or flash - Pattern 2 (fast flash)
  • pattern3 - Pattern 3
  • pattern4 - Pattern 4
  • pattern5 - Pattern 5
  • pattern6 - Pattern 6

Response: Current beacon status

Example:

curl -X PUT http://localhost:38861/light \
  -H "Content-Type: application/json" \
  -d '{"color": "red", "mode": "flash", "duration_ms": 10000}'

DELETE /light

Turn off the current light.

Response: Current beacon status

Example:

curl -X DELETE http://localhost:38861/light

Sequence Endpoints

POST /sequence

Start a sequence of light commands that execute one after another.

Request Body:

{
  "commands": [
    {
      "color": "red",
      "mode": "on",
      "duration_ms": 3000
    },
    {
      "color": "blue",
      "mode": "flash",
      "duration_ms": 3000
    },
    {
      "color": "green",
      "mode": "blink",
      "duration_ms": 2000
    }
  ],
  "loop_sequence": true  // Optional, defaults to true. If false, sequence runs once
}

Response: Current beacon status

Example (looping sequence):

curl -X POST http://localhost:38861/sequence \
  -H "Content-Type: application/json" \
  -d '{
    "commands": [
      {"color": "red", "mode": "on", "duration_ms": 3000},
      {"color": "blue", "mode": "flash", "duration_ms": 3000}
    ],
    "loop_sequence": true
  }'

Example (one-shot sequence):

curl -X POST http://localhost:38861/sequence \
  -H "Content-Type: application/json" \
  -d '{
    "commands": [
      {"color": "red", "mode": "on", "duration_ms": 1000},
      {"color": "yellow", "mode": "on", "duration_ms": 1000},
      {"color": "green", "mode": "on", "duration_ms": 1000}
    ],
    "loop_sequence": false
  }'

DELETE /sequence

Stop the current running sequence.

Response: Current beacon status

Example:

curl -X DELETE http://localhost:38861/sequence

POST /update

Trigger an update of the sequence state (advances to next command if current duration has elapsed).

Response: Current beacon status

Example:

curl -X POST http://localhost:38861/update

Buzzer Control Endpoints

PUT /buzzer

Activate the buzzer with a specific pattern.

Request Body:

{
  "pattern": "strong_attention",  // See available patterns below
  "volume": 75,         // Optional, 0-100
  "duration_ms": 5000   // Optional, in milliseconds
}

Available Patterns:

  • off - No sound
  • on or continuous - Continuous tone
  • sweep - Sweeping sound pattern
  • intermittent - Intermittent beeping
  • weak_attention or weak or chirp - Weak attention sound (gentle chirp)
  • strong_attention or strong or alarm - Strong attention sound (alarm)
  • shining_star - "Shining Star" melody
  • london_bridge - "London Bridge" melody

Response: Current beacon status

Example:

curl -X PUT http://localhost:38861/buzzer \
  -H "Content-Type: application/json" \
  -d '{"pattern": "strong_attention", "volume": 80, "duration_ms": 10000}'

Example with melody:

curl -X PUT http://localhost:38861/buzzer \
  -H "Content-Type: application/json" \
  -d '{"pattern": "london_bridge", "volume": 60}'

DELETE /buzzer

Stop the buzzer.

Response: Current beacon status

Example:

curl -X DELETE http://localhost:38861/buzzer

POST /buzzer/pattern

Play a custom buzzer pattern with specific frequencies.

Request Body:

{
  "pattern": [
    {
      "frequency_hz": 1000,
      "duration_ms": 200,
      "pause_ms": 100
    },
    {
      "frequency_hz": 1500,
      "duration_ms": 200,
      "pause_ms": 100
    }
  ],
  "repetitions": 3,
  "volume": 60  // Optional, 0-100
}

Response: Current beacon status

Example:

curl -X POST http://localhost:38861/buzzer/pattern \
  -H "Content-Type: application/json" \
  -d '{
    "pattern": [
      {"frequency_hz": 800, "duration_ms": 250, "pause_ms": 150},
      {"frequency_hz": 1200, "duration_ms": 250, "pause_ms": 150}
    ],
    "repetitions": 2,
    "volume": 70
  }'

Utility Endpoints

POST /clear

Turn off the light, stop any running sequence, and stop the buzzer.

Response: Current beacon status

Example:

curl -X POST http://localhost:38861/clear

POST /test

Run a test sequence that cycles through all light colors.

Response:

{
  "success": true,
  "results": [
    "Test sequence started",
    "Step 1 executed",
    "Step 2 executed",
    "Step 3 executed",
    "Step 4 executed",
    "Step 5 executed"
  ]
}

Example:

curl -X POST http://localhost:38861/test

Advanced Usage

API Authentication

When the server is started with the --api-key parameter, all API endpoints require authentication:

# Start server with API key
./patlite-beacon-serv --api-key my-secret-key

# Make authenticated request
curl http://localhost:38861/status?apiKey=my-secret-key

Without the correct API key, requests will return 401 Unauthorized.

Touch Sensor Integration

The server automatically monitors the beacon's touch sensor. When pressed:

  • All lights turn off immediately
  • Any running sequence stops
  • All buzzer sounds stop
  • Server logs: "Touch sensor pressed - clearing all outputs"

This provides a hardware "panic button" for instant shutdown of all beacon activity.

Sequence Programming

Create complex light shows with sequences:

# Traffic light sequence (loops forever)
curl -X POST http://localhost:38861/sequence \
  -H "Content-Type: application/json" \
  -d '{
    "commands": [
      {"color": "red", "mode": "on", "duration_ms": 3000},
      {"color": "yellow", "mode": "on", "duration_ms": 1000},
      {"color": "green", "mode": "on", "duration_ms": 3000}
    ],
    "loop_sequence": true
  }'

# Alert sequence (runs once)
curl -X POST http://localhost:38861/sequence \
  -H "Content-Type: application/json" \
  -d '{
    "commands": [
      {"color": "red", "mode": "pattern3", "duration_ms": 500},
      {"color": "blue", "mode": "pattern3", "duration_ms": 500}
    ],
    "loop_sequence": false
  }'

Automatic Timeouts

Both lights and buzzers support automatic timeouts:

# Red light for exactly 5 seconds
curl -X PUT http://localhost:38861/light \
  -H "Content-Type: application/json" \
  -d '{"color": "red", "mode": "on", "duration_ms": 5000}'

# Alarm for 10 seconds
curl -X PUT http://localhost:38861/buzzer \
  -H "Content-Type: application/json" \
  -d '{"pattern": "strong_attention", "volume": 80, "duration_ms": 10000}'

After the specified duration, the light/buzzer automatically turns off without affecting other active components.

Data Types

Light Modes

  • off: Light is turned off
  • on: Light is continuously on
  • flash: Light flashes rapidly
  • blink: Light blinks slowly

Light Colors

  • red
  • yellow or amber
  • green
  • blue
  • white or clear

Buzzer Patterns

  • off - No sound
  • on or continuous - Continuous tone
  • sweep - Sweeping sound pattern
  • intermittent - Intermittent beeping
  • weak_attention (aliases: weak, chirp) - Gentle attention sound
  • strong_attention (aliases: strong, alarm) - Strong alarm sound
  • shining_star - Plays "Shining Star" melody
  • london_bridge - Plays "London Bridge" melody

Error Responses

The API returns appropriate HTTP status codes:

  • 200 OK: Successful operation
  • 400 Bad Request: Invalid parameters or request body
  • 401 Unauthorized: Invalid or missing API key (when authentication is enabled)
  • 500 Internal Server Error: Server or beacon communication error

Troubleshooting

Common Issues

  1. "Device not found" error

    • Ensure the PATLITE beacon is connected via USB
    • Check USB permissions on Linux: sudo usermod -a -G dialout $USER
    • May need to logout/login after adding user to dialout group
  2. "Resource busy" error

    • Another application may be using the beacon
    • Check if another instance of the server is running: ps aux | grep patlite
  3. Touch sensor not working

    • The touch sensor monitoring requires the beacon to support this feature
    • Check server logs for "Touch sensor monitoring enabled" message
  4. API returns 401 Unauthorized

    • Verify you're using the correct API key in the query parameter
    • Check server startup logs for the API key if auto-generated

Development

Building from Source

git clone https://github.com/yourusername/patlite-beacon-serv.git
cd patlite-beacon-serv
cargo build --release

Running Tests

cargo test

Code Structure

src/
├── main.rs          # Server initialization and route handlers
├── beacon.rs        # Beacon controller logic
├── api.rs           # API types and serialization
└── auth.rs          # Authentication middleware

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: cargo test
  5. Submit a pull request

License

MIT License

Copyright (c) 2025 Benjamin Burkhart

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Dependencies

~10–22MB
~286K SLoC