or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

composite-devices.mdindex.mdinput-devices.mdoutput-devices.mdpin-factories.mdspi-devices.mdsystem-monitoring.mdtone-system.mdtools.md

composite-devices.mddocs/

0

# Composite Devices

1

2

Pre-built configurations for commercial GPIO boards, LED collections, and robotic platforms. Composite devices combine multiple individual devices into cohesive units with simplified control interfaces.

3

4

## Base Classes

5

6

### CompositeDevice

7

8

Base class for devices composed of multiple sub-devices.

9

10

```python { .api }

11

class CompositeDevice(Device):

12

def __init__(self, *, pin_factory=None):

13

"""

14

Base class for composite devices.

15

16

Parameters:

17

- pin_factory: Factory or None - Pin factory for advanced usage

18

"""

19

20

def close(self):

21

"""Close the device and all sub-devices."""

22

23

@property

24

def closed(self) -> bool:

25

"""Returns True if device is closed."""

26

27

@property

28

def value(self) -> tuple:

29

"""Tuple of all sub-device values."""

30

31

@value.setter

32

def value(self, values): ...

33

```

34

35

### CompositeOutputDevice

36

37

Base class for composite output devices.

38

39

```python { .api }

40

class CompositeOutputDevice(ValuesMixin, SourceMixin, CompositeDevice):

41

def __init__(self, *, initial_value=False, pin_factory=None):

42

"""

43

Base class for composite output devices.

44

45

Parameters:

46

- initial_value: Initial state for all outputs

47

- pin_factory: Factory or None - Pin factory for advanced usage

48

"""

49

50

def on(self):

51

"""Turn on all outputs."""

52

53

def off(self):

54

"""Turn off all outputs."""

55

56

def toggle(self):

57

"""Toggle all outputs."""

58

59

def pulse(self, fade_in_time: float = 1, fade_out_time: float = 1, n: int = None, background: bool = True):

60

"""Pulse all outputs."""

61

62

def blink(self, on_time: float = 1, off_time: float = 1, n: int = None, background: bool = True):

63

"""Blink all outputs."""

64

65

@property

66

def is_active(self) -> bool:

67

"""Returns True if any output is active."""

68

```

69

70

## LED Collections

71

72

### LEDBoard

73

74

Collection of LEDs indexed by name.

75

76

```python { .api }

77

class LEDBoard(CompositeOutputDevice):

78

def __init__(self, **named_pins):

79

"""

80

Collection of LEDs with named access.

81

82

Parameters:

83

- **named_pins: Named pin assignments (e.g., red=17, green=18, blue=19)

84

"""

85

86

def __getitem__(self, key) -> LED:

87

"""Access LED by name."""

88

89

def __setitem__(self, key, value):

90

"""Set LED state by name."""

91

92

@property

93

def leds(self) -> dict:

94

"""Dictionary of all LEDs by name."""

95

```

96

97

### LEDBarGraph

98

99

Bar graph representation using multiple LEDs.

100

101

```python { .api }

102

class LEDBarGraph(LEDBoard):

103

def __init__(self, *pins, pwm=False, active_high=True, initial_value=0, pin_factory=None):

104

"""

105

LED bar graph for displaying values.

106

107

Parameters:

108

- *pins: Pin numbers for LEDs (in order from low to high)

109

- pwm: bool - True for PWM LEDs, False for simple LEDs

110

- active_high: bool - True if LEDs are on when pins are HIGH

111

- initial_value: float - Initial value to display (0.0-1.0)

112

- pin_factory: Factory or None - Pin factory for advanced usage

113

"""

114

115

@property

116

def value(self) -> float:

117

"""Current bar graph value (0.0-1.0)."""

118

119

@value.setter

120

def value(self, value: float): ...

121

122

@property

123

def lit_count(self) -> int:

124

"""Number of currently lit LEDs."""

125

```

126

127

### LEDCharDisplay

128

129

7-segment character display.

130

131

