Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion software/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.ONESHELL:
SOURCES=authbox setup.py
SOURCES=authbox *.py

ifeq ($(shell grep ^ID= /etc/os-release | cut -d = -f 2), raspbian)
RASPBIAN=1
Expand Down
12 changes: 7 additions & 5 deletions software/authbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
__version__ = "2.0.0"

try:
from gpiozero import Device
del Device
from gpiozero import Device

del Device
except ModuleNotFoundError:
print("ERROR: 'gpiozero' must be installed")
import sys
sys.exit(1)
print("ERROR: 'gpiozero' must be installed")
import sys

sys.exit(1)
4 changes: 1 addition & 3 deletions software/authbox/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ def run(self):


class BasePinThread(BaseDerivedThread):
def __init__(
self, event_queue, config_name, input_pin, output_pin
):
def __init__(self, event_queue, config_name, input_pin, output_pin):
super(BasePinThread, self).__init__(event_queue, config_name)

self.input_pin = input_pin
Expand Down
5 changes: 3 additions & 2 deletions software/authbox/badgereader_hid_keystroking.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from authbox.api import BaseDerivedThread, NoMatchingDevice


class HIDKeystrokingReader(BaseDerivedThread):
"""Badge reader hardware abstraction.

Expand Down Expand Up @@ -178,9 +179,9 @@ def __init__(

def setUp(self):
try:
import evdev
import evdev # noqa: F401
except ModuleNotFoundError:
self.fail("evdev not available")
self.fail("evdev not available")

def get_scanner_device(self):
"""Finds connected device matching device_name.
Expand Down
5 changes: 2 additions & 3 deletions software/authbox/badgereader_wiegand_gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ def __init__(
self.timeout_in_seconds = float(timeout_in_ms) / 1000

if self._on_scan:
self.d0_input_device.when_activated = self.decode;
self.d1_input_device.when_activated = self.decode;
self.d0_input_device.when_activated = self.decode
self.d1_input_device.when_activated = self.decode

def decode(self, channel):
bit = "0" if channel == self.d0_input_device else "1"
Expand Down Expand Up @@ -119,4 +119,3 @@ def close(self):
self.d0_input_device.close()
if self.d1_input_device:
self.d1_input_device.close()

5 changes: 3 additions & 2 deletions software/authbox/fake_gpio_for_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@

from __future__ import print_function

import time
import time # noqa: F401


def _log_match(a, b):
return abs(a[0] - b[0]) < 0.1 and a[1] == b[1] and a[2] == b[2]


class FakeTime(object):
"""Fake for the module 'time' so tests run faster."""

def __init__(self):
self.t = 0

def time(self):
def time(self): # noqa: F811
return self.t

def sleep(self, x):
Expand Down
28 changes: 15 additions & 13 deletions software/authbox/gpio_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
"""Abstraction for blinky buttons.
"""

import time

import gpiozero

from authbox.api import BasePinThread
from authbox.compat import queue
import gpiozero
import time


class Button(BasePinThread):
Expand Down Expand Up @@ -55,26 +57,26 @@ def __init__(
self.steady_state = False
self.gpio_led = gpiozero.LED(pin="BOARD" + str(self.output_pin))
button_pin = "BOARD" + str(self.input_pin)
self.gpio_button = gpiozero.Button(button_pin, bounce_time = 0.15)
self.gpio_button = gpiozero.Button(button_pin, bounce_time=0.15)
if self._on_down:
self.gpio_button.when_pressed = self._callback

def _callback(self):
"""Wrapper to queue events instead of calling them directly."""
# If we have a callback registered, debounce the switch press
if (self._on_down):
if self._on_down:
# This is a de-bounce filter to prevent spurious signals from triggering the logic
# Looks for 5 continuous active states (each separated by 10ms)
maxcount = 15 # Look for 150ms maximum
lowcount = 0 # Count the number of active states seen
while ((maxcount > 0) and (lowcount <= 4)):
time.sleep(0.01) # 10ms delay between each cycle
maxcount = maxcount - 1 # Decrement remaining cycles
if (self.gpio_button.is_pressed):
lowcount = lowcount + 1 # One more low cycle detected
maxcount = 15 # Look for 150ms maximum
lowcount = 0 # Count the number of active states seen
while (maxcount > 0) and (lowcount <= 4):
time.sleep(0.01) # 10ms delay between each cycle
maxcount = maxcount - 1 # Decrement remaining cycles
if self.gpio_button.is_pressed:
lowcount = lowcount + 1 # One more low cycle detected
else:
lowcount = 0 # Not continuously low, reset
if (lowcount > 4):
lowcount = 0 # Not continuously low, reset
if lowcount > 4:
self.event_queue.put((self._on_down, self))

def run_inner(self):
Expand Down
3 changes: 2 additions & 1 deletion software/authbox/gpio_buzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
"""
from __future__ import print_function

import gpiozero
import time

import gpiozero

from authbox.api import BasePinThread
from authbox.compat import queue

Expand Down
8 changes: 4 additions & 4 deletions software/authbox/gpio_relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ class Relay(BasePinThread):
"""

def __init__(self, event_queue, config_name, output_type, output_pin):
super(Relay, self).__init__(
event_queue, config_name, None, int(output_pin)
)
super(Relay, self).__init__(event_queue, config_name, None, int(output_pin))
self.output_on_val = types[output_type]
self.gpio_relay = gpiozero.DigitalOutputDevice("BOARD" + str(output_pin), initial_value= not types[output_type])
self.gpio_relay = gpiozero.DigitalOutputDevice(
"BOARD" + str(output_pin), initial_value=not types[output_type]
)
# TODO: Push this initial setup into BasePinThread, to avoid a momentary glitch
self.off()

Expand Down
16 changes: 9 additions & 7 deletions software/authbox/tests/setup_mock_pin_factory.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
try:
from gpiozero import Device
if not Device.pin_factory:
from gpiozero.pins.mock import MockFactory
Device.pin_factory = MockFactory()
from gpiozero import Device

if not Device.pin_factory:
from gpiozero.pins.mock import MockFactory

Device.pin_factory = MockFactory()
except ModuleNotFoundError:
print("ERROR: 'gpiozero' must be installed")
import sys
sys.exit(1)
print("ERROR: 'gpiozero' must be installed")
import sys

sys.exit(1)
30 changes: 16 additions & 14 deletions software/authbox/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@

"""Tests for authbox.api"""

import gpiozero
import gpiozero.pins.mock
import tempfile
import unittest

import setup_mock_pin_factory
import gpiozero
import gpiozero.pins.mock # noqa: F401

import authbox.api
import authbox.config
import authbox.gpio_button

from . import setup_mock_pin_factory # noqa: F401

SAMPLE_CONFIG = b"""
[pins]
button_a = Button:11:38
Expand All @@ -41,17 +42,18 @@ def test_no_duplicate_names(self):
self.assertEqual(len(short_names), len(authbox.api.CLASS_REGISTRY))

def test_all_names_importable(self):
try:
import evdev
del evdev
except ModuleNotFoundError:
self.fail("Test requires evdev, but evdev is not available")

for c in authbox.api.CLASS_REGISTRY:
cls = authbox.api._import(c)
assert issubclass(
cls, (authbox.api.BasePinThread, authbox.api.BaseDerivedThread)
), (c, cls, cls.__bases__)
try:
import evdev

del evdev
except ModuleNotFoundError:
self.fail("Test requires evdev, but evdev is not available")

for c in authbox.api.CLASS_REGISTRY:
cls = authbox.api._import(c)
assert issubclass(
cls, (authbox.api.BasePinThread, authbox.api.BaseDerivedThread)
), (c, cls, cls.__bases__)


class DispatcherTest(unittest.TestCase):
Expand Down
5 changes: 2 additions & 3 deletions software/authbox/tests/test_badgereader_hid_keystroking.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@
import unittest

import authbox.badgereader_hid_keystroking

from authbox.compat import queue


class BadgereaderTest(unittest.TestCase):
def setUp(self):
try:
from authbox import fake_evdev_device_for_testing
from authbox import fake_evdev_device_for_testing
except ModuleNotFoundError:
self.fail("Test requires evdev, but evdev is not available")
self.fail("Test requires evdev, but evdev is not available")

authbox.badgereader_hid_keystroking.evdev.list_devices = (
fake_evdev_device_for_testing.list_devices
Expand Down
9 changes: 4 additions & 5 deletions software/authbox/tests/test_badgereader_wiegand_gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@

"""Tests for authbox.badgereader_wiegand_gpio"""

import gpiozero
import threading
import time
import unittest

import setup_mock_pin_factory

import authbox.badgereader_wiegand_gpio
from authbox.compat import queue

from . import setup_mock_pin_factory # noqa: F401


class BadgereaderWiegandGPIOTest(unittest.TestCase):
def setUp(self):
Expand All @@ -35,7 +34,7 @@ def setUp(self):
"40",
on_scan=self.on_scan,
)

def tearDown(self):
self.b.close()

Expand Down Expand Up @@ -70,7 +69,7 @@ def add_bits_later():
def test_limited_queue_size(self):
self.b.d1_input_device.pin.drive_low()
for i in range(500):
# Send a 0
# Send a 0
self.b.d0_input_device.pin.drive_high()
self.b.d0_input_device.pin.drive_low()
self.b.run_inner()
Expand Down
4 changes: 2 additions & 2 deletions software/authbox/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@

import unittest

import setup_mock_pin_factory

import authbox.config

from . import setup_mock_pin_factory # noqa: F401


class ConfigTest(unittest.TestCase):
def test_parse_time(self):
Expand Down
Loading