# pudap/qubot architecture

> Architecture diagram of the GitHub repository pudap/qubot, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-10-01). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/pudap/qubot
- Repository: https://github.com/pudap/qubot

## Overview

This repository provides four PUDA-advertised machine edge services backed by shared Python drivers. The user-facing workflow is to invoke a machine command through its edge service; the corresponding machine class coordinates motion, pipetting, deck/labware, or capper operations and device-specific controllers. The README documents the service-to-machine pattern and hardware variants. The graph preserves major driver capabilities shown in the source index, but several implementations and edge entry points were not excerpted, so only documented or indexed relationships are connected.

Main entry points: [`driver/src/qubot_drivers/machines/first.py`](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/first.py) (First machine), [`driver/src/qubot_drivers/machines/pipqubot_mof.py`](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/pipqubot_mof.py) (MOF machine), [`driver/src/qubot_drivers/serialcontroller.py`](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/serialcontroller.py) (Serial controller), [`driver/src/qubot_drivers/satorius.py`](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/satorius.py) (Sartorius pipette)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_edges["Edge services"]
  node_first_edge["First edge<br/>[main.py]"]
  node_capper_edge["Capper edge<br/>[main.py]"]
  node_mof_edge["MOF edge<br/>[main.py]"]
  node_pescador_edge["Pescador edge<br/>[main.py]"]
end

subgraph group_machines["Machine workflows"]
  node_first["First machine<br/>[first.py]"]
  node_capper["Capper machine<br/>[capper.py]"]
  node_mof["MOF machine<br/>[pipqubot_mof.py]"]
  node_pescador["Pescador machine<br/>[pescador.py]"]
  node_pipette["Pipette machine<br/>[pipette.py]"]
end

subgraph group_motion["Motion controllers"]
  node_reprap["RepRap motion<br/>[reprap.py]"]
  node_grblhal["GRBL HAL motion<br/>[grblHAL.py]"]
  node_grblws["GRBL WebSocket<br/>[grbl_ws.py]"]
  node_reprap_http["RepRap HTTP<br/>[reprap_http.py]"]
  node_gcode_api["G-code API<br/>[api.py]"]
end

subgraph group_hardware["Device I/O"]
  node_serial["Serial controller"]
  node_sartorius["Sartorius pipette<br/>[satorius.py]"]
end

subgraph group_shared["Shared capabilities"]
  node_deck["Deck and labware<br/>[deck.py]"]
  node_labware["Labware definitions<br/>[labware.py]"]
  node_position["Position model<br/>[position.py]"]
  node_camera["Camera utilities<br/>[camera.py]"]
  node_logging["Logging setup<br/>[logging.py]"]
end

node_user(("PUDA user"))

node_user -->|"invokes commands"| node_first_edge
node_user -->|"invokes commands"| node_capper_edge
node_user -->|"invokes commands"| node_mof_edge
node_user -->|"invokes commands"| node_pescador_edge
node_first_edge -->|"wraps machine"| node_first
node_capper_edge -->|"wraps machine"| node_capper
node_mof_edge -->|"wraps machine"| node_mof
node_pescador_edge -->|"wraps machine"| node_pipette
node_first -->|"uses motion"| node_reprap
node_first -->|"controls pipette"| node_sartorius
node_first -->|"manages deck"| node_deck
node_mof -->|"uses motion"| node_grblhal
node_mof -->|"controls pipette"| node_sartorius
node_mof -->|"manages deck"| node_deck
node_pipette -->|"uses motion"| node_grblws
node_pipette -->|"controls pipette"| node_sartorius
node_pescador -->|"uses motion"| node_grblws
node_capper -->|"uses motion"| node_reprap_http
node_serial -.-> node_position
node_reprap -->|"uses serial"| node_serial
node_grblhal -->|"uses serial"| node_serial
node_sartorius -->|"uses serial"| node_serial
node_reprap -->|"tracks position"| node_position
node_grblhal -->|"tracks position"| node_position
node_grblws -->|"reports position"| node_position
node_deck -->|"loads definitions"| node_labware

