Com bus
Communication bus abstractions for hardware peripherals.
This module provides thread-safe bus wrappers for I2C (via Blinka/adafruit)
and MODBUS RTU (via pymodbus). Sensors and pumps declare which bus they use
by inheriting from I2CInterface or MODBUSInterface.
Bus type constants
_I2C: Canonical string identifier for the I2C bus ("i2c"). _MODBUS: Canonical string identifier for the MODBUS bus ("MODBUS").
Bus
¶
Bases: ABC
Abstract base class for communication buses.
Provides thread-safety primitives for serial bus access. All bus
operations that touch hardware should go through run_sync (async)
or run_sync_blocking (sync) to ensure mutual exclusion.
Source code in pt/controller_3/src/plant_controller/com_bus.py
run_sync(fn)
async
¶
Run a synchronous function in a worker thread, holding the bus lock.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Zero-argument callable to execute under the lock. |
required |
Returns:
| Type | Description |
|---|---|
|
The return value of fn(). |
Source code in pt/controller_3/src/plant_controller/com_bus.py
run_sync_blocking(fn)
¶
Run a synchronous function on the current thread, holding the bus lock.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Zero-argument callable to execute under the lock. |
required |
Returns:
| Type | Description |
|---|---|
|
The return value of fn(). |
Source code in pt/controller_3/src/plant_controller/com_bus.py
BlinkaI2CBus
¶
Bases: Bus
I2C bus implementation using Adafruit Blinka.
Wraps the board's I2C interface and manages TCA9548A multiplexers for addressing multiple devices on the same bus.
Attributes:
| Name | Type | Description |
|---|---|---|
wrapped_bus |
The underlying board.I2C() instance. |
|
multiplexers |
Dict mapping addresses to TCA9548A instances. |
Source code in pt/controller_3/src/plant_controller/com_bus.py
ensure_multiplexer(address)
¶
Get or create a TCA9548A multiplexer at the given I2C address.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
int
|
I2C address of the multiplexer (e.g. 0x70). |
required |
Returns:
| Type | Description |
|---|---|
TCA9548A
|
The TCA9548A instance for that address. |
Source code in pt/controller_3/src/plant_controller/com_bus.py
MODBUS
¶
Bases: Bus
MODBUS RTU bus implementation using pymodbus.
Wraps a pymodbus ModbusSerialClient and provides both synchronous and async (thread-offloaded) access patterns. Method calls are proxied to the underlying client with automatic locking.
Attribute access patterns
bus.write_coil(...)- synchronous, locked call to the client.await bus.snagged_write_coil(...)- async, runs in a worker thread with the bus lock held. Prefix any client method withsnagged_to get the async variant.
Attributes:
| Name | Type | Description |
|---|---|---|
client |
The underlying pymodbus ModbusSerialClient. |
Source code in pt/controller_3/src/plant_controller/com_bus.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
__init__(port='/dev/ttyUSB0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=1.0)
¶
Initialize the MODBUS serial client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
port
|
str
|
Serial port path (default: /dev/ttyUSB0). |
'/dev/ttyUSB0'
|
baudrate
|
int
|
Communication speed (default: 9600). |
9600
|
bytesize
|
int
|
Data bits per frame (default: 8). |
8
|
parity
|
str
|
Parity setting: 'N', 'E', or 'O' (default: 'N'). |
'N'
|
stopbits
|
int
|
Number of stop bits (default: 1). |
1
|
timeout
|
float
|
Read timeout in seconds (default: 1.0). |
1.0
|
Source code in pt/controller_3/src/plant_controller/com_bus.py
__getattr__(name)
¶
Proxy attribute access to the underlying pymodbus client.
If the attribute name starts with 'snagged_', returns an async wrapper that runs the client method in a worker thread with the bus lock. Otherwise returns a synchronous locked wrapper.
Source code in pt/controller_3/src/plant_controller/com_bus.py
connect()
async
¶
Open the serial connection to the MODBUS network.
Source code in pt/controller_3/src/plant_controller/com_bus.py
BusInterface
¶
Bases: ABC
Mixin declaring which bus type a peripheral uses.
Sensors and pumps must inherit from one of the concrete subclasses (I2CInterface or MODBUSInterface) so the dynamic loader can automatically select the correct bus instance.
Source code in pt/controller_3/src/plant_controller/com_bus.py
bus_type()
abstractmethod
staticmethod
¶
Return the canonical bus type string for this peripheral.
Returns:
| Type | Description |
|---|---|
str
|
The bus type identifier (matches keys in the busses dict). |
I2CInterface
¶
Bases: BusInterface
Mixin indicating a peripheral communicates via I2C.
Source code in pt/controller_3/src/plant_controller/com_bus.py
bus_type()
staticmethod
¶
MODBUSInterface
¶
Bases: BusInterface
Mixin indicating a peripheral communicates via MODBUS RTU.
Source code in pt/controller_3/src/plant_controller/com_bus.py
bus_type()
staticmethod
¶
Return the MODBUS bus type identifier.
Returns:
| Type | Description |
|---|---|
str
|
The string 'MODBUS'. |
busses()
async
¶
Initialize and connect all communication buses.
Returns:
| Type | Description |
|---|---|
|
Dict mapping bus type strings to initialized Bus instances. |