```python { .api }

132

class LEDCharDisplay(CompositeOutputDevice):

133

def __init__(self, a, b, c, d, e, f, g, *, dp=None, active_high=True, initial_value=' ', pin_factory=None):

134

"""

135

7-segment character display.

136

137

Parameters:

138

- a, b, c, d, e, f, g: Pin numbers for segments

139

- dp: Pin number for decimal point (optional)

140

- active_high: bool - True if segments are on when pins are HIGH

141

- initial_value: str - Initial character to display

142

- pin_factory: Factory or None - Pin factory for advanced usage

143

"""

144

145

@property

146

def char(self) -> str:

147

"""Current displayed character."""

148

149

@char.setter

150

def char(self, value: str): ...

151

152

def display_hex(self, value: int):

153

"""Display hexadecimal digit (0-F)."""

154

155

def display_decimal(self, value: int):

156

"""Display decimal digit (0-9)."""

157

```

158

159

### LEDMultiCharDisplay

160

161

Multi-character 7-segment display.

162

163

```python { .api }

164

class LEDMultiCharDisplay(CompositeOutputDevice):

165

def __init__(self, *chars, active_high=True, initial_value=' ', pin_factory=None):

166

"""

167

Multi-character 7-segment display.

168

169

Parameters:

170

- *chars: LEDCharDisplay objects for each digit position

171

- active_high: bool - True if segments are on when pins are HIGH

172

- initial_value: str - Initial text to display

173

- pin_factory: Factory or None - Pin factory for advanced usage

174

"""

175

176

@property

177

def text(self) -> str:

178

"""Current displayed text."""

179

180

@text.setter

181

def text(self, value: str): ...

182

183

def display_int(self, value: int):

184

"""Display integer value."""

185

186

def display_float(self, value: float, decimal_places: int = 1):

187

"""Display floating point value."""

188

```

189

190

## Robot Classes

191

192

### Robot

193

194

Generic two-wheeled robot with differential drive.

195

196

```python { .api }

197

class Robot(CompositeDevice, SourceMixin):

198

def __init__(self, left=None, right=None, *, pwm=True, pin_factory=None):

199

"""

200

Two-wheeled robot with differential drive.

201

202

Parameters:

203

- left: Motor pins for left wheel (forward, backward) or Motor object

204

- right: Motor pins for right wheel (forward, backward) or Motor object

205

- pwm: bool - True for PWM speed control

206

- pin_factory: Factory or None - Pin factory for advanced usage

207

"""

208

209

def forward(self, speed: float = 1):

210

"""Move forward at specified speed (0.0-1.0)."""

211

212

def backward(self, speed: float = 1):

213

"""Move backward at specified speed (0.0-1.0)."""

214

215

def left(self, speed: float = 1):

216

"""Turn left at specified speed."""

217

218

def right(self, speed: float = 1):

219

"""Turn right at specified speed."""

220

221

def stop(self):

222

"""Stop all movement."""

223

224

def reverse(self):

225

"""Reverse current movement direction."""

226

227

@property

228

def value(self) -> tuple:

229

"""Current movement as (left_speed, right_speed) tuple."""

230

231

@value.setter

232

def value(self, speeds: tuple): ...

233

234

@property

235

def is_active(self) -> bool:

236

"""Returns True if either motor is active."""

237

238

@property

239

def left_motor(self) -> Motor:

240

"""Left motor object."""

241

242

@property

243

def right_motor(self) -> Motor:

244

"""Right motor object."""

245

```

246

247

### CamJamKitRobot

248

249

Robot configuration for CamJam EduKit #3.

250

251

```python { .api }

252

class CamJamKitRobot(Robot):

253

def __init__(self, *, pwm=True, pin_factory=None):

254

"""

255

CamJam EduKit robot with predefined pin configuration.

256

257

Parameters:

258

- pwm: bool - True for PWM speed control

259

- pin_factory: Factory or None - Pin factory for advanced usage

260

"""

261

```

262

263

### RyanteckRobot

264

265

Robot configuration for Ryanteck MCB robot.

266

267

```python { .api }

268

class RyanteckRobot(Robot):

269

def __init__(self, *, pwm=True, pin_factory=None):

270

"""

271

Ryanteck MCB robot with predefined pin configuration.

272

273

Parameters:

274

- pwm: bool - True for PWM speed control

275

- pin_factory: Factory or None - Pin factory for advanced usage

276

"""

277

```

278

279

### PololuDRV8835Robot

280

281

Robot using Pololu DRV8835 motor controller.

282

283