click node_first_edge "https://github.com/pudap/qubot/blob/main/first-edge/main.py"
click node_capper_edge "https://github.com/pudap/qubot/blob/main/capper-edge/main.py"
click node_mof_edge "https://github.com/pudap/qubot/blob/main/pipqubot-mof-edge/main.py"
click node_pescador_edge "https://github.com/pudap/qubot/blob/main/pescador-pipqubot-edge/main.py"
click node_first "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/first.py"
click node_capper "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/capper.py"
click node_mof "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/pipqubot_mof.py"
click node_pescador "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/pescador.py"
click node_pipette "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/pipette.py"
click node_reprap "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/reprap.py"
click node_grblhal "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/grblHAL.py"
click node_grblws "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/grbl_ws.py"
click node_reprap_http "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/reprap_http.py"
click node_gcode_api "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/gcode/api.py"
click node_serial "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/serialcontroller.py"
click node_sartorius "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/satorius.py"
click node_deck "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/deck.py"
click node_labware "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/labware/labware.py"
click node_position "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/position.py"
click node_camera "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/cv/camera.py"
click node_logging "https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/logging.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_first_edge,node_capper_edge,node_mof_edge,node_pescador_edge,node_user toneBlue
class node_first,node_capper,node_mof,node_pescador,node_pipette toneAmber
class node_reprap,node_grblhal,node_grblws,node_reprap_http,node_gcode_api toneMint
class node_serial,node_sartorius toneRose
class node_deck,node_labware,node_position,node_camera,node_logging toneIndigo
```

## Components

### Edge services

- [First edge](https://github.com/pudap/qubot/blob/main/first-edge/main.py): `first-edge/main.py`
- [Capper edge](https://github.com/pudap/qubot/blob/main/capper-edge/main.py): `capper-edge/main.py`
- [MOF edge](https://github.com/pudap/qubot/blob/main/pipqubot-mof-edge/main.py): `pipqubot-mof-edge/main.py`
- [Pescador edge](https://github.com/pudap/qubot/blob/main/pescador-pipqubot-edge/main.py): `pescador-pipqubot-edge/main.py`

### Machine workflows

- [First machine](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/first.py): `driver/src/qubot_drivers/machines/first.py`
- [Capper machine](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/capper.py): `driver/src/qubot_drivers/machines/capper.py`
- [MOF machine](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/pipqubot_mof.py): `driver/src/qubot_drivers/machines/pipqubot_mof.py`
- [Pescador machine](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/pescador.py): `driver/src/qubot_drivers/machines/pescador.py`
- [Pipette machine](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/machines/pipette.py): `driver/src/qubot_drivers/machines/pipette.py`

### Motion controllers

- [RepRap motion](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/reprap.py): `driver/src/qubot_drivers/move/reprap.py`
- [GRBL HAL motion](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/grblHAL.py): `driver/src/qubot_drivers/move/grblHAL.py`
- [GRBL WebSocket](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/grbl_ws.py): `driver/src/qubot_drivers/move/grbl_ws.py`
- [RepRap HTTP](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/reprap_http.py): `driver/src/qubot_drivers/move/reprap_http.py`
- [G-code API](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/gcode/api.py): `driver/src/qubot_drivers/move/gcode/api.py`

### Device I/O

- [Serial controller](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/serialcontroller.py): `driver/src/qubot_drivers/serialcontroller.py`
- [Sartorius pipette](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/satorius.py): `driver/src/qubot_drivers/satorius.py`

### Shared capabilities

- [Deck and labware](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/move/deck.py): `driver/src/qubot_drivers/move/deck.py`
- [Labware definitions](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/labware/labware.py): `driver/src/qubot_drivers/labware/labware.py`
- [Position model](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/position.py): `driver/src/qubot_drivers/position.py`
- [Camera utilities](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/cv/camera.py): `driver/src/qubot_drivers/cv/camera.py`
- [Logging setup](https://github.com/pudap/qubot/blob/main/driver/src/qubot_drivers/logging.py): `driver/src/qubot_drivers/logging.py`

### Other components

- **PUDA user**

## Connections

- PUDA user → First edge: invokes commands (evidence: `README.md`)
- PUDA user → Capper edge: invokes commands (evidence: `README.md`)
- PUDA user → MOF edge: invokes commands (evidence: `README.md`)
- PUDA user → Pescador edge: invokes commands (evidence: `README.md`)
- First edge → First machine: wraps machine (evidence: `README.md`)
- Capper edge → Capper machine: wraps machine (evidence: `capper-edge/main.py`)
- MOF edge → MOF machine: wraps machine (evidence: `pipqubot-mof-edge/main.py`)
- Pescador edge → Pipette machine: wraps machine (evidence: `pescador-pipqubot-edge/main.py`)
- First machine → RepRap motion: uses motion (evidence: `driver/src/qubot_drivers/machines/first.py`)
- First machine → Sartorius pipette: controls pipette (evidence: `driver/src/qubot_drivers/machines/first.py`)
- First machine → Deck and labware: manages deck (evidence: `driver/src/qubot_drivers/machines/first.py`)
- MOF machine → GRBL HAL motion: uses motion (evidence: `driver/src/qubot_drivers/machines/pipqubot_mof.py`)
- MOF machine → Sartorius pipette: controls pipette (evidence: `driver/src/qubot_drivers/machines/pipqubot_mof.py`)
- MOF machine → Deck and labware: manages deck (evidence: `driver/src/qubot_drivers/machines/pipqubot_mof.py`)
- Pipette machine → GRBL WebSocket: uses motion (evidence: `driver/src/qubot_drivers/machines/pipette.py`)
- Pipette machine → Sartorius pipette: controls pipette (evidence: `driver/src/qubot_drivers/machines/pipette.py`)
- Pescador machine → GRBL WebSocket: uses motion (evidence: `driver/src/qubot_drivers/machines/pescador.py`)
- Capper machine → RepRap HTTP: uses motion (evidence: `driver/src/qubot_drivers/machines/capper.py`)
- Serial controller → Position model
- RepRap motion → Serial controller: uses serial (evidence: `driver/src/qubot_drivers/move/reprap.py`)
- GRBL HAL motion → Serial controller: uses serial (evidence: `driver/src/qubot_drivers/move/grblHAL.py`)
- Sartorius pipette → Serial controller: uses serial (evidence: `driver/src/qubot_drivers/satorius.py`)
- RepRap motion → Position model: tracks position (evidence: `driver/src/qubot_drivers/move/reprap.py`)
- GRBL HAL motion → Position model: tracks position (evidence: `driver/src/qubot_drivers/move/grblHAL.py`)
- GRBL WebSocket → Position model: reports position (evidence: `driver/src/qubot_drivers/move/grbl_ws.py`)
- Deck and labware → Labware definitions: loads definitions (evidence: `driver/src/qubot_drivers/move/deck.py`)
