USV / UPS Raspberry

26. April 2015 at 18:46
Print Friendly, PDF & Email

Der Medien-Server wird in ein Auto eingebaut werden, dessen Spannungsversorgung erfolgt über das Bordnetz.
Damit der raspberry heruntergefahren wird, habe ich nun eine unterbrechungsfreie Spannungsversorgung (USV) mit einfachen Komponenten realisiert:

  • Produino 5V Spannung Boost Mobile Power Module für ca. 4 EUR bei dealextreme
  • Akku aus einem altem Handy (hat wahrscheinlich jeder rumliegen)

 

 

USV-5

 

USV-6 USV-7USV-4

USV-1

Das folgende Script wird automatisch während des Boot-Vorgangs geladen.

Wenn die Stromversorgung von dem Power Module getrennt wird, erfolgt die Versorgung über den Akku.
Das Script bekommt über einen Interrupt den Wegfall der Hauptversorgung mit, legt sich aber erst einmal schlafen.
Nach einer Wartezeit wird geprüft, ob die Stromversorgung wieder zur Verfügung steht.
Falls dies der Fall ist, wird kein shutdown durchgeführt.
Somit kann man das Fahrzeug betanken und der Medien-Server läuft weiter.

 

 

 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# USV logic for raspberry
# V1.0 2015-04-26 Thomas Hoeser
# 
# USV Logic to control main power failure of shutdown request via Button
#
# Wait for Button
#    - Single press: shutdown raspberry
#    - Double press: reboot raspberry
#
# main power failure
#    - wait for x min to avoid unnecessary shutdowns
#
# crontab -e
# @reboot cd "/home/pi/bin"; sudo ./usv.py > usv.log 2>&1 &
#
# Note, the official Python documentation states a warning about using the shell=True argument.
#
# Python script based on 
# http://www.gtkdb.de/index_36_2238.html
# http://www.forum-raspberrypi.de/Thread-tutorial-hoch-und-runterfahren-mittels-taster-incl-status-led> 
 
 
import RPi.GPIO as GPIO
import time
import subprocess
 
GPIO.setmode(GPIO.BOARD) # use the pin number as on the raspi board
Button_GPIOPin = 5 # s/b 5 for boot / shutdown
USV_GPIOPin    = 13 # Main Power Supply to UPS
LED_GPIOPin    = 11  # LED showing status
 
# define grace period for UPC running w/o main power, just on the battery
PwrGraceMinutes    = 1
PwrGraceSeconds    = PwrGraceMinutes * 60
PwrGraceMSeconds   = PwrGraceSeconds * 1000
 
GPIO.setup  (Button_GPIOPin, GPIO.IN ) # set pin 5 is input
GPIO.setup  (USV_GPIOPin   , GPIO.IN ) # detect UPS level - input
GPIO.setup  (LED_GPIOPin   , GPIO.OUT) # set pin 7 as output and HIGH
GPIO.output (LED_GPIOPin   , True    )
 
Counter = 0
CounterPrior = 0
flagIntUSV = False;
# ----------------------------------------------------------
def Button_Interrupt(channel):
	global Counter
	Counter = Counter + 1
	print "Button interrupt -> Counter :" + str(Counter)
	return
 
# ----------------------------------------------------------
def USV_Interrupt(channel):
	global flagIntUSV
	flagIntUSV = True
	print "USV interrupt"
	return
 
# ----------------------------------------------------------
def myBlink(ledpin, sleeptime, repeat):
	i = 0
	curlevel = 0
	curlevel = GPIO.input(ledpin)
 
	for i in range(0,repeat): 
		print "myblink - " + str(i)
		GPIO.output(ledpin, not curlevel)
		time.sleep(sleeptime) # wait 100ms
		GPIO.output(ledpin, curlevel)
		time.sleep(sleeptime) # wait 100ms
	return
#---------------------------------------------------------
# main function
def main():
 
	global Counter
	global CounterPrior
	global flagIntUSV
 
	print "-----------------------  USV Polling started ...."
	GPIO.add_event_detect(Button_GPIOPin, GPIO.RISING, callback = Button_Interrupt, bouncetime = 200)
	GPIO.add_event_detect(USV_GPIOPin   , GPIO.RISING, callback = USV_Interrupt   , bouncetime = 200)
 
	while True:
		# increment value if button is pressed
		if Counter > CounterPrior:
			if Counter > 1 :
				print "Counter > 1 :" + str(Counter)
				time.sleep(2.0) # wait for more pulses
				print "Counter confirm " + str(Counter)
				if Counter > 3:
					print "reboot"
					myBlink(LED_GPIOPin,0.2,4);
					subprocess.call('date | wall -n; echo USV-PY - REBOOT | wall -n ', shell=True)
					subprocess.call(["shutdown", "-r", "now"])
					return 0
				else:
					print "shutdown now"
					myBlink(LED_GPIOPin,0.2,2);
					subprocess.call('date | wall -n; echo USV-PY - SHUTDOWN NOW | wall -n ', shell=True)
					subprocess.call(["shutdown", "-h", "now"])
					return 0
			CounterPrior = Counter
		# end if Counter
 
		if flagIntUSV :
			print "-------- USV power down "
			print "Main Power Failure -> USV is running on battery now"
			print PwrGraceMSeconds
			subprocess.call('date | wall -n; echo USV-PY - UPS SHUTDOWN NOW | wall -n ', shell=True)
			time.sleep(PwrGraceSeconds) # wait PwrGraceMSeconds
			if (GPIO.input(USV_GPIOPin)):
				flagIntUSV = False
				print "Main Power is back -> do not shutdown"
				subprocess.call('date | wall -n; echo USV-PY - UPS Main Power is back do not shutdown | wall -n ', shell=True)
			else:
				print "Main Power still down -> SHUTDOWN"
				myBlink(LED_GPIOPin,0.2,6);
				subprocess.call('date | wall -n; echo USV-PY - UPS Main Power still down SHUTDOWN | wall -n ', shell=True)
				subprocess.call(["shutdown", "-h", "now"])
				return 0
		# end if flagIntUSV
 
		time.sleep(0.5) # wait 500ms
 
		# 
	return 0
 
if __name__ == '__main__':
 
	 # call main function
	 main()