mirror of
https://github.com/KevinMidboe/python-gpiozero.git
synced 2025-10-29 17:50:37 +00:00
Add a pwm option to the RGBLED and Motor constructors
...along with the other necessary changes required, to allow them to optionally be used with non-PWM-capable pins
This commit is contained in:
@@ -378,67 +378,6 @@ def test_output_pwm_pulse_foreground():
|
||||
(0.04, 0),
|
||||
])
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_pulse_background():
|
||||
pin = MockPWMPin(2)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
device.pulse(0.2, 0.2, n=2)
|
||||
device._blink_thread.join()
|
||||
pin.assert_states_and_times([
|
||||
(0.0, 0),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.8),
|
||||
(0.04, 1),
|
||||
(0.04, 0.8),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.8),
|
||||
(0.04, 1),
|
||||
(0.04, 0.8),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0),
|
||||
])
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_output_pwm_pulse_foreground():
|
||||
pin = MockPWMPin(2)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
device.pulse(0.2, 0.2, n=2, background=False)
|
||||
pin.assert_states_and_times([
|
||||
(0.0, 0),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.8),
|
||||
(0.04, 1),
|
||||
(0.04, 0.8),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.8),
|
||||
(0.04, 1),
|
||||
(0.04, 0.8),
|
||||
(0.04, 0.6),
|
||||
(0.04, 0.4),
|
||||
(0.04, 0.2),
|
||||
(0.04, 0),
|
||||
])
|
||||
|
||||
def test_output_pwm_blink_interrupt():
|
||||
pin = MockPWMPin(2)
|
||||
with PWMOutputDevice(pin) as device:
|
||||
@@ -461,9 +400,47 @@ def test_rgbled_initial_value():
|
||||
assert isclose(g.state, 0.2)
|
||||
assert isclose(b.state, 0.0)
|
||||
|
||||
def test_rgbled_initial_value_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False, initial_value=(0, 1, 1)) as device:
|
||||
assert r.state == 0
|
||||
assert g.state == 1
|
||||
assert b.state == 1
|
||||
|
||||
def test_rgbled_initial_bad_value():
|
||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||
with pytest.raises(ValueError):
|
||||
RGBLED(r, g, b, initial_value=(0.1, 0.2, 1.2))
|
||||
|
||||
def test_rgbled_initial_bad_value_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with pytest.raises(ValueError):
|
||||
RGBLED(r, g, b, pwm=False, initial_value=(0.1, 0.2, 0))
|
||||
|
||||
def test_rgbled_value():
|
||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b) as device:
|
||||
assert isinstance(device._leds[0], PWMLED)
|
||||
assert isinstance(device._leds[1], PWMLED)
|
||||
assert isinstance(device._leds[2], PWMLED)
|
||||
assert not device.is_active
|
||||
assert device.value == (0, 0, 0)
|
||||
device.on()
|
||||
assert device.is_active
|
||||
assert device.value == (1, 1, 1)
|
||||
device.off()
|
||||
assert not device.is_active
|
||||
assert device.value == (0, 0, 0)
|
||||
device.value = (0.5, 0.5, 0.5)
|
||||
assert device.is_active
|
||||
assert device.value == (0.5, 0.5, 0.5)
|
||||
|
||||
def test_rgbled_value_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
assert isinstance(device._leds[0], LED)
|
||||
assert isinstance(device._leds[1], LED)
|
||||
assert isinstance(device._leds[2], LED)
|
||||
assert not device.is_active
|
||||
assert device.value == (0, 0, 0)
|
||||
device.on()
|
||||
@@ -473,6 +450,33 @@ def test_rgbled_value():
|
||||
assert not device.is_active
|
||||
assert device.value == (0, 0, 0)
|
||||
|
||||
def test_rgbled_bad_value():
|
||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = (2, 0, 0)
|
||||
with RGBLED(r, g, b) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = (0, -1, 0)
|
||||
|
||||
def test_rgbled_bad_value_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = (2, 0, 0)
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = (0, -1, 0)
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = (0.5, 0, 0)
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = (0, 0.5, 0)
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = (0, 0, 0.5)
|
||||
|
||||
def test_rgbled_toggle():
|
||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b) as device:
|
||||
@@ -485,6 +489,18 @@ def test_rgbled_toggle():
|
||||
assert not device.is_active
|
||||
assert device.value == (0, 0, 0)
|
||||
|
||||
def test_rgbled_toggle_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
assert not device.is_active
|
||||
assert device.value == (0, 0, 0)
|
||||
device.toggle()
|
||||
assert device.is_active
|
||||
assert device.value == (1, 1, 1)
|
||||
device.toggle()
|
||||
assert not device.is_active
|
||||
assert device.value == (0, 0, 0)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_background():
|
||||
@@ -506,6 +522,27 @@ def test_rgbled_blink_background():
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_background_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2)
|
||||
assert isclose(time() - start, 0, abs_tol=0.05)
|
||||
device._blink_thread.join()
|
||||
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||
expected = [
|
||||
(0.0, 0),
|
||||
(0.0, 1),
|
||||
(0.1, 0),
|
||||
(0.1, 1),
|
||||
(0.1, 0)
|
||||
]
|
||||
r.assert_states_and_times(expected)
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_foreground():
|
||||
@@ -525,6 +562,25 @@ def test_rgbled_blink_foreground():
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_blink_foreground_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
start = time()
|
||||
device.blink(0.1, 0.1, n=2, background=False)
|
||||
assert isclose(time() - start, 0.4, abs_tol=0.05)
|
||||
expected = [
|
||||
(0.0, 0),
|
||||
(0.0, 1),
|
||||
(0.1, 0),
|
||||
(0.1, 1),
|
||||
(0.1, 0)
|
||||
]
|
||||
r.assert_states_and_times(expected)
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_fade_background():
|
||||
@@ -562,6 +618,12 @@ def test_rgbled_fade_background():
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
def test_rgbled_fade_background_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.blink(0, 0, 0.2, 0.2, n=2)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_fade_foreground():
|
||||
@@ -597,6 +659,12 @@ def test_rgbled_fade_foreground():
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
def test_rgbled_fade_foreground_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_pulse_background():
|
||||
@@ -634,6 +702,12 @@ def test_rgbled_pulse_background():
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
def test_rgbled_pulse_background_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.pulse(0.2, 0.2, n=2)
|
||||
|
||||
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
|
||||
reason='timing is too random on pypy')
|
||||
def test_rgbled_pulse_foreground():
|
||||
@@ -669,6 +743,12 @@ def test_rgbled_pulse_foreground():
|
||||
g.assert_states_and_times(expected)
|
||||
b.assert_states_and_times(expected)
|
||||
|
||||
def test_rgbled_pulse_foreground_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.pulse(0.2, 0.2, n=2, background=False)
|
||||
|
||||
def test_rgbled_blink_interrupt():
|
||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b) as device:
|
||||
@@ -679,6 +759,16 @@ def test_rgbled_blink_interrupt():
|
||||
g.assert_states([0, 1, 0])
|
||||
b.assert_states([0, 1, 0])
|
||||
|
||||
def test_rgbled_blink_interrupt_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
device.blink(1, 0.1)
|
||||
sleep(0.2)
|
||||
device.off() # should interrupt while on
|
||||
r.assert_states([0, 1, 0])
|
||||
g.assert_states([0, 1, 0])
|
||||
b.assert_states([0, 1, 0])
|
||||
|
||||
def test_rgbled_close():
|
||||
r, g, b = (MockPWMPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b) as device:
|
||||
@@ -688,6 +778,15 @@ def test_rgbled_close():
|
||||
device.close()
|
||||
assert device.closed
|
||||
|
||||
def test_rgbled_close_nonpwm():
|
||||
r, g, b = (MockPin(i) for i in (1, 2, 3))
|
||||
with RGBLED(r, g, b, pwm=False) as device:
|
||||
assert not device.closed
|
||||
device.close()
|
||||
assert device.closed
|
||||
device.close()
|
||||
assert device.closed
|
||||
|
||||
def test_motor_missing_pins():
|
||||
with pytest.raises(ValueError):
|
||||
Motor()
|
||||
@@ -697,7 +796,18 @@ def test_motor_pins():
|
||||
b = MockPWMPin(2)
|
||||
with Motor(f, b) as device:
|
||||
assert device.forward_device.pin is f
|
||||
assert isinstance(device.forward_device, PWMOutputDevice)
|
||||
assert device.backward_device.pin is b
|
||||
assert isinstance(device.backward_device, PWMOutputDevice)
|
||||
|
||||
def test_motor_pins_nonpwm():
|
||||
f = MockPin(1)
|
||||
b = MockPin(2)
|
||||
with Motor(f, b, pwm=False) as device:
|
||||
assert device.forward_device.pin is f
|
||||
assert isinstance(device.forward_device, DigitalOutputDevice)
|
||||
assert device.backward_device.pin is b
|
||||
assert isinstance(device.backward_device, DigitalOutputDevice)
|
||||
|
||||
def test_motor_close():
|
||||
f = MockPWMPin(1)
|
||||
@@ -710,6 +820,15 @@ def test_motor_close():
|
||||
device.close()
|
||||
assert device.closed
|
||||
|
||||
def test_motor_close_nonpwm():
|
||||
f = MockPin(1)
|
||||
b = MockPin(2)
|
||||
with Motor(f, b, pwm=False) as device:
|
||||
device.close()
|
||||
assert device.closed
|
||||
assert device.forward_device.pin is None
|
||||
assert device.backward_device.pin is None
|
||||
|
||||
def test_motor_value():
|
||||
f = MockPWMPin(1)
|
||||
b = MockPWMPin(2)
|
||||
@@ -726,6 +845,27 @@ def test_motor_value():
|
||||
assert device.is_active
|
||||
assert device.value == 0.5
|
||||
assert b.state == 0 and f.state == 0.5
|
||||
device.value = -0.5
|
||||
assert device.is_active
|
||||
assert device.value == -0.5
|
||||
assert b.state == 0.5 and f.state == 0
|
||||
device.value = 0
|
||||
assert not device.is_active
|
||||
assert not device.value
|
||||
assert b.state == 0 and f.state == 0
|
||||
|
||||
def test_motor_value_nonpwm():
|
||||
f = MockPin(1)
|
||||
b = MockPin(2)
|
||||
with Motor(f, b, pwm=False) as device:
|
||||
device.value = -1
|
||||
assert device.is_active
|
||||
assert device.value == -1
|
||||
assert b.state == 1 and f.state == 0
|
||||
device.value = 1
|
||||
assert device.is_active
|
||||
assert device.value == 1
|
||||
assert b.state == 0 and f.state == 1
|
||||
device.value = 0
|
||||
assert not device.is_active
|
||||
assert not device.value
|
||||
@@ -735,9 +875,24 @@ def test_motor_bad_value():
|
||||
f = MockPWMPin(1)
|
||||
b = MockPWMPin(2)
|
||||
with Motor(f, b) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = -2
|
||||
with pytest.raises(ValueError):
|
||||
device.value = 2
|
||||
|
||||
def test_motor_bad_value_nonpwm():
|
||||
f = MockPin(1)
|
||||
b = MockPin(2)
|
||||
with Motor(f, b, pwm=False) as device:
|
||||
with pytest.raises(ValueError):
|
||||
device.value = -2
|
||||
with pytest.raises(ValueError):
|
||||
device.value = 2
|
||||
with pytest.raises(ValueError):
|
||||
device.value = 0.5
|
||||
with pytest.raises(ValueError):
|
||||
device.value = -0.5
|
||||
|
||||
def test_motor_reverse():
|
||||
f = MockPWMPin(1)
|
||||
b = MockPWMPin(2)
|
||||
@@ -748,4 +903,20 @@ def test_motor_reverse():
|
||||
device.reverse()
|
||||
assert device.value == -1
|
||||
assert b.state == 1 and f.state == 0
|
||||
device.backward(0.5)
|
||||
assert device.value == -0.5
|
||||
assert b.state == 0.5 and f.state == 0
|
||||
device.reverse()
|
||||
assert device.value == 0.5
|
||||
assert b.state == 0 and f.state == 0.5
|
||||
|
||||
def test_motor_reverse_nonpwm():
|
||||
f = MockPin(1)
|
||||
b = MockPin(2)
|
||||
with Motor(f, b, pwm=False) as device:
|
||||
device.forward()
|
||||
assert device.value == 1
|
||||
assert b.state == 0 and f.state == 1
|
||||
device.reverse()
|
||||
assert device.value == -1
|
||||
assert b.state == 1 and f.state == 0
|
||||
|
||||
Reference in New Issue
Block a user