blob: bcd3b03d4615a57cf2c9df77057ca5054b92249e [file] [log] [blame]
#!/usr/bin/python
"""Blinks a specific LED pattern read from a simple pattern file.
The first value is the state that the LED pattern represents. Followed by
any combination of the following values:
R = Red blink
B = Blue blink
P = Purple blink
An example pattern file might look like:
echo "blink,R,R,R" > /tmp/test.pat
Invoking "ledpattern.py /tmp/test.pat blink" would result in the red LED
blinking three times.
"""
__author__ = 'Chris Gibson <cgibson@google.com>'
import csv
import os
import sys
import time
# Unit tests can override these values.
DISABLE_GPIOMAILBOX = '/tmp/gpio/disable'
SYSFS_RED_BRIGHTNESS = '/sys/class/leds/sys-red/brightness'
SYSFS_BLUE_BRIGHTNESS = '/sys/class/leds/sys-blue/brightness'
SLEEP_TIMEOUT = 0.5
class LedPattern(object):
"""Read, parse, and blink LEDs based on a pattern from a file."""
def ReadCsvPatternFile(self, pattern_file, state):
"""Read a CSV pattern file."""
if not os.path.exists(pattern_file):
print 'Error: Pattern file: "%s" not found.' % pattern_file
return None
if not state:
print 'Error: led state cannot be empty.'
return None
try:
with open(pattern_file, 'r') as f:
patterns = csv.reader(f, delimiter=',')
for row in patterns:
if row[0] == state:
return [c for c in row[1:] if c in ['R', 'B', 'P']]
print ('Error: Could not find led state: "%s" in pattern file: %s'
% (state, pattern_file))
return None
except (IOError, OSError) as ex:
print ('Failed to open the pattern file: %s, error: %s.'
% (pattern_file, ex))
return None
def SetRedBrightness(self, level):
with open(SYSFS_RED_BRIGHTNESS, 'w') as f:
f.write(level)
def SetBlueBrightness(self, level):
with open(SYSFS_BLUE_BRIGHTNESS, 'w') as f:
f.write(level)
def SetLedsOff(self):
self.SetRedBrightness('0')
self.SetBlueBrightness('0')
def RedBlink(self):
self.SetLedsOff()
time.sleep(SLEEP_TIMEOUT)
self.SetRedBrightness('100')
self.SetBlueBrightness('0')
time.sleep(SLEEP_TIMEOUT)
self.SetLedsOff()
def BlueBlink(self):
self.SetLedsOff()
time.sleep(SLEEP_TIMEOUT)
self.SetRedBrightness('0')
self.SetBlueBrightness('100')
time.sleep(SLEEP_TIMEOUT)
self.SetLedsOff()
def PurpleBlink(self):
self.SetLedsOff()
time.sleep(SLEEP_TIMEOUT)
self.SetRedBrightness('100')
self.SetBlueBrightness('100')
time.sleep(SLEEP_TIMEOUT)
self.SetLedsOff()
def PlayPattern(self, pattern):
for color in pattern:
if color == 'R':
self.RedBlink()
elif color == 'B':
self.BlueBlink()
elif color == 'P':
self.PurpleBlink()
def Run(self, pattern_file, state):
"""Sets up an LED pattern to play.
Arguments:
pattern_file: Pattern file containing a list of LED states/patterns.
state: Name of the LED state to play.
Returns:
An integer exit code: 0 means everything succeeded. Non-zero exit codes
mean something went wrong.
"""
try:
open(DISABLE_GPIOMAILBOX, 'w').close()
except (IOError, OSError) as ex:
# If we can't disable gpio-mailbox then we can't guarantee control
# over the LEDs, so we just have to admit defeat.
print 'Error: Failed to disable gpio-mailbox! %s' % ex
return 1
try:
pattern = self.ReadCsvPatternFile(pattern_file, state)
if not pattern:
print 'Reading pattern failed! Exiting!'
return 1
except (IOError, OSError) as ex:
print 'Error: Failed to read pattern file, %s' % ex
return 1
# Depending on what state the LEDs are in when we touched the gpio-mailbox
# disable file, the LEDs will remain in that last state. Firstly, turn both
# LEDs off then sleep for a second to indicate that the pattern is about
# to begin.
self.SetLedsOff()
time.sleep(1)
self.PlayPattern(pattern)
# Turn off the LEDs and sleep for a second to clearly delineate the end of
# the current pattern.
self.SetLedsOff()
time.sleep(1)
os.unlink(DISABLE_GPIOMAILBOX)
return 0
def Usage():
print 'Usage:'
print ' %s {pattern file} {state}' % sys.argv[0]
print
print ' pattern file: path to a pattern file'
print ' state: the LED state to select'
if __name__ == '__main__':
if len(sys.argv) != 3:
Usage()
sys.exit(1)
ledpattern = LedPattern()
sys.exit(ledpattern.Run(sys.argv[1], sys.argv[2]))