0
# Utility Tools
1
2
Source chaining utility functions for complex device interactions and value transformations. These functions enable declarative programming patterns and advanced device coordination in GPIO Zero's source/values system.
3
4
## Core Imports
5
6
```python
7
from gpiozero.tools import negated, inverted, scaled
8
from gpiozero.tools import all_values, any_values, averaged
9
from gpiozero.tools import booleanized, clamped
10
```
11
12
## Value Transformation Functions
13
14
### negated
15
16
Negate boolean values in a stream.
17
18
```python { .api }
19
def negated(values):
20
"""
21
Returns the negation of the supplied values (True becomes False, False becomes True).
22
23
Parameters:
24
- values: Iterable of boolean values or ValuesMixin device
25
26
Returns:
27
Generator yielding negated values
28
"""
29
```
30
31
**Usage Example:**
32
```python
33
from gpiozero import LED, Button
34
from gpiozero.tools import negated
35
from signal import pause
36
37
led = LED(17)
38
button = Button(2)
39
40
# LED is on when button is NOT pressed
41
led.source = negated(button)
42
43
pause()
44
```
45
46
### inverted
47
48
Invert numeric values within a specified range.
49
50
```python { .api }
51
def inverted(values, input_min=0, input_max=1):
52
"""
53
Returns the inversion of supplied values within the specified range.
54
55
Parameters:
56
- values: Iterable of numeric values or ValuesMixin device
57
- input_min: float - Minimum value of input range (default: 0)
58
- input_max: float - Maximum value of input range (default: 1)
59
60
Returns:
61
Generator yielding inverted values
62
"""
63
```
64
65
**Usage Example:**
66
```python
67
from gpiozero import PWMLED, MCP3008
68
from gpiozero.tools import inverted
69
from signal import pause
70
71
led = PWMLED(17)
72
pot = MCP3008(0)
73
74
# LED brightness is inverted - bright when pot is low
75
led.source = inverted(pot)
76
77
pause()
78
```
79
80
### scaled
81
82
Scale values from one range to another.
83
84
```python { .api }
85
def scaled(values, output_min, output_max, input_min=0, input_max=1):
86
"""
87
Scale values from input range to output range.
88
89
Parameters:
90
- values: Iterable of numeric values or ValuesMixin device
91
- output_min: float - Minimum value of output range
92
- output_max: float - Maximum value of output range
93
- input_min: float - Minimum value of input range (default: 0)
94
- input_max: float - Maximum value of input range (default: 1)
95
96
Returns:
97
Generator yielding scaled values
98
"""
99
```
100
101
**Usage Example:**
102
```python
103
from gpiozero import Motor, MCP3008
104
from gpiozero.tools import scaled
105
from signal import pause
106
107
motor = Motor(20, 21)
108
pot = MCP3008(0)
109
110
# Scale potentiometer (0-1) to motor range (-1 to 1)
111
motor.source = scaled(pot, -1, 1)
112
113
pause()
114
```
115
116
### clamped
117
118
Clamp values to stay within specified bounds.
119
120
```python { .api }
121
def clamped(values, min_value=0, max_value=1):
122
"""
123
Clamp values to stay within specified minimum and maximum bounds.
124
125
Parameters:
126
- values: Iterable of numeric values or ValuesMixin device
127
- min_value: float - Minimum allowed value (default: 0)
128
- max_value: float - Maximum allowed value (default: 1)
129
130
Returns:
131
Generator yielding clamped values
132
"""
133
```
134
135
## Logical Combination Functions
136
137
### all_values
138
139
Logical AND operation on multiple value sources.
140
141
```python { .api }
142
def all_values(*sources):
143
"""
144
Returns True only when all source values are True (logical AND).
145
146
Parameters:
147
- *sources: Variable number of value sources (devices or iterables)
148
149
Returns:
150
Generator yielding True when all sources are True
151
"""
152
```
153
154
### any_values
155
156
Logical OR operation on multiple value sources.
157
158
```python { .api }
159
def any_values(*sources):
160
"""
161
Returns True when any source value is True (logical OR).
162
163
Parameters:
164
- *sources: Variable number of value sources (devices or iterables)
165
166
Returns:
167
Generator yielding True when any source is True
168
"""
169
```
170
171
**Logical Combination Example:**
172
```python
173
from gpiozero import LED, Button, MotionSensor
174
from gpiozero.tools import all_values, any_values
175
from signal import pause
176
177
security_light = LED(17)
178
manual_button = Button(2)
179
motion1 = MotionSensor(4)
180
motion2 = MotionSensor(5)
181
182
# Light turns on when button pressed OR motion detected on either sensor
183
security_light.source = any_values(manual_button, motion1, motion2)
184
185
# Alternative: Light only when button pressed AND motion detected
186
# security_light.source = all_values(manual_button, any_values(motion1, motion2))
187
188
pause()
189
```
190
191
## Statistical Functions
192
193
### averaged
194
195
Average values over a time window.
196
197
```python { .api }
198
def averaged(values, samples=10):
199
"""
200
Returns the mean average of the last n samples from values.
201
202
Parameters:
203
- values: Iterable of numeric values or ValuesMixin device
204
- samples: int - Number of samples to average (default: 10)
205
206
Returns:
207
Generator yielding averaged values
208
"""
209
```
210
211
**Usage Example:**
212
```python
213
from gpiozero import PWMLED, MCP3008
214
from gpiozero.tools import averaged
215
from signal import pause
216
217
led = PWMLED(17)
218
light_sensor = MCP3008(0)
219
220
# LED brightness follows smoothed light sensor reading
221
led.source = averaged(light_sensor, samples=20)
222
223
pause()
224
```
225
226
## Boolean Conversion Functions
227
228
### booleanized
229
230
Convert numeric values to boolean based on threshold.
231
232
```python { .api }
233
def booleanized(values, threshold=0.5):
234
"""
235
Convert numeric values to boolean based on threshold comparison.
236
237
Parameters:
238
- values: Iterable of numeric values or ValuesMixin device
239
- threshold: float - Threshold for True/False conversion (default: 0.5)
240
241
Returns:
242
Generator yielding boolean values
243
"""
244
```
245
246
**Usage Example:**
247
```python
248
from gpiozero import LED, LightSensor
249
from gpiozero.tools import booleanized
250
from signal import pause
251
252
night_light = LED(17)
253
light_sensor = LightSensor(7)
254
255
# Light turns on when sensor reads below 0.1 (dark)
256
night_light.source = booleanized(light_sensor, 0.1)
257
258
pause()
259
```
260
261
## Random Value Generators
262
263
### random_values
264
265
Generate random values within a specified range.
266
267
```python { .api }
268
def random_values(*, min_value=0, max_value=1):
269
"""
270
Generate infinite stream of random values.
271
272
Parameters:
273
- min_value: float - Minimum random value (default: 0)
274
- max_value: float - Maximum random value (default: 1)
275
276
Returns:
277
Generator yielding random values
278
"""
279
```
280
281
### scaled_full
282
283
Convenience function to scale half-range values (0..1) to full-range (-1..1).
284
285
```python { .api }
286
def scaled_full(values):
287
"""
288
Scale half-range values (0..1) to full-range (-1..1).
289
290
Parameters:
291
- values: Iterable of numeric values or ValuesMixin device
292
293
Returns:
294
Generator yielding full-range values
295
"""
296
```
297
298
### scaled_half
299
300
Convenience function to scale full-range values (-1..1) to half-range (0..1).
301
302
```python { .api }
303
def scaled_half(values):
304
"""
305
Scale full-range values (-1..1) to half-range (0..1).
306
307
Parameters:
308
- values: Iterable of numeric values or ValuesMixin device
309
310
Returns:
311
Generator yielding half-range values
312
"""
313
```
314
315
### clamped
316
317
Clamp values to specified minimum and maximum bounds.
318
319
```python { .api }
320
def clamped(values, output_min=0, output_max=1):
321
"""
322
Clamp values to specified bounds.
323
324
Parameters:
325
- values: Iterable of numeric values or ValuesMixin device
326
- output_min: float - Minimum output value (default: 0)
327
- output_max: float - Maximum output value (default: 1)
328
329
Returns:
330
Generator yielding clamped values
331
"""
332
```
333
334
### absoluted
335
336
Return absolute values (all negative values become positive).
337
338
```python { .api }
339
def absoluted(values):
340
"""
341
Return absolute values of supplied values.
342
343
Parameters:
344
- values: Iterable of numeric values or ValuesMixin device
345
346
Returns:
347
Generator yielding absolute values
348
"""
349
```
350
351
### quantized
352
353
Quantize values to specified number of discrete steps.
354
355
```python { .api }
356
def quantized(values, steps, input_min=0, input_max=1):
357
"""
358
Quantize values to discrete steps.
359
360
Parameters:
361
- values: Iterable of numeric values or ValuesMixin device
362
- steps: int - Number of quantization steps
363
- input_min: float - Minimum input value (default: 0)
364
- input_max: float - Maximum input value (default: 1)
365
366
Returns:
367
Generator yielding quantized values
368
"""
369
```
370
371
### summed
372
373
Sum values from multiple sources.
374
375
```python { .api }
376
def summed(*values):
377
"""
378
Return sum of all supplied value streams.
379
380
Parameters:
381
- values: Variable number of iterables or ValuesMixin devices
382
383
Returns:
384
Generator yielding summed values
385
"""
386
```
387
388
### multiplied
389
390
Multiply values from multiple sources.
391
392
```python { .api }
393
def multiplied(*values):
394
"""
395
Return product of all supplied value streams.
396
397
Parameters:
398
- values: Variable number of iterables or ValuesMixin devices
399
400
Returns:
401
Generator yielding multiplied values
402
"""
403
```
404
405
### queued
406
407
Queue values with specified buffer size.
408
409
```python { .api }
410
def queued(values, qsize):
411
"""
412
Queue values with specified buffer size.
413
414
Parameters:
415
- values: Iterable of values or ValuesMixin device
416
- qsize: int - Queue buffer size
417
418
Returns:
419
Generator yielding queued values
420
"""
421
```
422
423
### smoothed
424
425
Smooth values using specified averaging function.
426
427
```python { .api }
428
def smoothed(values, qsize, average=mean):
429
"""
430
Smooth values using moving average.
431
432
Parameters:
433
- values: Iterable of values or ValuesMixin device
434
- qsize: int - Size of smoothing window
435
- average: function - Averaging function (default: statistics.mean)
436
437
Returns:
438
Generator yielding smoothed values
439
"""
440
```
441
442
### pre_delayed
443
444
Add delay before processing values.
445
446
```python { .api }
447
def pre_delayed(values, delay):
448
"""
449
Add delay before yielding each value.
450
451
Parameters:
452
- values: Iterable of values or ValuesMixin device
453
- delay: float - Delay in seconds before each value
454
455
Returns:
456
Generator yielding delayed values
457
"""
458
```
459
460
### post_delayed
461
462
Add delay after processing values.
463
464
```python { .api }
465
def post_delayed(values, delay):
466
"""
467
Add delay after yielding each value.
468
469
Parameters:
470
- values: Iterable of values or ValuesMixin device
471
- delay: float - Delay in seconds after each value
472
473
Returns:
474
Generator yielding values with post-delay
475
"""
476
```
477
478
### pre_periodic_filtered
479
480
Filter values periodically before processing.
481
482
```python { .api }
483
def pre_periodic_filtered(values, block, repeat_after):
484
"""
485
Filter values periodically before processing.
486
487
Parameters:
488
- values: Iterable of values or ValuesMixin device
489
- block: float - Duration to block values
490
- repeat_after: float - Period after which to repeat blocking
491
492
Returns:
493
Generator yielding filtered values
494
"""
495
```
496
497
### post_periodic_filtered
498
499
Filter values periodically after processing.
500
501
```python { .api }
502
def post_periodic_filtered(values, repeat_after, block):
503
"""
504
Filter values periodically after processing.
505
506
Parameters:
507
- values: Iterable of values or ValuesMixin device
508
- repeat_after: float - Period after which to repeat blocking
509
- block: float - Duration to block values
510
511
Returns:
512
Generator yielding filtered values
513
"""
514
```
515
516
## Value Generators
517
518
### sin_values
519
520
Generate sine wave values.
521
522
```python { .api }
523
def sin_values(period=360):
524
"""
525
Generate sine wave values.
526
527
Parameters:
528
- period: int - Period in steps for complete sine wave (default: 360)
529
530
Returns:
531
Generator yielding sine wave values (-1 to 1)
532
"""
533
```
534
535
### cos_values
536
537
Generate cosine wave values.
538
539
```python { .api }
540
def cos_values(period=360):
541
"""
542
Generate cosine wave values.
543
544
Parameters:
545
- period: int - Period in steps for complete cosine wave (default: 360)
546
547
Returns:
548
Generator yielding cosine wave values (-1 to 1)
549
"""
550
```
551
552
### alternating_values
553
554
Generate alternating True/False values.
555
556
```python { .api }
557
def alternating_values(initial_value=False):
558
"""
559
Generate alternating boolean values.
560
561
Parameters:
562
- initial_value: bool - Starting value (default: False)
563
564
Returns:
565
Generator yielding alternating boolean values
566
"""
567
```
568
569
### ramping_values
570
571
Generate ramping values (sawtooth wave).
572
573
```python { .api }
574
def ramping_values(period=360):
575
"""
576
Generate ramping sawtooth wave values.
577
578
Parameters:
579
- period: int - Period in steps for complete ramp (default: 360)
580
581
Returns:
582
Generator yielding ramping values (0 to 1)
583
"""
584
```
585
586
### zip_values
587
588
Combine multiple device value streams.
589
590
```python { .api }
591
def zip_values(*devices):
592
"""
593
Combine multiple device value streams into tuples.
594
595
Parameters:
596
- devices: Variable number of ValuesMixin devices
597
598
Returns:
599
Generator yielding tuples of values from each device
600
"""
601
```
602
603
## Complex Usage Examples
604
605
### Multi-Sensor Security System
606
607
```python
608
from gpiozero import LED, Button, MotionSensor, LightSensor
609
from gpiozero.tools import all_values, any_values, booleanized, negated
610
from signal import pause
611
612
# Devices
613
security_light = LED(17)
614
disable_switch = Button(2)
615
motion_sensor = MotionSensor(4)
616
light_sensor = LightSensor(7)
617
618
# Security light logic:
619
# - Motion detected AND it's dark AND system not disabled
620
motion_active = motion_sensor
621
is_dark = booleanized(light_sensor, 0.2) # Dark when < 0.2
622
system_enabled = negated(disable_switch) # Enabled when switch not pressed
623
624
security_light.source = all_values(motion_active, is_dark, system_enabled)
625
626
pause()
627
```
628
629
### Adaptive Motor Control
630
631
```python
632
from gpiozero import Motor, MCP3008, Button
633
from gpiozero.tools import scaled, clamped, negated
634
from signal import pause
635
636
motor = Motor(20, 21)
637
speed_pot = MCP3008(0) # Speed control potentiometer
638
reverse_button = Button(2) # Reverse direction button
639
640
# Scale potentiometer to motor speed range
641
base_speed = scaled(speed_pot, 0, 1) # 0 to 1 forward
642
643
# Apply direction based on button (negate for reverse)
644
def directional_speed():
645
for speed in base_speed:
646
if reverse_button.is_pressed:
647
yield -speed # Reverse direction
648
else:
649
yield speed # Forward direction
650
651
motor.source = directional_speed()
652
653
pause()
654
```
655
656
### Smart Garden Irrigation
657
658
```python
659
from gpiozero import OutputDevice, MCP3008, TimeOfDay
660
from gpiozero.tools import all_values, booleanized, inverted
661
from signal import pause
662
663
irrigation_pump = OutputDevice(17)
664
soil_moisture = MCP3008(0) # Soil moisture sensor
665
daytime = TimeOfDay(start_time=(6, 0), end_time=(20, 0))
666
667
# Irrigation logic:
668
# - Soil is dry (low moisture reading)
669
# - During daytime hours only
670
soil_dry = booleanized(inverted(soil_moisture), 0.3) # Invert: low reading = dry
671
during_day = daytime
672
673
irrigation_pump.source = all_values(soil_dry, during_day)
674
675
pause()
676
```
677
678
### Temperature-Controlled Fan
679
680
```python
681
from gpiozero import Motor, CPUTemperature
682
from gpiozero.tools import scaled, clamped
683
from signal import pause
684
685
cooling_fan = Motor(20, 21)
686
cpu_temp = CPUTemperature()
687
688
# Fan speed based on CPU temperature
689
# - No fan below 50°C
690
# - Full speed at 80°C and above
691
def temp_to_fan_speed():
692
for temp in cpu_temp.values:
693
if temp < 50:
694
yield 0 # No cooling needed
695
elif temp > 80:
696
yield 1 # Full speed
697
else:
698
# Scale from 50-80°C to 0-1 fan speed
699
yield (temp - 50) / 30
700
701
cooling_fan.source = clamped(temp_to_fan_speed(), 0, 1)
702
703
pause()
704
```
705
706
These utility functions enable powerful declarative programming patterns where device behavior is described through value transformations and logical combinations rather than imperative control loops.