multithread rewrite without rpi.gpio
This commit is contained in:
parent
4f17a42bbe
commit
b4de30f825
218
pi/power.py
218
pi/power.py
@ -1,169 +1,81 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import time
|
from select import poll, POLLPRI, POLLIN, POLLERR
|
||||||
import requests
|
|
||||||
import signal
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import threading
|
import threading
|
||||||
import random
|
import time
|
||||||
import logging
|
import queue
|
||||||
|
import requests
|
||||||
|
|
||||||
#initialise some startup values
|
|
||||||
last = time.time()
|
|
||||||
current = time.time()
|
|
||||||
lpower = 10000
|
|
||||||
power = 0
|
|
||||||
thGpioExit = False
|
|
||||||
thTranExit = False
|
|
||||||
debug = False
|
|
||||||
server = "https://strom.ccc-ffm.de"
|
|
||||||
doMeasurement = None
|
|
||||||
doTransfer = None
|
|
||||||
simulation = False
|
|
||||||
|
|
||||||
def measure():
|
def trans():
|
||||||
GPIO.wait_for_edge(24, GPIO.FALLING)
|
queuelast = time.time()
|
||||||
|
|
||||||
def simulate(data=None):
|
|
||||||
if data == None:
|
|
||||||
time.sleep(random.randrange(1, 20, 1)/10)
|
|
||||||
else:
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
def transSimulate(data=None):
|
|
||||||
time.sleep(random.randrange(1, 20, 1)/10)
|
|
||||||
return("HTTP 1.0 - 200")
|
|
||||||
|
|
||||||
def transfer(data):
|
|
||||||
r = requests.post(server, data=data, verify=False)
|
|
||||||
if debug:
|
|
||||||
return(r)
|
|
||||||
|
|
||||||
#define function trapping the gpio interrupts
|
|
||||||
def trapGpio():
|
|
||||||
global last
|
|
||||||
global current
|
|
||||||
global power
|
|
||||||
while True:
|
while True:
|
||||||
#wait for a falling edge on gpio 24
|
queuedata = powerqueue.get()
|
||||||
doMeasurement()
|
queuetime = queuedata[0]
|
||||||
|
queueval = str(queuedata[1])
|
||||||
#get current time and calculate current power from difference
|
if ((queuetime - queuelast) >= 5):
|
||||||
current = time.time()
|
payload = "val:" + str(queuetime) + ";" + queueval
|
||||||
diff = current - last
|
if sys.stdout.isatty():
|
||||||
power = 1800 / diff
|
print("request https://strom.ccc-ffm.de:2342/gettest.php => "+payload)
|
||||||
if debug:
|
r = requests.post("https://strom.ccc-ffm.de:2342/gettest.php", data=payload, verify=False, auth=('CCC', 'Freundschaft'))
|
||||||
logging.debug("current power: " + str(power))
|
if sys.stdout.isatty():
|
||||||
if thGpioExit:
|
print(r)
|
||||||
break
|
queuelast = queuetime
|
||||||
last = current
|
|
||||||
|
|
||||||
# define function transfering the measurments to our webserver
|
|
||||||
def powerTran(once=False):
|
|
||||||
while True:
|
|
||||||
if not once:
|
|
||||||
time.sleep(5)
|
|
||||||
out = str(int(current)) + ";" + str(round(power,0))
|
|
||||||
payload = {"val": out}
|
|
||||||
logging.debug("request: " + server + " => "+ out)
|
|
||||||
transStatus = doTransfer(payload)
|
|
||||||
if simulation:
|
|
||||||
logging.debug("result: HTTP1.0:200")
|
|
||||||
else:
|
|
||||||
logging.debug(transStatus)
|
|
||||||
if once:
|
|
||||||
break
|
|
||||||
if thTranExit:
|
|
||||||
break
|
|
||||||
|
|
||||||
def sigtermHandler(signal, stack):
|
|
||||||
if signal == 2:
|
|
||||||
signal = "SIGINT"
|
|
||||||
elif signal == 15:
|
|
||||||
signal = "SIGTERM"
|
|
||||||
|
|
||||||
logging.info("Signal '%s' received", signal)
|
|
||||||
logging.info("--- powerpi schutdown invoked ---")
|
|
||||||
global th1, th2, thTranExit, thGpioExit
|
|
||||||
thGpioExit = True
|
|
||||||
th1.join()
|
|
||||||
thTranExit = True
|
|
||||||
if not simulation:
|
|
||||||
GPIO.cleanup()
|
|
||||||
logging.info("--- powerpi shutdown completed ---")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def initPowerPi():
|
|
||||||
global last, debug, doMeasurement, doTransfer, simulation
|
|
||||||
|
|
||||||
#checking for debugging mode flag
|
|
||||||
if "-d" in sys.argv:
|
|
||||||
debug=True
|
|
||||||
logging.basicConfig(level = logging.DEBUG, format = '%(asctime)s - %(levelname)8s - %(message)s')
|
|
||||||
else:
|
|
||||||
logging.basicConfig(filename = '/var/log/powerpi.log', level = logging.INFO, format = '%(asctime)s - %(levelname)8s - %(message)s')
|
|
||||||
|
|
||||||
logging.info("--- starting powerpi ---")
|
|
||||||
|
|
||||||
#checking for simulation mode flag
|
|
||||||
if "-s" in sys.argv:
|
|
||||||
logging.info("But it's just a SIMULATION!")
|
|
||||||
simulation = True
|
|
||||||
doMeasurement = simulate
|
|
||||||
doTransfer = simulate
|
|
||||||
else:
|
|
||||||
doMeasurement = measure
|
|
||||||
doTransfer = transfer
|
|
||||||
try:
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
except:
|
|
||||||
logging.critical("Module GPIO not found ... Abort!")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# set gpio port numeration to bcm style
|
|
||||||
GPIO.setmode(GPIO.BCM)
|
|
||||||
|
|
||||||
#initialise gpio on pi 24 as input with an pull_up resistor
|
|
||||||
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
|
||||||
|
|
||||||
#wait for two interrupts to obtain "clean" data
|
|
||||||
for i in range(2):
|
|
||||||
doMeasurement()
|
|
||||||
logging.debug("waiting for 2 interrupts ... [ %s seen ] " % (i))
|
|
||||||
logging.debug("waiting for 2 interrupts ... [ %s seen ] " % (2))
|
|
||||||
|
|
||||||
|
def readgpio():
|
||||||
|
gpio = open("/sys/class/gpio/gpio24/value", "r")
|
||||||
|
gpiopoll = poll()
|
||||||
|
gpiopoll.register(gpio, POLLERR)
|
||||||
|
if sys.stdout.isatty():
|
||||||
|
print("wait for 2 interrupts...")
|
||||||
|
gpioevent = gpiopoll.poll()
|
||||||
|
gpio.read()
|
||||||
|
gpio.seek(0)
|
||||||
last = time.time()
|
last = time.time()
|
||||||
|
gpioevent = gpiopoll.poll()
|
||||||
|
gpio.read()
|
||||||
|
gpio.seek(0)
|
||||||
|
if sys.stdout.isatty():
|
||||||
|
print("start readgpio mainloop")
|
||||||
|
while True:
|
||||||
|
gpioevent = gpiopoll.poll()
|
||||||
|
gpio.read()
|
||||||
|
gpio.seek(0)
|
||||||
|
now = time.time()
|
||||||
|
power = round(1800 / (now-last),2)
|
||||||
|
if sys.stdout.isatty():
|
||||||
|
print("Current power consumption: " + str(power) + " Watt")
|
||||||
|
powerqueue.put([now, power])
|
||||||
|
last = now
|
||||||
|
|
||||||
global th1, th2
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
if not os.path.exists("/sys/class/gpio/gpio24"):
|
||||||
|
gpioinit = open("/sys/class/gpio/export", "w")
|
||||||
|
gpioinit.write("24\n")
|
||||||
|
gpioinit.close()
|
||||||
|
gpiopin = open("/sys/class/gpio/gpio24/direction", "w")
|
||||||
|
gpiopin.write("in")
|
||||||
|
gpiopin.close()
|
||||||
|
gpiotype = open("/sys/class/gpio/gpio24/edge", "w")
|
||||||
|
gpiotype.write("falling")
|
||||||
|
gpiotype.close()
|
||||||
|
except:
|
||||||
|
sys.stderr.write("can't initialize gpio interface\n")
|
||||||
|
sys.stderr.flush()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
powerqueue = queue.Queue()
|
||||||
|
|
||||||
#initialise threads waiting fpr gpio interrupts and tansfering power data
|
th1 = threading.Thread(target=readgpio)
|
||||||
logging.debug("starting thread trapGpio")
|
th2 = threading.Thread(target=trans)
|
||||||
th1=threading.Thread(target=trapGpio)
|
|
||||||
logging.debug("starting thread powerTran")
|
|
||||||
th2=threading.Thread(target=powerTran)
|
|
||||||
|
|
||||||
#daemonize these threads
|
|
||||||
th1.setDaemon(True)
|
th1.setDaemon(True)
|
||||||
th2.setDaemon(True)
|
th2.setDaemon(True)
|
||||||
|
|
||||||
#start these threads
|
|
||||||
th1.start()
|
th1.start()
|
||||||
th2.start()
|
th2.start()
|
||||||
|
|
||||||
logging.info("start up completed - entering logging mode")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
# setting up signal trapping for SIGINT and SIGTERM
|
|
||||||
signal.signal(signal.SIGTERM, sigtermHandler)
|
|
||||||
signal.signal(signal.SIGINT, sigtermHandler)
|
|
||||||
|
|
||||||
# call initialising function
|
|
||||||
initPowerPi()
|
|
||||||
|
|
||||||
# busyloop
|
|
||||||
while True:
|
while True:
|
||||||
raw_input("")
|
time.sleep(1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user