Skip to content

Commit

Permalink
Merge pull request #96 from emxsys/gpio-config
Browse files Browse the repository at this point in the history
Updated configuration settings
  • Loading branch information
emxsys authored Aug 30, 2020
2 parents a2e8819 + 1e3e48b commit b423cec
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 84 deletions.
24 changes: 19 additions & 5 deletions callattendant/app.cfg.example
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,23 @@ VOICE_MAIL_MENU_FILE = "resources/voice_mail_menu.wav"
# This should not be changed/overridden except during development/testing
#VOICE_MAIL_MESSAGE_FOLDER = "messages"

GPIO_LED_RING = 4
GPIO_LED_APPROVED = 15
GPIO_LED_BLOCKED = 17
GPIO_LED_MESSAGE = 14
# GPIO_LED_..._PIN: These values are the GPIO pin numbers attached to the LED indicators
# GPIO_LED_..._BRIGHTNESS: These values are a percentage of brightness for the LED indicators when on.
GPIO_LED_RING_PIN = 4
GPIO_LED_RING_BRIGHTNESS = 100

GPIO_LED_APPROVED_PIN = 15
GPIO_LED_APPROVED_BRIGHTNESS = 100

GPIO_LED_BLOCKED_PIN = 17
GPIO_LED_BLOCKED_BRIGHTNESS = 100

GPIO_LED_MESSAGE_PIN = 14
GPIO_LED_MESSAGE_BRIGHTNESS = 100

# GPIO_LED_MESSAGE_COUNT_PINS: This is a tuple containing the GPIO pins for the 7-segment LED
# ordered by segment as thus: (a, b, c, d, e, f, g, dp)
GPIO_LED_MESSAGE_COUNT_PINS = (11, 8, 25, 5, 18, 9, 7, 27)
GPIO_LED_MESSAGE_COUNT_KWARGS = {active_high="False"}

# GPIO_LED_MESSAGE_COUNT_KWARGS: This is a dictionary of optional arguments (used by GPIOZero LEDBoard)
GPIO_LED_MESSAGE_COUNT_KWARGS = {"active_high": False}
8 changes: 6 additions & 2 deletions callattendant/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ def __init__(self, config):
self._caller_queue = queue.Queue()

# Initialize the visual indicators (LEDs)
self.approved_indicator = ApprovedIndicator()
self.blocked_indicator = BlockedIndicator()
self.approved_indicator = ApprovedIndicator(
self.config.get("GPIO_LED_APPROVED_PIN"),
self.config.get("GPIO_LED_APPROVED_BRIGHTNESS", 100))
self.blocked_indicator = BlockedIndicator(
self.config.get("GPIO_LED_BLOCKED_PIN"),
self.config.get("GPIO_LED_BLOCKED_BRIGHTNESS", 100))

# Screening subsystem
self.logger = CallLogger(self.db, self.config)
Expand Down
15 changes: 11 additions & 4 deletions callattendant/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
# and screened callers through to the home phone.
#
default_config = {
"VERSION": '1.0.0',

"ENV": 'production',
"DEBUG": False,
"TESTING": False,

"DATABASE": "callattendant.db",
"SCREENING_MODE": ("whitelist", "blacklist"),

Expand All @@ -48,10 +51,14 @@
"VOICE_MAIL_MENU_FILE": "resources/voice_mail_menu.wav",
"VOICE_MAIL_MESSAGE_FOLDER": "messages",

"GPIO_LED_RING": 14,
"GPIO_LED_APPROVED": 15,
"GPIO_LED_BLOCKED":17,
"GPIO_LED_MESSAGE": 4,
"GPIO_LED_RING_PIN": 14,
"GPIO_LED_RING_BRIGHTNESS": 100,
"GPIO_LED_APPROVED_PIN": 15,
"GPIO_LED_APPROVED_BRIGHTNESS": 100,
"GPIO_LED_BLOCKED_PIN":17,
"GPIO_LED_BLOCKED_BRIGHTNESS":100,
"GPIO_LED_MESSAGE_PIN": 4,
"GPIO_LED_MESSAGE_BRIGHTNESS": 100,
"GPIO_LED_MESSAGE_COUNT_PINS": (11, 8, 25, 5, 18, 9, 7, 27),
"GPIO_LED_MESSAGE_COUNT_KWARGS": {"active_high": False},
}
Expand Down
128 changes: 77 additions & 51 deletions callattendant/hardware/indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,6 @@
GPIO_MESSAGE_COUNT_KWARGS = {"active_high": False}


