Files
python-gpiozero/tests/test_outputs.py
Dave Jones 4049ef5094 Work around for longer object lifetimes on pypy
On pypy the subordinate LED objects in RGBLED composite objects do die
on failed construction ... eventually. Unfortunately it's not quick
enough to prevent the following tests from failing. As we can't know for
certain exactly which test is going to follow, it's best to simply clear
down the reservation table before each test.
2017-06-16 13:28:55 +01:00

1050 lines
34 KiB
Python

from __future__ import (
unicode_literals,
absolute_import,
print_function,
division,
)
str = type('')
import sys
from time import sleep, time
try:
from math import isclose
except ImportError:
from gpiozero.compat import isclose
import pytest
from gpiozero.pins.mock import MockPWMPin
from gpiozero import *
def teardown_function(function):
Device._pin_factory.reset()
Device._reservations.clear()
def test_output_initial_values():
pin = Device._pin_factory.pin(2)
with OutputDevice(pin, initial_value=False) as device:
assert pin.function == 'output'
assert not pin.state
with OutputDevice(pin, initial_value=True) as device:
assert pin.state
state = pin.state
with OutputDevice(pin, initial_value=None) as device:
assert state == pin.state
def test_output_write_active_high():
pin = Device._pin_factory.pin(2)
with OutputDevice(pin) as device:
device.on()
assert pin.state
device.off()
assert not pin.state
def test_output_write_active_low():
pin = Device._pin_factory.pin(2)
with OutputDevice(pin, active_high=False) as device:
device.on()
assert not pin.state
device.off()
assert pin.state
def test_output_write_closed():
with OutputDevice(Device._pin_factory.pin(2)) as device:
device.close()
assert device.closed
device.close()
assert device.closed
with pytest.raises(GPIODeviceClosed):
device.on()
def test_output_write_silly():
pin = Device._pin_factory.pin(2)
with OutputDevice(pin) as device:
pin.function = 'input'
with pytest.raises(AttributeError):
device.on()
def test_output_value():
pin = Device._pin_factory.pin(2)
with OutputDevice(pin) as device:
assert not device.value
assert not pin.state
device.on()
assert device.value
assert pin.state
device.value = False
assert not device.value
assert not pin.state
def test_output_digital_toggle():
pin = Device._pin_factory.pin(2)
with DigitalOutputDevice(pin) as device:
assert not device.value
assert not pin.state
device.toggle()
assert device.value
assert pin.state
device.toggle()
assert not device.value
assert not pin.state
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
reason='timing is too random on pypy')
def test_output_blink_background():
pin = Device._pin_factory.pin(2)
with DigitalOutputDevice(pin) 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() # naughty, but ensures no arbitrary waits in the test
assert isclose(time() - start, 0.4, abs_tol=0.05)
pin.assert_states_and_times([
(0.0, False),
(0.0, True),
(0.1, False),
(0.1, True),
(0.1, False)
])
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
reason='timing is too random on pypy')
def test_output_blink_foreground():
pin = Device._pin_factory.pin(2)
with DigitalOutputDevice(pin) as device:
start = time()
device.blink(0.1, 0.1, n=2, background=False)
assert isclose(time() - start, 0.4, abs_tol=0.05)
pin.assert_states_and_times([
(0.0, False),
(0.0, True),
(0.1, False),
(0.1, True),
(0.1, False)
])
def test_output_blink_interrupt_on():
pin = Device._pin_factory.pin(2)
with DigitalOutputDevice(pin) as device:
device.blink(1, 0.1)
sleep(0.2)
device.off() # should interrupt while on
pin.assert_states([False, True, False])
def test_output_blink_interrupt_off():
pin = Device._pin_factory.pin(2)
with DigitalOutputDevice(pin) as device:
device.blink(0.1, 1)
sleep(0.2)
device.off() # should interrupt while off
pin.assert_states([False, True, False])
def test_output_pwm_bad_initial_value():
with pytest.raises(ValueError):
PWMOutputDevice(Device._pin_factory.pin(2), initial_value=2)
def test_output_pwm_not_supported():
with pytest.raises(AttributeError):
PWMOutputDevice(Device._pin_factory.pin(2))
def test_output_pwm_states():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
device.value = 0.1
device.value = 0.2
device.value = 0.0
pin.assert_states([0.0, 0.1, 0.2, 0.0])
def test_output_pwm_read():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin, frequency=100) as device:
assert device.frequency == 100
device.value = 0.1
assert isclose(device.value, 0.1)
assert isclose(pin.state, 0.1)
assert device.is_active
device.frequency = None
assert not device.value
assert not device.is_active
assert device.frequency is None
def test_output_pwm_write():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
device.on()
device.off()
pin.assert_states([False, True, False])
def test_output_pwm_toggle():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
device.toggle()
device.value = 0.5
device.value = 0.1
device.toggle()
device.off()
pin.assert_states([False, True, 0.5, 0.1, 0.9, False])
def test_output_pwm_active_high_read():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin, active_high=False) as device:
device.value = 0.1
assert isclose(device.value, 0.1)
assert isclose(pin.state, 0.9)
device.frequency = None
assert device.value
def test_output_pwm_bad_value():
with PWMOutputDevice(Device._pin_factory.pin(2, pin_class=MockPWMPin)) as device:
with pytest.raises(ValueError):
device.value = 2
def test_output_pwm_write_closed():
with PWMOutputDevice(Device._pin_factory.pin(2, pin_class=MockPWMPin)) as device:
device.close()
with pytest.raises(GPIODeviceClosed):
device.on()
def test_output_pwm_write_silly():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
pin.function = 'input'
with pytest.raises(AttributeError):
device.off()
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
reason='timing is too random on pypy')
def test_output_pwm_blink_background():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) 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)
pin.assert_states_and_times([
(0.0, 0),
(0.0, 1),
(0.1, 0),
(0.1, 1),
(0.1, 0)
])
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
reason='timing is too random on pypy')
def test_output_pwm_blink_foreground():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
start = time()
device.blink(0.1, 0.1, n=2, background=False)
assert isclose(time() - start, 0.4, abs_tol=0.05)
pin.assert_states_and_times([
(0.0, 0),
(0.0, 1),
(0.1, 0),
(0.1, 1),
(0.1, 0)
])
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
reason='timing is too random on pypy')
def test_output_pwm_fade_background():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
start = time()
device.blink(0, 0, 0.2, 0.2, n=2)
assert isclose(time() - start, 0, abs_tol=0.05)
device._blink_thread.join()
assert isclose(time() - start, 0.8, abs_tol=0.05)
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_fade_foreground():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
start = time()
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
assert isclose(time() - start, 0.8, abs_tol=0.05)
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_background():
pin = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
start = time()
device.pulse(0.2, 0.2, n=2)
assert isclose(time() - start, 0, abs_tol=0.05)
device._blink_thread.join()
assert isclose(time() - start, 0.8, abs_tol=0.05)
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 = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
start = time()
device.pulse(0.2, 0.2, n=2, background=False)
assert isclose(time() - start, 0.8, abs_tol=0.05)
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 = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with PWMOutputDevice(pin) as device:
device.blink(1, 0.1)
sleep(0.2)
device.off() # should interrupt while on
pin.assert_states([0, 1, 0])
def test_rgbled_missing_pins():
with pytest.raises(ValueError):
RGBLED()
def test_rgbled_initial_value():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b, initial_value=(0.1, 0.2, 0)) as device:
assert r.frequency
assert g.frequency
assert b.frequency
assert isclose(r.state, 0.1)
assert isclose(g.state, 0.2)
assert isclose(b.state, 0.0)
def test_rgbled_initial_value_nonpwm():
r, g, b = (Device._pin_factory.pin(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 = (Device._pin_factory.pin(i, pin_class=MockPWMPin) 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 = (Device._pin_factory.pin(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 = (Device._pin_factory.pin(i, pin_class=MockPWMPin) 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 = (Device._pin_factory.pin(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()
assert device.is_active
assert device.value == (1, 1, 1)
device.off()
assert not device.is_active
assert device.value == (0, 0, 0)
def test_rgbled_bad_value():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) 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 = (Device._pin_factory.pin(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 = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) 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)
def test_rgbled_toggle_nonpwm():
r, g, b = (Device._pin_factory.pin(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)
def test_rgbled_blink_nonpwm():
r, g, b = (Device._pin_factory.pin(i) for i in (1, 2, 3))
with RGBLED(r, g, b, pwm=False) as device:
with pytest.raises(ValueError):
device.blink(fade_in_time=1)
with pytest.raises(ValueError):
device.blink(fade_out_time=1)
@pytest.mark.skipif(hasattr(sys, 'pypy_version_info'),
reason='timing is too random on pypy')
def test_rgbled_blink_background():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) 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_background_nonpwm():
r, g, b = (Device._pin_factory.pin(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():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) 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_blink_foreground_nonpwm():
r, g, b = (Device._pin_factory.pin(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():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) as device:
start = time()
device.blink(0, 0, 0.2, 0.2, n=2)
assert isclose(time() - start, 0, abs_tol=0.05)
device._blink_thread.join()
assert isclose(time() - start, 0.8, abs_tol=0.05)
expected = [
(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),
]
r.assert_states_and_times(expected)
g.assert_states_and_times(expected)
b.assert_states_and_times(expected)
def test_rgbled_fade_background_nonpwm():
r, g, b = (Device._pin_factory.pin(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():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) as device:
start = time()
device.blink(0, 0, 0.2, 0.2, n=2, background=False)
assert isclose(time() - start, 0.8, abs_tol=0.05)
expected = [
(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),
]
r.assert_states_and_times(expected)
g.assert_states_and_times(expected)
b.assert_states_and_times(expected)
def test_rgbled_fade_foreground_nonpwm():
r, g, b = (Device._pin_factory.pin(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():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) as device:
start = time()
device.pulse(0.2, 0.2, n=2)
assert isclose(time() - start, 0, abs_tol=0.05)
device._blink_thread.join()
assert isclose(time() - start, 0.8, abs_tol=0.05)
expected = [
(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),
]
r.assert_states_and_times(expected)
g.assert_states_and_times(expected)
b.assert_states_and_times(expected)
def test_rgbled_pulse_background_nonpwm():
r, g, b = (Device._pin_factory.pin(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():
r, g, b = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) as device:
start = time()
device.pulse(0.2, 0.2, n=2, background=False)
assert isclose(time() - start, 0.8, abs_tol=0.05)
expected = [
(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),
]
r.assert_states_and_times(expected)
g.assert_states_and_times(expected)
b.assert_states_and_times(expected)
def test_rgbled_pulse_foreground_nonpwm():
r, g, b = (Device._pin_factory.pin(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 = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) 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_blink_interrupt_nonpwm():
r, g, b = (Device._pin_factory.pin(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 = (Device._pin_factory.pin(i, pin_class=MockPWMPin) for i in (1, 2, 3))
with RGBLED(r, g, b) as device:
assert not device.closed
device.close()
assert device.closed
device.close()
assert device.closed
def test_rgbled_close_nonpwm():
r, g, b = (Device._pin_factory.pin(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()
def test_motor_pins():
f = Device._pin_factory.pin(1, pin_class=MockPWMPin)
b = Device._pin_factory.pin(2, pin_class=MockPWMPin)
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 = Device._pin_factory.pin(1)
b = Device._pin_factory.pin(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 = Device._pin_factory.pin(1, pin_class=MockPWMPin)
b = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with Motor(f, b) as device:
device.close()
assert device.closed
assert device.forward_device.pin is None
assert device.backward_device.pin is None
device.close()
assert device.closed
def test_motor_close_nonpwm():
f = Device._pin_factory.pin(1)
b = Device._pin_factory.pin(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 = Device._pin_factory.pin(1, pin_class=MockPWMPin)
b = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with Motor(f, b) 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.5
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 = Device._pin_factory.pin(1)
b = Device._pin_factory.pin(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
assert b.state == 0 and f.state == 0
def test_motor_bad_value():
f = Device._pin_factory.pin(1, pin_class=MockPWMPin)
b = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with Motor(f, b) as device:
with pytest.raises(ValueError):
device.value = -2
with pytest.raises(ValueError):
device.value = 2
with pytest.raises(ValueError):
device.forward(2)
with pytest.raises(ValueError):
device.backward(2)
def test_motor_bad_value_nonpwm():
f = Device._pin_factory.pin(1)
b = Device._pin_factory.pin(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 = Device._pin_factory.pin(1, pin_class=MockPWMPin)
b = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with Motor(f, b) 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
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 = Device._pin_factory.pin(1)
b = Device._pin_factory.pin(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
def test_servo_pins():
p = Device._pin_factory.pin(1, pin_class=MockPWMPin)
with Servo(p) as device:
assert device.pwm_device.pin is p
assert isinstance(device.pwm_device, PWMOutputDevice)
def test_servo_bad_value():
p = Device._pin_factory.pin(1, pin_class=MockPWMPin)
with pytest.raises(ValueError):
Servo(p, initial_value=2)
with pytest.raises(ValueError):
Servo(p, min_pulse_width=30/1000)
with pytest.raises(ValueError):
Servo(p, max_pulse_width=30/1000)
def test_servo_pins_nonpwm():
p = Device._pin_factory.pin(2)
with pytest.raises(PinPWMUnsupported):
Servo(p)
def test_servo_close():
p = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with Servo(p) as device:
device.close()
assert device.closed
assert device.pwm_device.pin is None
device.close()
assert device.closed
def test_servo_pulse_width():
p = Device._pin_factory.pin(2, pin_class=MockPWMPin)
with Servo(p, min_pulse_width=5/10000, max_pulse_width=25/10000) as device:
assert isclose(device.min_pulse_width, 5/10000)
assert isclose(device.max_pulse_width, 25/10000)
assert isclose(device.frame_width, 20/1000)
assert isclose(device.pulse_width, 15/10000)
device.value = -1
assert isclose(device.pulse_width, 5/10000)
device.value = 1
assert isclose(device.pulse_width, 25/10000)
device.value = None
assert device.pulse_width is None
def test_servo_values():
p = Device._pin_factory.pin(1, pin_class=MockPWMPin)
with Servo(p) as device:
device.min()
assert device.is_active
assert device.value == -1
assert isclose(p.state, 0.05)
device.max()
assert device.is_active
assert device.value == 1
assert isclose(p.state, 0.1)
device.mid()
assert device.is_active
assert device.value == 0.0
assert isclose(p.state, 0.075)
device.value = 0.5
assert device.is_active
assert device.value == 0.5
assert isclose(p.state, 0.0875)
device.detach()
assert not device.is_active
assert device.value is None
device.value = 0
assert device.value == 0
device.value = None
assert device.value is None
def test_angular_servo_range():
p = Device._pin_factory.pin(1, pin_class=MockPWMPin)
with AngularServo(p, initial_angle=15, min_angle=0, max_angle=90) as device:
assert device.min_angle == 0
assert device.max_angle == 90
def test_angular_servo_angles():
p = Device._pin_factory.pin(1, pin_class=MockPWMPin)
with AngularServo(p) as device:
device.angle = 0
assert device.angle == 0
assert isclose(device.value, 0)
device.max()
assert device.angle == 90
assert isclose(device.value, 1)
device.min()
assert device.angle == -90
assert isclose(device.value, -1)
device.detach()
assert device.angle is None
with AngularServo(p, initial_angle=15, min_angle=0, max_angle=90) as device:
assert device.angle == 15
assert isclose(device.value, -2/3)
device.angle = 0
assert device.angle == 0
assert isclose(device.value, -1)
device.angle = 90
assert device.angle == 90
assert isclose(device.value, 1)
device.angle = None
assert device.angle is None
with AngularServo(p, min_angle=45, max_angle=-45) as device:
assert device.angle == 0
assert isclose(device.value, 0)
device.angle = -45
assert device.angle == -45
assert isclose(device.value, 1)
device.angle = -15
assert device.angle == -15
assert isclose(device.value, 1/3)