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
|
||||
import requests
|
||||
import signal
|
||||
from select import poll, POLLPRI, POLLIN, POLLERR
|
||||
import sys
|
||||
import os
|
||||
import threading
|
||||
import random
|
||||
import logging
|
||||
import time
|
||||
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():
|
||||
GPIO.wait_for_edge(24, GPIO.FALLING)
|
||||
|
||||
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
|
||||
def trans():
|
||||
queuelast = time.time()
|
||||
while True:
|
||||
#wait for a falling edge on gpio 24
|
||||
doMeasurement()
|
||||
|
||||
#get current time and calculate current power from difference
|
||||
current = time.time()
|
||||
diff = current - last
|
||||
power = 1800 / diff
|
||||
if debug:
|
||||
logging.debug("current power: " + str(power))
|
||||
if thGpioExit:
|
||||
break
|
||||
last = current
|
||||
queuedata = powerqueue.get()
|
||||
queuetime = queuedata[0]
|
||||
queueval = str(queuedata[1])
|
||||
if ((queuetime - queuelast) >= 5):
|
||||
payload = "val:" + str(queuetime) + ";" + queueval
|
||||
if sys.stdout.isatty():
|
||||
print("request https://strom.ccc-ffm.de:2342/gettest.php => "+payload)
|
||||
r = requests.post("https://strom.ccc-ffm.de:2342/gettest.php", data=payload, verify=False, auth=('CCC', 'Freundschaft'))
|
||||
if sys.stdout.isatty():
|
||||
print(r)
|
||||
queuelast = queuetime
|
||||
|
||||
# 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()
|
||||
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
|
||||
logging.debug("starting thread trapGpio")
|
||||
th1=threading.Thread(target=trapGpio)
|
||||
logging.debug("starting thread powerTran")
|
||||
th2=threading.Thread(target=powerTran)
|
||||
|
||||
#daemonize these threads
|
||||
th1 = threading.Thread(target=readgpio)
|
||||
th2 = threading.Thread(target=trans)
|
||||
th1.setDaemon(True)
|
||||
th2.setDaemon(True)
|
||||
|
||||
#start these threads
|
||||
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:
|
||||
raw_input("")
|
||||
time.sleep(1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user