```python { .api }

284

class PololuDRV8835Robot(Robot):

285

def __init__(self, *, pwm=True, pin_factory=None):

286

"""

287

Pololu DRV8835 robot with predefined pin configuration.

288

289

Parameters:

290

- pwm: bool - True for PWM speed control

291

- pin_factory: Factory or None - Pin factory for advanced usage

292

"""

293

```

294

295

## Commercial GPIO Boards

296

297

### TrafficLights

298

299

Generic traffic light board (red, amber, green).

300

301

```python { .api }

302

class TrafficLights(CompositeOutputDevice):

303

def __init__(self, red=None, amber=None, green=None, *, pwm=False, initial_value=False, pin_factory=None):

304

"""

305

Traffic light control board.

306

307

Parameters:

308

- red: int or str - Red LED pin

309

- amber: int or str - Amber LED pin

310

- green: int or str - Green LED pin

311

- pwm: bool - True for PWM LEDs

312

- initial_value: Initial state

313

- pin_factory: Factory or None - Pin factory for advanced usage

314

"""

315

316

@property

317

def red(self) -> LED:

318

"""Red LED."""

319

320

@property

321

def amber(self) -> LED:

322

"""Amber LED."""

323

324

@property

325

def green(self) -> LED:

326

"""Green LED."""

327

328

def red_on(self):

329

"""Turn on red light, turn off others."""

330

331

def amber_on(self):

332

"""Turn on amber light, turn off others."""

333

334

def green_on(self):

335

"""Turn on green light, turn off others."""

336

```

337

338

### PiTraffic

339

340

Low Voltage Labs PiTraffic board with fixed pins.

341

342

```python { .api }

343

class PiTraffic(TrafficLights):

344

def __init__(self, *, pwm=False, initial_value=False, pin_factory=None):

345

"""

346

PiTraffic board with predefined pins (9, 10, 11).

347

348

Parameters:

349

- pwm: bool - True for PWM LEDs

350

- initial_value: Initial state

351

- pin_factory: Factory or None - Pin factory for advanced usage

352

"""

353

```

354

355

### PiStop

356

357

PiHardware PiStop traffic lights.

358

359

```python { .api }

360

class PiStop(TrafficLights):

361

def __init__(self, location=None, *, pwm=False, initial_value=False, pin_factory=None):

362

"""

363

PiStop traffic lights for different GPIO locations.

364

365

Parameters:

366

- location: str - Board location ('A', 'B', 'C', 'D') or None for auto-detect

367

- pwm: bool - True for PWM LEDs

368

- initial_value: Initial state

369

- pin_factory: Factory or None - Pin factory for advanced usage

370

"""

371

```

372

373

### LEDBoard Variants

374

375

#### PiLiter

376

377

Ciseco PiLiter 8-LED board.

378

379

```python { .api }

380

class PiLiter(LEDBoard):

381

def __init__(self, *, pwm=False, active_high=True, initial_value=False, pin_factory=None):

382

"""

383

PiLiter 8-LED board with predefined pins.

384

385

Parameters:

386

- pwm: bool - True for PWM LEDs

387

- active_high: bool - True if LEDs are on when pins are HIGH

388

- initial_value: Initial state

389

- pin_factory: Factory or None - Pin factory for advanced usage

390

"""

391

```

392

393

#### PiHutXmasTree

394

395

Pi Hut 3D Christmas tree LED board.

396

397

```python { .api }

398

class PiHutXmasTree(LEDBoard):

399

def __init__(self, *, pwm=False, initial_value=False, pin_factory=None):

400

"""

401

Pi Hut 3D Christmas tree with 24 LEDs.

402

403

Parameters:

404

- pwm: bool - True for PWM LEDs

405

- initial_value: Initial state

406

- pin_factory: Factory or None - Pin factory for advanced usage

407

"""

408

409

def on(self, *, led_count: int = None):

410

"""Turn on LEDs (optionally specify count)."""

411

412

def off(self):

413

"""Turn off all LEDs."""

414

```

415

416

### Button Boards

417

418

#### ButtonBoard

419

420

Collection of buttons with event handling.

421

422

