Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

The External Server is a component of the BringAuto Fleet Protocol that handles communication between a cloud instance and multiple cars. It bridges External Clients (Module Gateway) with car modules via MQTT and dynamically loaded shared libraries.

## Common Commands

### Setup
```bash
git submodule update --init --recursive
python3 -m venv .venv && source .venv/bin/activate
pip3 install -r requirements.txt
pip install -e .
```

### Run Server
```bash
python3 -m external_server <config-path> [--tls] [--ca <path>] [--cert <path>] [--key <path>]
```

### Build Standalone Package (.pyz)
```bash
pip install shiv
shiv -e external_server.__main__:main -o external_server.pyz . -r requirements.txt --compressed
```

### Run Tests
```bash
pip install -r tests/requirements.txt
python -m tests # all tests
python -m tests server/ # specific directory
python -m tests api_access/test_api.py # specific file
python -m tests -h # with HTML coverage report
```

### Build Example Module (required for tests)
```bash
pushd tests/utils/example_module && mkdir -p _build && cd _build && \
cmake .. -DCMLIB_DIR=<path-to-cmakelib-dir> && make && popd
```

### Regenerate Protobuf Type Stubs
```bash
pushd lib/fleet-protocol/protobuf && \
find ./definition -name "*.proto" -exec protoc -I=./definition \
--python_out=./compiled/python/fleet_protocol_protobuf_files \
--pyi_out=./compiled/python/fleet_protocol_protobuf_files {} + && popd
```

## Architecture

### Threading Model
- `ExternalServer` (all_cars.py) spawns one `CarServer` thread per configured car
- Each `CarServer` (single_car.py) operates independently with its own MQTT connection and modules

### State Machine (CarServer)
`UNINITIALIZED → CONNECTED → INITIALIZED → RUNNING → STOPPED/ERROR`

### Component Layers
```
ExternalServer
└── CarServer (per car)
├── MQTTClientAdapter - Paho MQTT client wrapper (QoS 1, 15s keepalive)
├── EventQueue - Thread-safe event synchronization
├── StatusChecker / CommandChecker - Message validation
└── ServerModule (per module ID)
├── APIClientAdapter - Loads .so libraries via ctypes
└── CommandWaitingThread - Async command handling
```

### Key Directories
- `external_server/server/` - Core server logic (CarServer, ExternalServer)
- `external_server/adapters/mqtt/` - MQTT communication
- `external_server/adapters/api/` - C library interface via ctypes
- `external_server/checkers/` - Message validation and timeout handling
- `external_server/models/` - Data structures, events, exceptions

### Protocol
- Uses Fleet Protocol (Protobuf-based) over MQTT
- Protobuf definitions in `lib/fleet-protocol/` submodule
- Generated Python files in `lib/fleet-protocol/protobuf/compiled/python/`

## Configuration

Config file (`config/config.json`) defines:
- `company_name` - MQTT topic prefix (lowercase, numbers, underscores only)
- `mqtt_address`, `mqtt_port` - Broker connection
- `mqtt_timeout`, `timeout` - Message timeouts in seconds
- `common_modules` - Modules shared by all cars (keyed by module ID)
- `cars` - Per-car config with `specific_modules`

Module IDs must be unique within each car (no overlap between common and specific).
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,27 @@ Following arguments are used if argument `tls` is set:
- `--cert <str>` = path to cert file
- `--key <str>` = path to key file

## Build Standalone Package (.pyz)

The External Server can be packaged as a standalone `.pyz` file using [shiv](https://github.com/linkedin/shiv). This is useful for deployment or integration testing.

### Prerequisites

- Complete the [Install dependencies](#install-dependencies) steps
- Install shiv: `pip install shiv`

### Build

```bash
shiv -e external_server.__main__:main -o external_server.pyz . -r requirements.txt --compressed
```

This creates `external_server.pyz` which bundles the application with all dependencies. Run it with:

```bash
python3 external_server.pyz <config> [--tls] [--ca <str>] [--cert <str>] [--key <str>]
```

# Unit tests

## Necessary steps before testing
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ version = "2.2.3"


[tool.setuptools.packages.find]
include = ["external_server", "config", "docs"]
include = ["external_server", "external_server.*", "config", "docs"]