#!/usr/bin/env python2 # import time import os from GPIO import GPIO as GP import urllib2 """ This script is run via an SSH forced command that is tied to a particular user and public/private key pair. Commands are read using the original ssh command and are therefore available to this script via the SSH_ORIGINAL_COMMAND environment variable. A set of valid commands are whitelisted and the passed command is checked against this list using an if-formatted case pattern. All commands result in a return of the new state of all LEDs (an implied new status command). LEDs are numbered 1, 2, 3, and 4 on the android app's user interface, so as to be user friendly. Don't confuse the 0 based array index in ledState with the LED number. LED numbers are passed as an argument to the command. There is a space separating the command from its LED arguments. The LED argument is a comma delimited list of one or more numbers representing the LEDs to operate on. Examples: 3 2,4 1,2,3,4 The ALL argument can be used to have the command operate on all LEDs. It is a short cut way of specifying 1,2,3,4. Commands are: STATUS - return a pattern indicating LED state (on/off) - also returns a temperature and humidity from a networked arduino sensor. The returned string is a JSON formatted array indicating the state of each LED, 0 (LOW) respresenting OFF and 1 (HIGH) representing ON. The array's first element represents the first LED which is usually pin 21 on the beaglebone black (BBB). The remaining elements are the rest of the pins 22, 23, and 24 in order (i.e. LED numbers 1 through 4). A sample returned string is as follows (JSON array): [0, 1, 0, 0, 20, 25] Above, the LED on pin 22 (LED 2) is lit up, while the other three LEDs are off. The temperature is 20C and the humidity is 25%. OFF ALL - set all LEDs to off. ON ALL - set all LEDs to on. OFF n1[,n2,...] - set numbered LEDs to off. ON n1[,n2,...] - set numbered LEDs to on. """ # The controller that has the 4 user LEDs is given the number 1 as in # /dev/gpioc1 GPIO_CONTROLLER = 1 LOW = 0 HIGH = 1 leftBracket = "[" rightBracket = "]" temperature = -999 humidity = -999 def JSONstate(leftDelimiter = "[", state_array = [], rightDelimiter = "]"): state_string = ", ".join([str(i) for i in state_array]) return "".join([leftDelimiter, state_string, rightDelimiter]) def getSensorData(): global temperature, humidity try: response = urllib2.urlopen('http://192.168.1.177/', timeout=1) html = response.read() temperature, humidity = html.split(" ") except urllib2.URLError, e: pass pinBus = GP.GPIO(GPIO_CONTROLLER) numPins = 4 ledPins = [21, 22, 23, 24] ledNums = [1, 2, 3, 4] ledState = [0, 0, 0, 0] # Get the current state of the LEDs for index, pin in enumerate(ledPins): ledState[index] = pinBus.pin_get(pin) def get_pins_from_command(command): """ Take the string command, split it on a single space, and then try and parse the LED number arguments. Returns an empty list when things go wrong. Ignores non numeric LED numbers. The LED num argument is a comma separated list of LED numbers between 1 and 4 inclusive. """ command_parts = command.split(" ") if(len(command_parts) != 2): print("Command parts not equal to 2: ", command) return [] # bad arguments, bail, should complain TODO log else: possible_led_numbers = command_parts[1].split(",") num_led_args = len(possible_led_numbers) if (num_led_args <=0 or num_led_args > 4): print("Count of possible led numbers out of range: ", num_led_args) return [] # bad arguments, bail, should complain TODO log good_led_numbers = [] for n in possible_led_numbers: try: num = int(n.strip()) except ValueError: print("Value error on conversion of: ", n) continue if (num in ledNums): good_led_numbers.append(ledPins[num-1]) return good_led_numbers commandText = os.environ.get("SSH_ORIGINAL_COMMAND", "NONE") #commandText = "STATUS" #commandText = "OFF ALL" #commandText = "ON ALL" #commandText = "ON 1,4" if (commandText == "STATUS" ): pass elif (commandText == "ON ALL"): for index, pin in enumerate(ledPins): if (ledState[index] == LOW): pinBus.pin_set(pin, HIGH) elif (commandText == "OFF ALL"): for index, pin in enumerate(ledPins): if (ledState[index] == HIGH): pinBus.pin_set(pin, LOW) elif (commandText.startswith("ON ")): pin_args = get_pins_from_command(commandText) # returns a list of pin numbers (21, ...) for index, pin in enumerate(pin_args): pinBus.pin_set(pin, HIGH) elif (commandText.startswith("OFF ")): pin_args = get_pins_from_command(commandText) # returns a list of pin numbers (21, ...) for index, pin in enumerate(pin_args): pinBus.pin_set(pin, LOW) elif (commandText.startswith("VIDEO ")): print("Running video") exit() else: pass # unknown command, this is a good item to log for security purposes TODO getSensorData() # Get the updated state of the LEDs for index, pin in enumerate(ledPins): ledState[index] = pinBus.pin_get(pin) ledState.append(temperature) ledState.append(humidity) # return the JSON status array to the android caller print(JSONstate(leftBracket, ledState, rightBracket))