```python { .api }

423

class ButtonBoard(CompositeDevice):

424

def __init__(self, **named_pins):

425

"""

426

Collection of buttons with named access.

427

428

Parameters:

429

- **named_pins: Named pin assignments for buttons

430

"""

431

432

def __getitem__(self, key) -> Button:

433

"""Access button by name."""

434

435

@property

436

def buttons(self) -> dict:

437

"""Dictionary of all buttons by name."""

438

439

@property

440

def when_pressed(self) -> callable:

441

"""Callback for any button press."""

442

443

@when_pressed.setter

444

def when_pressed(self, value: callable): ...

445

446

@property

447

def when_released(self) -> callable:

448

"""Callback for any button release."""

449

450

@when_released.setter

451

def when_released(self, value: callable): ...

452

```

453

454

### Specialized Boards

455

456

#### Energenie

457

458

Energenie power control sockets.

459

460

```python { .api }

461

class Energenie(CompositeOutputDevice):

462

def __init__(self, socket=None, *, initial_value=False, pin_factory=None):

463

"""

464

Energenie power control sockets.

465

466

Parameters:

467

- socket: int - Socket number (1-4) or None for all

468

- initial_value: Initial state

469

- pin_factory: Factory or None - Pin factory for advanced usage

470

"""

471

472

def __getitem__(self, socket: int) -> OutputDevice:

473

"""Access socket by number."""

474

475

def on(self, socket: int = None):

476

"""Turn on socket (or all if None)."""

477

478

def off(self, socket: int = None):

479

"""Turn off socket (or all if None)."""

480

```

481

482

## Usage Examples

483

484

### LED Board Control

485

486

```python

487

from gpiozero import LEDBoard

488

from time import sleep

489

490

# Create named LED board

491

leds = LEDBoard(red=2, green=3, blue=4, yellow=5)

492

493

# Individual LED control

494

leds.red.on()

495

leds.green.blink()

496

497

# Access by name

498

leds['blue'].on()

499

sleep(1)

500

leds['blue'].off()

501

502

# All LEDs

503

leds.on()

504

sleep(1)

505

leds.off()

506

507

# Sequence

508

for led_name in ['red', 'green', 'blue', 'yellow']:

509

leds[led_name].on()

510

sleep(0.5)

511

leds[led_name].off()

512

```

513

514

### LED Bar Graph

515

516

```python

517

from gpiozero import LEDBarGraph, MCP3008

518

from signal import pause

519

520

# 8-LED bar graph

521

bar = LEDBarGraph(2, 3, 4, 5, 6, 7, 8, 9, pwm=True)

522

sensor = MCP3008(channel=0)

523

524

# Bar graph follows sensor reading

525

bar.source = sensor

526

527

pause()

528

```

529

530

### Robot Control

531

532

```python

533

from gpiozero import Robot

534

from time import sleep

535

536

# Custom robot configuration

537

robot = Robot(left=(7, 8), right=(9, 10))

538

539

# Basic movements

540

robot.forward()

541

sleep(2)

542

robot.backward()

543

sleep(2)

544

robot.left()

545

sleep(1)

546

robot.right()

547

sleep(1)

548

robot.stop()

549

550

# Speed control

551

robot.forward(0.5) # Half speed

552

sleep(2)

553

robot.stop()

554

555

# Manual wheel control

556

robot.value = (1, 0.5) # Left full, right half

557

sleep(2)

558

robot.value = (0, 0) # Stop

559

```

560

561

### Traffic Light Sequence

562

563

```python

564

from gpiozero import TrafficLights

565

from time import sleep

566

567

lights = TrafficLights(red=2, amber=3, green=4)

568

569

def traffic_sequence():

570

"""Standard UK traffic light sequence."""

571

lights.green_on()

572

sleep(5)

573

574

lights.amber_on()

575

sleep(2)

576

577

lights.red_on()

578

sleep(5)

579

580

# Red + Amber (UK style)

581

lights.red.on()

582

lights.amber.on()

583

lights.green.off()

584

sleep(2)

585

586

# Run sequence

587

while True:

588

traffic_sequence()

589

```

590

591

### Button Board with LEDs

592

593

