Metadata-Version: 2.4
Name: conduyt-py
Version: 0.1.0
Summary: CONDUYT protocol SDK for Python — host-side hardware control
License: MIT
Project-URL: Homepage, https://github.com/virgilvox/conduyt
Project-URL: Repository, https://github.com/virgilvox/conduyt
Project-URL: Issues, https://github.com/virgilvox/conduyt/issues
Keywords: conduyt,iot,hardware,serial,mqtt,microcontroller,binary-protocol
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: serial
Requires-Dist: pyserial-asyncio>=0.6; extra == "serial"
Provides-Extra: mqtt
Requires-Dist: aiomqtt>=2.0; extra == "mqtt"
Provides-Extra: all
Requires-Dist: pyserial-asyncio>=0.6; extra == "all"
Requires-Dist: aiomqtt>=2.0; extra == "all"

# conduyt-py

CONDUYT protocol SDK for Python. Async and sync APIs for host-side hardware control.

## Install

```bash
pip install conduyt-py

# With serial transport
pip install conduyt-py[serial]

# With MQTT transport
pip install conduyt-py[mqtt]

# All transports
pip install conduyt-py[all]
```

## Quick Start

### Async

```python
from conduyt import ConduytDevice
from conduyt.transports.serial import SerialTransport

device = ConduytDevice(SerialTransport("/dev/ttyUSB0"))
hello = await device.connect()

await device.pin(13).mode("output")
await device.pin(13).write(1)
value = await device.pin(0).read("analog")

await device.disconnect()
```

### Sync

```python
from conduyt import ConduytDeviceSync
from conduyt.transports.serial import SerialTransport

device = ConduytDeviceSync(SerialTransport("/dev/ttyUSB0"))
device.connect()

device.pin(13).mode("output")
device.pin(13).write(1)
value = device.pin(0).read("analog")

device.disconnect()
```

### Module Usage

```python
from conduyt.modules.servo import ConduytServo

servo = ConduytServo(device)
await servo.attach(9)
await servo.write(90)
```

## API Reference

### ConduytDevice (async)

| Method | Returns | Description |
|--------|---------|-------------|
| `connect()` | `HelloResp` | Connect and run HELLO handshake |
| `disconnect()` | `None` | Close connection |
| `ping()` | `None` | Ping/pong roundtrip |
| `reset()` | `None` | Reset device state |
| `pin(num)` | `PinProxy` | Pin control object |

### ConduytDeviceSync

Synchronous wrapper around `ConduytDevice`. Same methods, no `await`.

### PinProxy

| Method | Returns | Description |
|--------|---------|-------------|
| `mode(mode)` | `None` | Set pin mode: `"input"`, `"output"`, `"pwm"`, `"analog"`, `"input_pullup"` |
| `write(value)` | `None` | Digital or PWM write |
| `read(mode?)` | `int` | Read pin value |

### Errors

| Class | When |
|-------|------|
| `ConduytNAKError` | Device rejected a command |
| `ConduytTimeoutError` | No response within timeout |
| `ConduytDisconnectedError` | Transport disconnected |

## Transports

| Transport | Module | Dependency |
|-----------|--------|------------|
| `SerialTransport` | `conduyt.transports.serial` | `pyserial-asyncio` |
| `MQTTTransport` | `conduyt.transports.mqtt` | `aiomqtt` |
| `MockTransport` | `conduyt.transports.mock` | None |

## Modules

| Module | Import | Hardware |
|--------|--------|----------|
| `ConduytServo` | `conduyt.modules.servo` | Hobby servos |
| `ConduytNeoPixel` | `conduyt.modules.neopixel` | WS2812/SK6812 LEDs |
| `ConduytDHT` | `conduyt.modules.dht` | DHT11/DHT22 sensors |
| `ConduytOLED` | `conduyt.modules.oled` | SSD1306 OLED displays |
| `ConduytStepper` | `conduyt.modules.stepper` | Stepper motors |
| `ConduytEncoder` | `conduyt.modules.encoder` | Rotary encoders |
| `ConduytPID` | `conduyt.modules.pid` | PID controller |

## Requirements

- Python >= 3.10
- `pyserial-asyncio >= 0.6` (for serial transport)
- `aiomqtt >= 2.0` (for MQTT transport)

## License

MIT. Copyright (c) 2026 LumenCanvas.
