Skip to main content

Python library for controlling Sirena carbot features over USB via LUCI_local protocol

Project description

sirena-carbot

A Python library for controlling Sirena carbot features over USB using the LUCI_local protocol.


Table of Contents


Overview

sirena-carbot is a pip-installable Python library that lets you control car features (windows, mirrors, child lock, etc.) by sending LUCI_local commands to a carbot USB device over a serial connection.

Each control function follows a simple on/off pattern:

front_right_window_up(1)   # ON  → sends command over USB
front_right_window_up(0)   # OFF → placeholder, does nothing

Requirements

  • Python 3.8 or higher
  • A Sirena carbot USB device connected to your machine
  • pyserial (installed automatically as a dependency)

Installation

pip install sirena-carbot

Installing from source (for development)

git clone https://github.com/your-org/sirena-carbot.git
cd sirena-carbot
pip install -e .

Quick Start

from sirena_carbot import *

enable_rx_monitor()        # opens a separate terminal showing RX data
connect()                  # auto-detects USB port

front_right_window_up(1)
mirror_fold(1)
child_lock_on(1)

disconnect()

Wildcard import

from sirena_carbot import *

Imports all public names: connect, disconnect, list_ports, enable_rx_monitor, all window / mirror / child-lock functions.


Connecting to the Device

Auto-detect port (recommended)

connect()

Specify port manually

connect("COM3")                      # Windows
connect("/dev/ttyUSB0")              # Linux
connect("/dev/tty.usbserial-0001")   # macOS

List available ports

ports = list_ports()
for p in ports:
    print(p['port'], '-', p['description'])

Connection parameters

Parameter Value
Baud rate 57600
Data bits 8
Parity None
Stop bits 1

RX Monitor

Call enable_rx_monitor() before connect() to automatically open a separate terminal window that displays all incoming serial data from the device in real time.

from sirena_carbot import *

enable_rx_monitor()   # ← opens a new cmd window showing live RX data
connect()

front_right_window_up(1)

The monitor window looks like:

=== Sirena Carbot — RX Monitor ===

[12:34:01] RX: OK
[12:34:01] RX: LUCI_ACK 245
[12:34:02] RX: window_up done

How it works internally:

  • Opens a local socket server on a free port
  • Launches sirena_carbot/_rx_monitor.py in a new cmd window connected to that socket
  • Attaches a log callback to SerialManager that forwards every RX line to the monitor window

Available Controls

All control functions accept state=1 (send command) or state=0 (no-op placeholder).

Return value: True if the command was sent successfully, False otherwise.

success = front_right_window_up(1)
if not success:
    print("Command failed – is the device connected?")

Window Controls

# Function Command sent (state=1)
1 front_right_window_up(1) LUCI_local 245 front_right_window_up
2 front_right_window_down(1) LUCI_local 245 front_right_window_down
3 front_left_window_up(1) LUCI_local 245 front_left_window_up
4 front_left_window_down(1) LUCI_local 245 front_left_window_down
5 rear_right_window_up(1) LUCI_local 245 rear_right_window_up
6 rear_right_window_down(1) LUCI_local 245 rear_right_window_down
7 rear_left_window_up(1) LUCI_local 245 rear_left_window_up
8 rear_left_window_down(1) LUCI_local 245 rear_left_window_down

Mirror Controls

# Function Command sent (state=1)
9 mirror_fold(1) LUCI_local 245 mirror_fold
10 mirror_unfold(1) LUCI_local 245 mirror_unfold

Child Lock Controls

# Function Command sent (state=1)
11 child_lock_on(1) LUCI_local 245 child_lock_on
12 child_lock_off(1) LUCI_local 245 child_lock_off

How Commands Work

When you call a control function with state=1, the library sends a plain-text command over USB:

LUCI_local 245 <command_name>\n

When called with state=0, nothing is sent — it is a placeholder for future OFF implementation.

Parameter Value
Protocol LUCI_local
Target 245
Encoding UTF-8
Line ending \n

Testing the Library

A test script is included at the root of the repository: test_library.py

import time
from sirena_carbot import *

enable_rx_monitor()
connect()

front_right_window_up(1);    time.sleep(5)
front_right_window_down(1);  time.sleep(5)
front_left_window_up(1);     time.sleep(5)
front_left_window_down(1);   time.sleep(5)
rear_right_window_up(1);     time.sleep(5)
rear_right_window_down(1);   time.sleep(5)
rear_left_window_up(1);      time.sleep(5)
rear_left_window_down(1);    time.sleep(5)
mirror_fold(1);              time.sleep(5)
mirror_unfold(1);            time.sleep(5)
child_lock_on(1);            time.sleep(5)
child_lock_off(1);           time.sleep(5)