```python

594

from gpiozero import ButtonBoard, LEDBoard

595

from signal import pause

596

597

buttons = ButtonBoard(a=2, b=3, c=4, d=5)

598

leds = LEDBoard(red=17, green=18, blue=19, yellow=20)

599

600

# Map buttons to LEDs

601

buttons['a'].when_pressed = leds.red.toggle

602

buttons['b'].when_pressed = leds.green.toggle

603

buttons['c'].when_pressed = leds.blue.toggle

604

buttons['d'].when_pressed = leds.yellow.toggle

605

606

# Global button handler

607

def any_button_pressed():

608

print("A button was pressed!")

609

610

buttons.when_pressed = any_button_pressed

611

612

pause()

613

```

614

615

### 7-Segment Display

616

617

```python

618

from gpiozero import LEDCharDisplay

619

from time import sleep

620

621

# 7-segment display (a, b, c, d, e, f, g segments)

622

display = LEDCharDisplay(2, 3, 4, 5, 6, 7, 8, dp=9)

623

624

# Display digits

625

for digit in "0123456789":

626

display.char = digit

627

sleep(0.5)

628

629

# Display hex digits

630

for digit in "0123456789ABCDEF":

631

display.char = digit

632

sleep(0.3)

633

634

# Display some letters

635

for char in "HELLO":

636

display.char = char

637

sleep(0.5)

638

```

639

640

### Robot with Sensors

641

642

```python

643

from gpiozero import Robot, DistanceSensor, Button

644

from signal import pause

645

646

robot = Robot(left=(7, 8), right=(9, 10))

647

distance = DistanceSensor(echo=24, trigger=23, threshold_distance=0.3)

648

stop_button = Button(2)

649

650

def obstacle_detected():

651

robot.stop()

652

print("Obstacle detected! Stopping.")

653

654

def path_clear():

655

robot.forward(0.5)

656

print("Path clear, moving forward.")

657

658

def emergency_stop():

659

robot.stop()

660

print("Emergency stop!")

661

662

# Connect sensors to robot

663

distance.when_in_range = obstacle_detected

664

distance.when_out_of_range = path_clear

665

stop_button.when_pressed = emergency_stop

666

667

# Start moving

668

robot.forward(0.5)

669

pause()

670

```

671

672

## Additional Board Classes

673

674

### LEDCharFont

675

676

Font management for character displays.

677

678

```python { .api }

679

class LEDCharFont(MutableMapping):

680

def __init__(self, font_file):

681

"""

682

Font for character displays.

683

684

Parameters:

685

- font_file: str - Path to font definition file

686

"""

687

```

688

689

### LedBorg

690

691

LedBorg RGB LED board.

692

693

```python { .api }

694

class LedBorg(RGBLED):

695

def __init__(self, *, pwm=True, pin_factory=None):

696

"""

697

LedBorg RGB LED board interface.

698

699

Parameters:

700

- pwm: bool - Enable PWM for color control (default: True)

701

- pin_factory: Factory or None - Pin factory for advanced usage

702

"""

703

```

704

705

### PiLiterBarGraph

706

707

PiLiter bar graph variant.

708

709

```python { .api }

710

class PiLiterBarGraph(LEDBarGraph):

711

def __init__(self, *, pwm=False, initial_value=False, pin_factory=None):

712

"""

713

PiLiter bar graph LED board.

714

715

Parameters:

716

- pwm: bool - Enable PWM brightness control (default: False)

717

- initial_value: bool - Initial state for all LEDs

718

- pin_factory: Factory or None - Pin factory for advanced usage

719

"""

720

```

721

722

### StatusZero

723

724

StatusZero LED board.

725

726

```python { .api }

727

class StatusZero(LEDBoard):

728

def __init__(self, *, pwm=False, initial_value=False, pin_factory=None):

729

"""

730

StatusZero RGB LED board interface.

731

732

Parameters:

733

- pwm: bool - Enable PWM brightness control (default: False)

734

- initial_value: bool - Initial state for all LEDs

735

- pin_factory: Factory or None - Pin factory for advanced usage

736

"""

737

```

738

739

### StatusBoard

740

741

Generic status board interface.

742

743

```python { .api }

744

class StatusBoard(CompositeOutputDevice):

745

def __init__(self, **named_pins):

746

"""

747

Generic status board with named LED outputs.

748

749

Parameters:

750

- named_pins: Named GPIO pins for LEDs

751

"""

752

```

753

754

### SnowPi

755

756

SnowPi LED board.

757

758

