FreshFish is a function decorator for functions with no arguments (hardware query).
The first time the function is called, the wrapper caches the result (the fish). Subsequent calls to the wrapped function simply return the cached result as long as the fish is still fresh. When the fish goes stale, FreshFish calls the underlying function again for FreshFish.
I used this on a BeagleBone project to monitor heart rate, speed, and cadence.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | import math
import time
import serial ## for heart rate monitor
try:
import Adafruit_BBIO.GPIO as GPIO
BBB = True
except:
## easier to write code on laptop then transfer to the BBB
BBB = False
try:
port = '/dev/ttyUSB0'
ser = serial.Serial(port, baudrate=9600, timeout=.1)
except Exception, e:
print 'No heartrate monitor detected', e
ser = None
class FreshFish:
'''
Keep result around for specified time. Refresh when "fish" goes bad
'''
def __init__(self, shelf_life=1):
self.shelf_life = shelf_life
self.last_time = 0
self.last_result = None
def __call__(self, f):
def out():
if time.time() - self.last_time < self.shelf_life:
res = self.last_result
else:
res = f()
self.last_time = time.time()
self.last_result = res
return res
return out
@FreshFish(2)
def getHR():
if BBB and ser:
ser.write('G1' + chr(13))
res = readline()
if len(res) > 5:
out = int(res.split()[2])
else:
out = 0
else:
### return a dummy result
out = int(50 * math.sin(time.time() / 20) + 50)
return out
# ... in GUI
while True:
### getHR() gets called 10x / sec, but FreshFish limits hardware calls to 1x / 2 sec
print getHR()
time.sleep(.1)
|
Result (depends on time) 91 91 91 91 91 91 91 91 91 88 88 88 88