disconnect()

Run it:

python test_library.py
  • Sends all 12 commands with a 5-second gap between each for safety
  • RX responses appear live in the separate monitor window
  • Main terminal stays silent

Adding New Controls

Add one line in sirena_carbot/controls.py:

horn          = _make_control("horn")
headlights_on = _make_control("headlights_on")
door_lock     = _make_control("door_lock")
door_unlock   = _make_control("door_unlock")

Then export in sirena_carbot/__init__.py:

from .controls import (
    # existing...
    horn,
    headlights_on,
    door_lock,
    door_unlock,
)

__all__ = [
    # existing...
    "horn",
    "headlights_on",
    "door_lock",
    "door_unlock",
]

Publishing Updates to PyPI

First time setup

  1. Create an account at https://pypi.org
  2. Go to Account Settings → API tokens → Add API token
  3. Copy the token (starts with pypi-)
  4. Save in ~/.pypirc:
[distutils]
index-servers = pypi

[pypi]
username = __token__
password = pypi-YOUR_TOKEN_HERE

Release workflow

# 1. Bump version in pyproject.toml AND sirena_carbot/__init__.py

# 2. Clean old build artifacts
Remove-Item -Recurse -Force dist, build, *.egg-info

# 3. Build
python -m build

# 4. Upload
python -m twine upload dist/*

Version numbering

Change type Example
Bug fix 1.0.01.0.1
New functions added 1.0.01.1.0
Breaking / major changes 1.0.02.0.0

PyPI does not allow re-uploading the same version. Always bump before uploading.


Project Structure

carbot_software/
├── pyproject.toml                   # Package metadata and build config
├── README.md                        # This file
├── test_library.py                  # Test script (sends all commands)
├── serial_communication.py          # Low-level USB serial driver
└── sirena_carbot/
    ├── __init__.py                  # Public API
    ├── connection.py                # Connection manager + enable_rx_monitor()
    ├── controls.py                  # Control functions (_make_control factory)
    └── _rx_monitor.py               # RX monitor window (launched automatically)

Key classes (internal)

Class File Responsibility
SerialManager serial_communication.py Opens port, reads/writes bytes, manages threads
ServoController serial_communication.py Builds SetServoPartial commands

Changelog

v1.0.0

  • Added enable_rx_monitor() — opens a live RX data window in a separate terminal
  • Added mirror controls: mirror_fold, mirror_unfold
  • Added child lock controls: child_lock_on, child_lock_off
  • from sirena_carbot import * supported via __all__
  • Test script simplified to 15 lines with 5-second safety delay between commands

v0.1.1

  • Fixed pyproject.toml build backend (setuptools.build_meta)

v0.1.0

  • Initial release: window controls, connect, disconnect, list_ports

Troubleshooting

RuntimeError: No serial ports found

  • Make sure the carbot USB device is plugged in
  • Specify port manually: connect("COM3")
  • Linux/macOS: sudo usermod -aG dialout $USER then log out and back in

Error: Not connected to serial port

Always call connect() before any control function:

from sirena_carbot import *
connect()
front_right_window_up(1)

Command returns False

  • Check the USB cable
  • Ensure connect() returned True
  • Reconnect:
    disconnect()
    connect()
    

RX Monitor window does not open

  • Ensure you called enable_rx_monitor() before connect()
  • Windows only: requires cmd.exe — not supported in Linux/macOS as-is

Wrong COM port selected automatically

for p in list_ports():
    print(p)

connect("COM5")

state=0 does nothing — is that a bug?

No. state=0 is intentionally a placeholder until the firmware implements OFF behaviour.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sirena_carbot-1.0.1.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sirena_carbot-1.0.1-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file sirena_carbot-1.0.1.tar.gz.

File metadata

  • Download URL: sirena_carbot-1.0.1.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for sirena_carbot-1.0.1.tar.gz
Algorithm Hash digest
SHA256 c821c1c1b0014b599bba10e8591151976abd9a53f586009b56fdb9fe8bfead89
MD5 2731eed74a78cc50bb0b3b802aee2908
BLAKE2b-256 076e5189ce28783434186d9b03854ff5765e9d33f6b887c22da530b5d67b2cfc

See more details on using hashes here.

File details

Details for the file sirena_carbot-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: sirena_carbot-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for sirena_carbot-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8cb54f0b333710719360998acd5ea680fc58afa6a8d491c67bf51cb3a8f66733
MD5 3f9cfce614470fcafbdf11c4be443e8e
BLAKE2b-256 7c81d8589e46612bc0e6f29a291041753b4e76fc05dba9735c8b273443adbcd9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page