diff --git a/bmc.sh b/bmc.sh old mode 100644 new mode 100755 index 17535d5..1d663d9 --- a/bmc.sh +++ b/bmc.sh @@ -4,25 +4,18 @@ stty eof undef stty intr undef hostsystem="$( cat /etc/bmchost )" -packages=( screen wiringpi ) -pkgfail="" -for package in ${packages[@]}; do - dpkg -l | grep "^ii ${package}" &>/dev/null || pkgfail="true" -done -if test -n "$pkgfail"; then - echo -n "Installing required packages... " - sudo apt update &>/dev/null - sudo apt install -y ${packages[@]} &>/dev/null - echo "done." -fi +bmcd_cmdpipe="/run/bmcd/bmcd.cmd" +bmcd_statepipe="/run/bmcd/bmcd.state" help() { echo -e "Available commands:" echo -e " \e[1mstate\e[0m - Show the system power state" echo -e " \e[1mconsole\e[0m - Connect to host via serial console; ^A+D to disconnect" - echo -e " \e[1mpowersw\e[0m - Press power switch on host" - echo -e " \e[1mresetsw\e[0m - Press reset switch on host" + echo -e " \e[1mpower\e[0m - Press power switch on host" + echo -e " \e[1mreset\e[0m - Press reset switch on host" echo -e " \e[1mkill\e[0m - Forcibly power off host" + echo -e " \e[1mlocate\e[0m - Enable locator (flash power LED)" + echo -e " \e[1munlocate\e[0m - Disable locator" echo -e " \e[1mhelp\e[0m - This help menu" echo -e " \e[1mbmc\e[0m - Show BMC information" echo -e " \e[1mhostname\e[0m - Set BMC hostname" @@ -60,33 +53,30 @@ setpassword() { echo "Passwords to not match!" fi } -resetsw() { - echo -n "Pressing reset switch... " - gpio mode 0 out - gpio write 0 1 - sleep 1 - gpio write 0 0 - sleep 1 - echo "done." +resetsw_press() { + echo "Pressing reset switch." + echo "resetsw_press" > ${bmcd_cmdpipe} } -powersw() { - if [ "$1" == "hard" ]; then - delay='sleep 10' - echo -n "Holding power switch... " - else - delay='sleep 1' - echo -n "Pressing power switch... " - fi - gpio mode 1 out - gpio write 1 1 - $delay - gpio write 1 0 +powersw_press() { + echo "Holding power switch." + echo "powersw_hold" > ${bmcd_cmdpipe} sleep 2 - echo "done." +} +powersw_hold() { + echo "Pressing power switch." + echo "powersw_press" > ${bmcd_cmdpipe} + sleep 2 +} +locate_on() { + echo "Enabling locator - host power LED will flash." + echo "locate_on" > ${bmcd_cmdpipe} +} +locate_off() { + echo "Disabling locator." + echo "locate_off" > ${bmcd_cmdpipe} } readpower() { - gpio mode 2 in - powerstate_raw=$(gpio read 2) + powerstate_raw=$(cat ${bmcd_statepipe}) if [ "${powerstate_raw}" -eq 1 ]; then powerstate="\e[32mOn\e[0m" else @@ -118,26 +108,37 @@ case $input in ;; 'console') echo "Starting console..." + # Connect to screen, or start it sudo screen -r serialconsole &>/dev/null || sudo screen -S serialconsole /dev/ttyUSB0 115200 + # If the user killed screen, restart it - just in case + pgrep screen &>/dev/null || sudo screen -S serialconsole /dev/ttyUSB0 115200 echo ;; 'powersw') - powersw soft + powersw_press readpower echo -e "Host state: $powerstate" echo ;; 'resetsw') - resetsw + resetsw_press readpower echo -e "Host state: $powerstate" echo ;; 'kill') - powersw hard + powersw_hold readpower echo -e "Host state: $powerstate" echo + ;; + 'locate') + locate_on + echo + ;; + 'unlocate') + locate_off + echo ;; 'help') help diff --git a/bmcd b/bmcd index 8f3e6e5..a6e7a1e 100755 --- a/bmcd +++ b/bmcd @@ -1,9 +1,9 @@ -#!/usr/bin/python +#!/usr/bin/env python import socket, os, time, struct -from threading import Thread +from threading import Thread, Event from daemon import runner -#import RPi.GPIO as GPIO +import RPi.GPIO as GPIO gpio_state = '11' gpio_psw = '12' @@ -14,21 +14,73 @@ bmcd_state = '/run/bmcd/bmcd.state' bmcd_cmd = '/run/bmcd/bmcd.cmd' pidfile = '/run/bmcd/bmcd.pid' -class readcmd(Thread): - def run(self): - while True: - print "Hi" - line = fcmd.readline() - print line - line = "" - time.sleep(1) +is_pled_flashing = Event() -class writestate(Thread): - def run(self): - while True: - print "Derp" - fstate.write("Writing state\n") # Write str length and str - time.sleep(1) +def powerled_on(): + GPIO.input(gpip_pled, 1) + +def powerled_off(): + GPIO.input(gpip_pled, 0) + +def powerled_flash(is_pled_flashing): + while is_pled_flashing.isSet(): + GPIO.input(gpip_pled, 1) + time.sleep(1) + GPIO.input(gpip_pled, 0) + time.sleep(1) + is_pled_flashing.clear() + return + +def powersw_press(): + GPIO.input(gpip_psw, 1) + time.sleep(0.5) + GPIO.input(gpio_psw, 0) + +def powersw_hold(): + GPIO.input(gpip_psw, 1) + time.sleep(8) + GPIO.input(gpio_psw, 0) + +def resetsw_press(): + GPIO.input(gpip_rsw, 1) + time.sleep(0.5) + GPIO.input(gpio_rsw, 0) + +def locate_on(): + is_pled_flashing.set() + t = Thread(name='non-block', target=powerled_flash, args=(is_pled_flashing,)) + t.start() + +def locate_off(): + is_pled_flashing.clear() + +def readcmd(): + fcmd = open(bmcd_cmd, 'r+b', 0) + while True: + line = fcmd.readline() + try: + globals()[line.rstrip()]() + except: + pass + +def writestate(is_pled_flashing): + fstate = open(bmcd_state, 'w+b', 0) + state_prev = 1 + while True: + state_now = GPIO.input(gpio_state) + if state_now != state_prev: + fstate.write(str(state_now)) + state_prev = state_now + else: + pass + + if not is_pled_flashing.isSet(): + if state_now == 1: + powerled_on() + else: + powerled_off() + + time.sleep(1) class App(): @@ -39,30 +91,25 @@ class App(): self.pidfile_path = pidfile self.pidfile_timeout = 5 def run(self): - print "Starting daemon." if not os.path.exists(bmcd_state): os.mkfifo(bmcd_state) if not os.path.exists(bmcd_cmd): os.mkfifo(bmcd_cmd) - fstate = open(bmcd_state, 'w+b', 0) - fcmd = open(bmcd_cmd, 'r+b', 0) - -# thread.start_new_thread(readcmd(fcmd)) -# thread.start_new_thread(writestate(fstate)) - wthread = Thread(target=writestate(fstate)) - rthread = Thread(target=readcmd(fcmd)) - wthread.daemon = True - rthread.daemon = True - wthread.start() - rthread.start() - -# GPIO.setmode(GPIO.BOARD) -# GPIO.setup(gpio_state, GPIO.OUT) -# GPIO.setup(gpio_psw, GPIO.OUT) -# GPIO.setup(gpio_rsw, GPIO.IN) -# GPIO.setup(gpio_pled, GPIO.OUT) + GPIO.setmode(GPIO.BOARD) + GPIO.setup(gpio_state, GPIO.OUT) + GPIO.setup(gpio_psw, GPIO.OUT) + GPIO.setup(gpio_rsw, GPIO.IN) + GPIO.setup(gpio_pled, GPIO.OUT) + t1 = Thread(target=readcmd) + t2 = Thread(target=writestate, args=(is_pled_flashing,)) + t1.setDaemon(True) + t2.setDaemon(True) + t1.start() + t2.start() + while True: + pass app = App() daemon_runner = runner.DaemonRunner(app)