Skip to content

CiTBIN Backend API

The CiTBIN Backend is the central component of the platform. It receives sensor data from the MQTT broker, decodes incoming payloads, processes measurements, stores them in PostgreSQL, and exposes a REST API for the frontend and other clients.

The backend is built with FastAPI and follows a modular architecture to make it easy to integrate new sensor types, waste bin models, and processing logic.


Features

  • FastAPI REST API
  • MQTT client for mioty sensor communication
  • Automatic payload decoding
  • Device management
  • Waste bin management
  • Historical measurement storage
  • PostgreSQL integration
  • Automatic database migrations
  • OpenAPI documentation
  • Modular sensor architecture
  • Extensible payload processing
  • Unit testing

Technology Stack

ComponentTechnology
LanguagePython 3.11+
FrameworkFastAPI
DatabasePostgreSQL
ORMSQLModel / SQLAlchemy
MigrationsAlembic
MQTTPaho MQTT
ASGI ServerUvicorn
Production ServerGunicorn

Architecture

text
                   MQTT Broker


                MQTT Client Service


                Payload Decoder


                Sensor Factory

          ┌──────────────┴──────────────┐
          ▼                             ▼
   Sensor Implementation         Trash Bin Factory
          │                             │
          └──────────────┬──────────────┘

                 Business Services

                PostgreSQL Database

                    REST API

                    Web Frontend

Project Structure

text
apps/api/

├── api/
│   ├── device_service.py
│   ├── trashbin_service.py
│   ├── trashbin_repository.py
│   ├── device_repository.py
│   └── mioty_service.py

├── models/

├── modules/
│   ├── sensors/
│   ├── trashbins/
│   ├── payload_decoder.py
│   ├── process_data.py
│   ├── sensor_factory.py
│   ├── trashbin_factory.py
│   ├── auto_migrate.py
│   └── postgresql.py

├── routers/

├── migrations/

├── tests/

└── app.py

Core Components

app.py

Application entry point.

Responsible for:

  • starting FastAPI
  • configuring logging
  • loading environment variables
  • connecting to PostgreSQL
  • running database migrations
  • connecting to the MQTT broker
  • registering API routes
  • enabling CORS

MQTT Service

The MQTT service establishes a connection to the configured broker and subscribes to incoming mioty messages.

Responsibilities:

  • broker connection
  • reconnect handling
  • message reception
  • forwarding payloads to the processing pipeline

The MQTT service acts as the bridge between the physical sensor network and the backend.


Payload Decoder

Incoming MQTT payloads are not directly stored.

Instead they are:

  • validated
  • decoded
  • normalized
  • converted into internal data models

This allows the backend to support multiple sensor manufacturers without changing the API.


Sensor Factory

The Sensor Factory determines which sensor implementation should process an incoming payload.

Advantages:

  • easy extension
  • manufacturer independence
  • clean separation of logic
  • reusable sensor implementations

Adding a new sensor usually requires:

  1. creating a new sensor class
  2. implementing the decoder
  3. registering it in the factory

No other backend logic should require modification.


Trash Bin Factory

The Trash Bin Factory contains waste-bin-specific logic.

Different waste bins may calculate fill levels differently or expose additional metadata.

The factory keeps this logic isolated from the rest of the backend.


Business Services

Business services contain the application logic.

Examples include:

  • creating devices
  • updating measurements
  • validating requests
  • assigning devices to waste bins

Repositories are responsible only for database access.


Database

The backend uses PostgreSQL together with SQLModel.

Main entities include:

Device

Stores information about installed sensor devices.

Examples:

  • device identifier
  • hardware information
  • battery status
  • assigned waste bin

Trash Bin

Represents a physical waste bin.

Typical information:

  • name
  • location
  • coordinates
  • type
  • current fill level

Measurement History

Stores historical measurements received from sensors.

Typical data:

  • timestamp
  • fill level
  • measured distance
  • battery information
  • signal quality

Historical data allows long-term analysis and visualization.


REST API

The backend exposes a versioned REST API.

/api/v1/

Examples include:

GET    /trashbin
POST   /trashbin

GET    /devices
POST   /devices

GET    /trashbin-data

Interactive documentation is automatically generated by FastAPI.

http://localhost:8000/api/docs

Local Development

Requirements

  • Python 3.11+
  • PostgreSQL
  • Docker
  • UV (recommended)

Installation

Clone the repository.

Create the environment file.

cp .env.example .env

Install dependencies.

uv sync

Running the Backend

Start the API using Uvicorn.

uv run uvicorn app:app --reload

During startup the backend automatically:

  • loads configuration
  • configures logging
  • runs Alembic migrations
  • connects to PostgreSQL
  • establishes the MQTT connection
  • registers all routes

Development Infrastructure

The infrastructure project provides PostgreSQL and supporting services.

Start it with Docker Compose.

cd ../../infrastructure

docker compose up -d

Database Migrations

Apply pending migrations.

uv run alembic upgrade head

Create a migration.

uv run alembic revision --autogenerate -m "Description"

Rollback one migration.

uv run alembic downgrade -1

View migration history.

uv run alembic history

Testing

Run all tests.

uv run pytest

Run with coverage.

uv run pytest --cov=. --cov-report html

Logging

The backend provides structured logging.

Logging includes:

  • startup information
  • MQTT events
  • database connections
  • API requests
  • warnings
  • errors

Log files are automatically rotated to prevent unlimited growth.


Adding a New Sensor

The backend is designed to support multiple sensor manufacturers.

Typical workflow:

  1. Create a new sensor implementation inside modules/sensors/.
  2. Implement payload decoding.
  3. Register the sensor inside the Sensor Factory.
  4. Test using simulated MQTT messages.
  5. Verify measurements appear in the frontend.

No API changes are usually required.


Troubleshooting

Backend cannot connect to PostgreSQL

  • Verify the database is running.
  • Check the .env configuration.
  • Ensure Docker services are started.

MQTT connection fails

  • Verify the MQTT broker is reachable.
  • Check broker credentials.
  • Confirm the configured topics exist.
  • Ensure the broker accepts incoming client connections.

API is unavailable

Verify the backend is running:

http://localhost:8000/api/health

If successful, the endpoint returns the current application status.


Related Documentation

  • Root Project Documentation: ../../README.md
  • Frontend Documentation: ../web/README.md
  • Infrastructure Documentation: ../../infrastructure/README.md

Contributing

Please keep the backend modular.

New functionality should follow the existing architecture by separating:

  • routers
  • services
  • repositories
  • models
  • sensor implementations
  • factories

This ensures the project remains maintainable as additional hardware and sensor types are integrated.