class LEDIndicator(object):
def turn_on(self):
self.led.on()

def blink(self, max_times=10):
# blink in a separate thread
self.led.blink(0.5, 0.2, max_times)

def turn_off(self):
self.led.off()

def close(self):
self.led.close()

def __init__(self, gpio_pin):
self.led = LED(gpio_pin)


class PWMLEDIndicator(object):

def __init__(self, gpio_pin):
self.led = PWMLED(gpio_pin)

def turn_on(self):
self.led.on()

def turn_off(self):
self.led.off()

def blink(self, max_times=10):
# blink in a separate thread
self.led.blink(0.5, 0.2, n=max_times)

def pulse(self, max_times=10):
# pulse in a separate thread
self.led.pulse(n=max_times)

def close(self):
self.led.close()


class SevenSegmentDisplay(LEDBoard):
"""
Extends :class:`LEDBoard` for a 7 segment LED display
Expand Down Expand Up @@ -243,32 +202,96 @@ def set_char_layout(self, char, layout):
self._layouts[char] = layout


class RingIndicator(PWMLEDIndicator):
class LEDIndicator(object):
def turn_on(self):
self.led.on()

def __init__(self, gpio_pin=GPIO_RING):
super().__init__(gpio_pin)
def blink(self, max_times=10):
# blink in a separate thread
self.led.blink(0.5, 0.2, max_times)

def turn_off(self):
self.led.off()

def close(self):
self.led.close()

def __init__(self, gpio_pin):
self.led = LED(gpio_pin)


class PWMLEDIndicator(object):
"""
A pulse-width modulated LED.
"""

def __init__(self, gpio_pin, brightness=100):
"""
Constructor of a PWM LED.
:param gpio_pin:
GPIO pin assignment (not the header pin number)
:param brightness:
Brightness percentage. Defaults to 100%.
"""
self.led = PWMLED(gpio_pin)
self.brightness = brightness / 100.0 # brightness value is from 0 to 1.0

def turn_on(self):
# ~ self.led.on()
self.led.value = self.brightness

def turn_off(self):
# ~ self.led.off()
self.led.value = 0

def blink(self, max_times=10):
# blink in a separate thread
self.led.blink(0.5, 0.2, n=max_times)

def pulse(self, max_times=10):
# pulse in a separate thread
self.led.pulse(n=max_times)

def close(self):
self.led.close()


class RingIndicator(PWMLEDIndicator):
"""
The ring indicator, activated when an incoming call is being received.
"""
def __init__(self, gpio_pin=GPIO_RING, brightness=100):
super().__init__(gpio_pin, brightness)

def ring(self):
self.blink()
print("{RING LED BLINKING}")


class ApprovedIndicator(PWMLEDIndicator):

def __init__(self, gpio_pin=GPIO_APPROVED):
super().__init__(gpio_pin)
"""
The approved indicator activated when a call from a permitted number is received.
"""
def __init__(self, gpio_pin=GPIO_APPROVED, brightness=100):
super().__init__(gpio_pin, brightness)


class BlockedIndicator(PWMLEDIndicator):
"""
The blocked indicator activated when a call from a blocked number is received.
"""

def __init__(self, gpio_pin=GPIO_BLOCKED):
super().__init__(gpio_pin)
def __init__(self, gpio_pin=GPIO_BLOCKED, brightness=100):
super().__init__(gpio_pin, brightness)


class MessageIndicator(PWMLEDIndicator):
"""
The message indicator activated when the voice messaging features are used.
"""

def __init__(self, gpio_pin=GPIO_MESSAGE):
super().__init__(gpio_pin)
def __init__(self, gpio_pin=GPIO_MESSAGE, brightness=100):
super().__init__(gpio_pin, brightness)

def turn_off(self):
print("{MSG LED OFF}")
Expand All @@ -288,6 +311,9 @@ def pulse(self):


class MessageCountIndicator(SevenSegmentDisplay):
"""
The message count indicator displays the number of unplayed messages in the system.
"""

def __init__(self, *pins, **kwargs):
if len(pins) > 0:
Expand Down
5 changes: 3 additions & 2 deletions callattendant/hardware/modem.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ def __init__(self, config, handle_caller):
self._lock = threading.RLock()

# Ring notifications
self.ring_indicator = RingIndicator()
self.ring_indicator = RingIndicator(
self.config.get("GPIO_LED_RING_PIN"),
self.config.get("GPIO_LED_RING_BRIGHTNESS", 100))
self.ring_event = threading.Event()

# Setup and open the serial port
Expand Down Expand Up @@ -672,4 +674,3 @@ def close_serial_port(self):
def decode(bytestr):
string = bytestr.decode("utf-8").strip(' \t\n\r' + DLE_CODE)
return string

8 changes: 5 additions & 3 deletions callattendant/messaging/voicemail.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ def __init__(self, db, config, modem):
self.config["MESSAGE_EVENT"] = self.message_event

# Initialize the message indicators (LEDs)
self.message_indicator = MessageIndicator(config.get("GPIO_LED_MESSAGE", GPIO_MESSAGE))
pins = config.get("GPIO_LED_MESSAGE_COUNT_PINS", GPIO_MESSAGE_COUNT_PINS)
kwargs = config.get("GPIO_LED_MESSAGE_COUNT_KWARGS", GPIO_MESSAGE_COUNT_KWARGS)
self.message_indicator = MessageIndicator(
self.config.get("GPIO_LED_MESSAGE_PIN", GPIO_MESSAGE),
self.config.get("GPIO_LED_MESSAGE_BRIGHTNESS", 100))
pins = self.config.get("GPIO_LED_MESSAGE_COUNT_PINS", GPIO_MESSAGE_COUNT_PINS)
kwargs = self.config.get("GPIO_LED_MESSAGE_COUNT_KWARGS", GPIO_MESSAGE_COUNT_KWARGS)
self.message_count_indicator = MessageCountIndicator(*pins, **kwargs)

# Create the Message object used to interface with the DB
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
long_description = fh.read()

setuptools.setup(
name="callattendant", # Add user name for upload to TestPyPI
version="0.5.0",
name="callattendant", # Add user name when uploading to TestPyPI
version="1.0.0", # Ensure this is in-sync with VERSION in config.py
author="Bruce Schubert",
author_email="[email protected]",
description="An automated call attendant and call blocker using a Raspberry Pi and USR-5637 modem",
Expand Down
30 changes: 15 additions & 15 deletions tests/test_indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,24 @@ def test_multiple():

config = Config()

# ~ ringer = RingIndicator(config["GPIO_LED_RING"])
# ~ approved = ApprovedIndicator(config["GPIO_LED_APPROVED"])
# ~ blocked = BlockedIndicator(config["GPIO_LED_BLOCKED"])
# ~ message = MessageIndicator(config["GPIO_LED_MESSAGE"])
ringer = RingIndicator(config["GPIO_LED_RING_PIN"], brightness=100)
approved = ApprovedIndicator(config["GPIO_LED_APPROVED_PIN"], brightness=25)
blocked = BlockedIndicator(config["GPIO_LED_BLOCKED_PIN"], brightness=25)
message = MessageIndicator(config["GPIO_LED_MESSAGE_PIN"], brightness=100)

# ~ pins_tuple = config["GPIO_LED_MESSAGE_COUNT_PINS"]
# ~ kwargs_dict = config["GPIO_LED_MESSAGE_COUNT_KWARGS"]
# ~ message_count = MessageCountIndicator(*pins_tuple, **kwargs_dict)
pins_tuple = config["GPIO_LED_MESSAGE_COUNT_PINS"]
kwargs_dict = config["GPIO_LED_MESSAGE_COUNT_KWARGS"]
message_count = MessageCountIndicator(*pins_tuple, **kwargs_dict)

ringer = RingIndicator()
approved = ApprovedIndicator()
blocked = BlockedIndicator()
message = MessageIndicator()
message_count = MessageCountIndicator()
# ~ ringer = RingIndicator()
# ~ approved = ApprovedIndicator()
# ~ blocked = BlockedIndicator()
# ~ message = MessageIndicator()
# ~ message_count = MessageCountIndicator()

for i in range(0, 16):
message_count.display_hex(i)
time.sleep(1)
time.sleep(.5)

print("[Visual Tests]")

Expand All @@ -83,14 +83,14 @@ def test_multiple():
approved.turn_off()
blocked.turn_off()
message.turn_off()
time.sleep(5)
time.sleep(2)


print("Test normal status")
ringer.ring()
message.pulse(),
message_count.display(2)
time.sleep(5)
time.sleep(10)

# Release GPIO pins
ringer.close()
Expand Down

0 comments on commit b423cec

Please sign in to comment.