```python { .api }

759

class SnowPi(LEDBoard):

760

def __init__(self, *, pwm=False, initial_value=False, pin_factory=None):

761

"""

762

SnowPi LED board interface with snowflake pattern.

763

764

Parameters:

765

- pwm: bool - Enable PWM brightness control (default: False)

766

- initial_value: bool - Initial state for all LEDs

767

- pin_factory: Factory or None - Pin factory for advanced usage

768

"""

769

```

770

771

### TrafficLightsBuzzer

772

773

Traffic lights with integrated buzzer.

774

775

```python { .api }

776

class TrafficLightsBuzzer(CompositeOutputDevice):

777

def __init__(self, red=None, amber=None, green=None, buzzer=None, *, pin_factory=None):

778

"""

779

Traffic lights with buzzer for audio signals.

780

781

Parameters:

782

- red: int or str - GPIO pin for red LED

783

- amber: int or str - GPIO pin for amber LED

784

- green: int or str - GPIO pin for green LED

785

- buzzer: int or str - GPIO pin for buzzer

786

- pin_factory: Factory or None - Pin factory for advanced usage

787

"""

788

```

789

790

### FishDish

791

792

FishDish LED board.

793

794

```python { .api }

795

class FishDish(CompositeOutputDevice):

796

def __init__(self, *, pwm=False, initial_value=False, pin_factory=None):

797

"""

798

FishDish LED board with fish-shaped pattern.

799

800

Parameters:

801

- pwm: bool - Enable PWM brightness control (default: False)

802

- initial_value: bool - Initial state for all LEDs

803

- pin_factory: Factory or None - Pin factory for advanced usage

804

"""

805

```

806

807

### TrafficHat

808

809

Traffic HAT board.

810

811

```python { .api }

812

class TrafficHat(CompositeOutputDevice):

813

def __init__(self, *, pin_factory=None):

814

"""

815

Traffic HAT board with LEDs and buzzer.

816

817

Parameters:

818

- pin_factory: Factory or None - Pin factory for advanced usage

819

"""

820

```

821

822

### TrafficpHat

823

824

Traffic pHAT board.

825

826

```python { .api }

827

class TrafficpHat(TrafficLights):

828

def __init__(self, *, pin_factory=None):

829

"""

830

Traffic pHAT board with traffic light LEDs.

831

832

Parameters:

833

- pin_factory: Factory or None - Pin factory for advanced usage

834

"""

835

```

836

837

### PhaseEnableRobot

838

839

Robot using phase/enable motor control.

840

841

```python { .api }

842

class PhaseEnableRobot(SourceMixin, CompositeDevice):

843

def __init__(self, left=None, right=None, *, pin_factory=None):

844

"""

845

Robot with phase/enable motor control.

846

847

Parameters:

848

- left: tuple - (phase_pin, enable_pin) for left motor

849

- right: tuple - (phase_pin, enable_pin) for right motor

850

- pin_factory: Factory or None - Pin factory for advanced usage

851

"""

852

```

853

854

### PumpkinPi

855

856

PumpkinPi LED board.

857

858

```python { .api }

859

class PumpkinPi(LEDBoard):

860

def __init__(self, *, pwm=False, initial_value=False, pin_factory=None):

861

"""

862

PumpkinPi LED board with pumpkin-shaped pattern.

863

864

Parameters:

865

- pwm: bool - Enable PWM brightness control (default: False)

866

- initial_value: bool - Initial state for all LEDs

867

- pin_factory: Factory or None - Pin factory for advanced usage

868

"""

869

```

870

871

### JamHat

872

873

Jam HAT board.

874

875

```python { .api }

876

class JamHat(CompositeOutputDevice):

877

def __init__(self, *, pin_factory=None):

878

"""

879

Jam HAT board with LEDs, buzzer, and button inputs.

880

881

Parameters:

882

- pin_factory: Factory or None - Pin factory for advanced usage

883

"""

884

```

885

886

### Pibrella

887

888

Pibrella board.

889

890

```python { .api }

891

class Pibrella(CompositeOutputDevice):

892

def __init__(self, *, pin_factory=None):

893

"""

894

Pibrella board with LEDs, buzzer, and button inputs.

895

896

Parameters:

897

- pin_factory: Factory or None - Pin factory for advanced usage

898

"""

899

```