Mercurial > templog
diff py/tempserver.py @ 293:d15dda1b1f76
merge
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 06 Jul 2019 18:29:45 +0800 |
parents | 26eee8591f61 |
children | 20c89630be6c |
line wrap: on
line diff
--- a/py/tempserver.py Thu Mar 19 21:50:52 2015 +0800 +++ b/py/tempserver.py Sat Jul 06 18:29:45 2019 +0800 @@ -5,9 +5,9 @@ import logging import time import signal +import asyncio +import argparse -import gevent -import gevent.monkey import lockfile.pidlockfile import daemon @@ -15,28 +15,28 @@ from utils import L,D,EX,W import fridge import config -import sensor_ds18b20 +import sensor import params import uploader +import configwaiter class Tempserver(object): - def __init__(self): + def __init__(self, test_mode): self.readings = [] self.current = (None, None) self.fridge = None - self._wakeup = gevent.event.Event() - - # don't patch os, fork() is used by daemonize - gevent.monkey.patch_all(os=False, thread=False) + self._wakeup = asyncio.Event() + self._test_mode = test_mode def __enter__(self): self.params = params.Params() self.fridge = fridge.Fridge(self) self.uploader = uploader.Uploader(self) + self.configwaiter = configwaiter.ConfigWaiter(self) self.params.load() - self.set_sensors(sensor_ds18b20.DS18B20s(self)) - gevent.signal(signal.SIGHUP, self._reload_signal) + self.set_sensors(sensor.make_sensor(self)) + asyncio.get_event_loop().add_signal_handler(signal.SIGHUP, self.reload_signal) return self def __exit__(self, exc_type, exc_value, traceback): @@ -50,16 +50,21 @@ # XXX do these go here or in __enter_() ? self.start_time = self.now() - self.fridge.start() - self.sensors.start() - self.uploader.start() + runloops = [ + self.fridge.run(), + self.sensors.run(), + self.uploader.run(), + self.configwaiter.run(), + ] - # won't return. - while True: - try: - gevent.sleep(60) - except KeyboardInterrupt: - break + loop = asyncio.get_event_loop() + try: + loop.run_until_complete(asyncio.gather(*runloops)) + except KeyboardInterrupt: + print('\nctrl-c') + finally: + # loop.close() seems necessary otherwise get warnings about signal handlers + loop.close() def now(self): return utils.monotonic_time() @@ -93,63 +98,88 @@ def current_temps(self): """ returns (wort_temp, fridge_temp) tuple """ + D("current: %s" % str(self.current)) return self.current + @asyncio.coroutine def sleep(self, timeout): """ sleeps for timeout seconds, though wakes if the server's config is updated """ - self._wakeup.wait(timeout) - - def _reload_signal(self): + # XXX fixme - we should wake on _wakeup but asyncio Condition with wait_for is a bit broken? + # https://groups.google.com/forum/#!topic/python-tulip/eSm7rZAe9LM + # For now we just sleep, ignore the _wakeup try: - self.params.load() - L("Reloaded.") + yield from asyncio.wait_for(self._wakeup.wait(), timeout=timeout) + except asyncio.TimeoutError: + pass + + def reload_signal(self, no_file = False): + try: + if not no_file: + self.params.load() + L("Reloaded.") self._wakeup.set() self._wakeup.clear() - except self.Error, e: + except Error as e: W("Problem reloading: %s" % str(e)) -def setup_logging(): + def test_mode(self): + return self._test_mode + +def setup_logging(debug = False): + level = logging.INFO + if debug: + level = logging.DEBUG logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', - level=logging.INFO) + level=level) + #logging.getLogger("asyncio").setLevel(logging.DEBUG) -def start(): - with Tempserver() as server: +def start(test_mode): + with Tempserver(test_mode) as server: server.run() def main(): - setup_logging() + parser = argparse.ArgumentParser() + parser.add_argument('--hup', action='store_true') + parser.add_argument('--new', action='store_true') + parser.add_argument('-D', '--daemon', action='store_true') + parser.add_argument('-d', '--debug', action='store_true') + parser.add_argument('-t', '--test', action='store_true') + args = parser.parse_args() + + setup_logging(args.debug) heredir = os.path.abspath(os.path.dirname(__file__)) pidpath = os.path.join(heredir, 'tempserver.pid') pidf = lockfile.pidlockfile.PIDLockFile(pidpath, threaded=False) - do_hup = '--hup' in sys.argv + + try: pidf.acquire(1) pidf.release() - except (lockfile.AlreadyLocked, lockfile.LockTimeout), e: + except (lockfile.AlreadyLocked, lockfile.LockTimeout) as e: pid = pidf.read_pid() - if do_hup: + if args.hup: try: os.kill(pid, signal.SIGHUP) - print>>sys.stderr, "Sent SIGHUP to process %d" % pid + print("Sent SIGHUP to process %d" % pid, file=sys.stderr) sys.exit(0) except OSError: - print>>sys.stderr, "Process %d isn't running?" % pid + print("Process %d isn't running?" % pid, file=sys.stderr) sys.exit(1) - print>>sys.stderr, "Locked by PID %d" % pid + print("Locked by PID %d" % pid, file=sys.stderr) stale = False if pid > 0: - if '--new' in sys.argv: + if args.new: try: os.kill(pid, 0) except OSError: stale = True if not stale: - print>>sys.stderr, "Stopping old tempserver pid %d" % pid + print("Stopping old tempserver pid %d" % pid, file=sys.stderr) os.kill(pid, signal.SIGTERM) time.sleep(2) pidf.acquire(0) @@ -164,21 +194,21 @@ if stale: # isn't still running, steal the lock - print>>sys.stderr, "Unlinking stale lockfile %s for pid %d" % (pidpath, pid) + print("Unlinking stale lockfile %s for pid %d" % (pidpath, pid), file=sys.stderr) pidf.break_lock() - if do_hup: - print>>sys.stderr, "Doesn't seem to be running" + if args.hup: + print("Doesn't seem to be running", file=sys.stderr) sys.exit(1) - if '--daemon' in sys.argv: + if args.daemon: logpath = os.path.join(os.path.dirname(__file__), 'tempserver.log') logf = open(logpath, 'a+') with daemon.DaemonContext(pidfile=pidf, stdout=logf, stderr = logf): - start() + start(args.test) else: with pidf: - start() + start(args.test) if __name__ == '__main__': main()