Raspberry-side server

The code that must run on the Raspberry Pi lives in the src_raspberry/ folder at the root of the plugin repository. It makes the bridge between the hardware (I2C sensors, GPIO actuators) and the network.

Note

This folder is an addition to the plugin and is not packaged: it is not part of the Python distribution of the PyMoDAQ plugin and does not modify it.

Layered architecture

The server is split into independent layers, each behind an interface; only main.py is not interchangeable, as it assembles the others.

 ZmqServer  ──►  JsonRequestHandler  ──►  HardwareBackend
(transport)       (request routing)       (component comm.)
      ▲                  ▲                       ▲
 ITransport       IRequestHandler         IHardwareBackend
  • transport/ — communication with the PyMoDAQ client. zmq_server.py implements ZmqServer (ZeroMQ ROUTER); it only handles networking and framing.

  • handlers/ — request handling. json_handler.py implements JsonRequestHandler (JSON decoding + routing). It performs no hardware access: everything is delegated to the backend.

  • hardware/ — communication with the components. backend.py implements HardwareBackend (sensors + actuators); sensors.py holds the sensor drivers and the SENSOR_DRIVER_REGISTRY (AHT10, TMP102, EMC2101, PT-100, SIMULE); actuators.py holds the actuator drivers and the ACTUATOR_DRIVER_REGISTRY (PWM, DIGITAL); scanner.py detects I2C addresses.

  • config.py — the description of the bench (pins, sensors, actuators). The only file to adapt from one bench to another (see Adapting the plugin to a bench).

  • main.py — entry point: instantiates and wires the three layers (HardwareBackendJsonRequestHandlerZmqServer on port 5555).

Requirements and installation

  1. OS Installation — Flash Raspberry Pi OS (64-bit) on a micro-SD card (8 GB min.). Connect via SSH and update the system: sudo apt update && sudo apt upgrade -y.

  2. Enable I2Csudo raspi-configInterfacing OptionsI2C.

  3. pigpio daemon (hardware GPIO control):

    sudo apt-get update
    sudo apt-get install pigpio python3-pigpio
    sudo systemctl enable pigpiod
    sudo systemctl start pigpiod
    
  4. Python dependencies:

    python3 -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
    

    Note

    If the requirements.txt file is missing, you can create it with the following content:

    Adafruit-Blinka>=8.69.0
    adafruit-circuitpython-busdevice>=5.2.15
    adafruit-circuitpython-connectionmanager>=3.1.6
    adafruit-circuitpython-emc2101>=1.2.12
    adafruit-circuitpython-register>=1.11.1
    adafruit-circuitpython-requests>=4.1.15
    adafruit-circuitpython-typing>=1.12.3
    Adafruit-PlatformDetect>=3.86.0
    Adafruit-PureIO>=1.1.11
    binho-host-adapter>=0.1.6
    board>=1.0
    pigpio>=1.78
    pyftdi>=0.57.1
    pyserial>=3.5
    pyusb>=1.3.1
    pyzmq>=27.1.0
    RPi.GPIO>=0.7.1
    smbus2>=0.6.0
    sysv_ipc>=1.2.0
    typing_extensions>=4.15.0
    

Running and Auto-start (systemd)

Manual test:

python main.py

Note

Automatic simulation mode — if the I2C bus or the pigpio daemon are unreachable (for instance when running on a regular PC), the server automatically falls back to simulated objects (MagicMock / SIMULE drivers), so the network communication can be tested without a real Raspberry Pi.

In production: create a systemd service file at /etc/systemd/system/pilotage.service:

[Unit]
Description=Thermal control ZeroMQ Server
After=network.target pigpiod.service

[Service]
ExecStart=/home/admin/PYMODAQ_PLUGIN_RASPPI3/PY_ENV/bin/python /home/admin/PYMODAQ_PLUGIN_RASPPI3/main.py
WorkingDirectory=/home/admin/PYMODAQ_PLUGIN_RASPPI3
StandardOutput=inherit
StandardError=inherit
Restart=always
User=admin

[Install]
WantedBy=multi-user.target

Warning

Make sure to put a space between the python binary and the path to main.py in ExecStart (two separate paths separated by a space).

Then, reload the daemon and start the service:

sudo systemctl daemon-reload
sudo systemctl enable pilotage.service
sudo systemctl start pilotage.service

Troubleshooting: * Check service status: sudo systemctl status pilotage.service (should be active (running)). * Check I2C devices on the bus: sudo i2cdetect -y 1.

Hardware Configuration (config.py)

The entire topology is centralized in src_raspberry/config.py:

I2C_BUS_ID      = 1
VENTILATEUR_PIN = 18     # PWM 25000 Hz
RESISTANCE_PIN  = 23     # PWM 100 Hz (via MOSFET)

CAPTEUR_AHT10   = 0x38   # rh_sortie
CAPTEUR_TMP102  = 0x48   # t_resistance
# 0x49 t_dissipateur, 0x4A t_entree, 0x4B t_sortie (TMP102)
CAPTEUR_EMC2101 = 0x4C   # T_emc

To change a pin or an address, modify ACTUATORS_CONFIG (actuators) or SENSORS_CONFIG (sensors) in this single file.