Mercurial > templog
annotate py/tempserver.py @ 188:ae5efca89001
working OK
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 07 Feb 2014 23:32:08 +0800 |
parents | c49d87bb81b9 |
children | be579bcf3c7f |
rev | line source |
---|---|
148 | 1 #!/home/matt/templog/venv/bin/python |
141 | 2 |
3 import sys | |
4 import os | |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
5 import logging |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
6 |
141 | 7 import gevent |
145 | 8 import gevent.monkey |
172 | 9 import lockfile.pidlockfile |
162
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
10 import daemon |
141 | 11 |
12 import utils | |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
13 from utils import L,D,EX,W |
145 | 14 import fridge |
15 import config | |
16 import sensor_ds18b20 | |
17 import params | |
160 | 18 import uploader |
145 | 19 |
141 | 20 |
21 class Tempserver(object): | |
22 def __init__(self): | |
23 self.readings = [] | |
145 | 24 self.current = (None, None) |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
25 self.fridge = None |
145 | 26 |
27 # don't patch os, fork() is used by daemonize | |
28 gevent.monkey.patch_all(os=False, thread=False) | |
141 | 29 |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
30 def __enter__(self): |
145 | 31 self.params = params.Params() |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
32 self.fridge = fridge.Fridge(self) |
160 | 33 self.uploader = uploader.Uploader(self) |
145 | 34 self.params.load() |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
35 self.set_sensors(sensor_ds18b20.DS18B20s(self)) |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
36 return self |
141 | 37 |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
38 def __exit__(self, exc_type, exc_value, traceback): |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
39 L("Exiting, cleanup handler"); |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
40 self.fridge.off() |
141 | 41 |
145 | 42 def run(self): |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
43 |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
44 if self.fridge is None: |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
45 raise Exception("Tempserver.run() must be within 'with Tempserver() as server'") |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
46 |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
47 # XXX do these go here or in __enter_() ? |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
48 self.start_time = self.now() |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
49 self.fridge.start() |
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
50 self.sensors.start() |
160 | 51 self.uploader.start() |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
52 |
145 | 53 # won't return. |
54 while True: | |
157 | 55 try: |
56 gevent.sleep(60) | |
57 except KeyboardInterrupt: | |
58 break | |
145 | 59 |
60 def now(self): | |
61 return utils.monotonic_time() | |
62 | |
144 | 63 def set_sensors(self, sensors): |
148 | 64 if hasattr(self, 'sensors'): |
144 | 65 self.sensors.kill() |
66 self.sensors = sensors | |
67 self.wort_name = sensors.wort_name() | |
68 self.fridge_name = sensors.fridge_name() | |
141 | 69 |
70 def take_readings(self): | |
71 ret = self.readings | |
72 self.readings = [] | |
73 return ret | |
74 | |
75 def pushfront(self, readings): | |
76 """ used if a caller of take_readings() fails """ | |
160 | 77 self.readings = readings + self.readings |
141 | 78 |
144 | 79 # a reading is a map of {sensorname: value}. temperatures |
80 # are float degrees | |
141 | 81 def add_reading(self, reading): |
82 """ adds a reading at the current time """ | |
155 | 83 D("add_reading(%s)" % str(reading)) |
145 | 84 self.readings.append( (reading, self.now())) |
144 | 85 self.current = (reading.get(self.wort_name, None), |
86 reading.get(self.fridge_name, None)) | |
160 | 87 if len(self.readings) > config.MAX_READINGS: |
88 self.readings = self.readings[-config.MAX_READINGS:] | |
141 | 89 |
90 def current_temps(self): | |
144 | 91 """ returns (wort_temp, fridge_temp) tuple """ |
148 | 92 return self.current |
145 | 93 |
94 def setup_logging(): | |
95 logging.basicConfig(format='%(asctime)s %(message)s', | |
96 datefmt='%m/%d/%Y %I:%M:%S %p', | |
163 | 97 level=logging.INFO) |
145 | 98 |
162
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
99 def start(): |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
100 with Tempserver() as server: |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
101 server.run() |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
102 |
145 | 103 def main(): |
149
d686b111dab4
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
148
diff
changeset
|
104 setup_logging() |
145 | 105 |
174
c49d87bb81b9
fix to absolute path for lockfile, --daemon does chdir("/")
Matt Johnston <matt@ucc.asn.au>
parents:
172
diff
changeset
|
106 heredir = os.path.abspath(os.path.dirname(__file__)) |
c49d87bb81b9
fix to absolute path for lockfile, --daemon does chdir("/")
Matt Johnston <matt@ucc.asn.au>
parents:
172
diff
changeset
|
107 pidpath = os.path.join(heredir, 'tempserver.pid') |
172 | 108 pidf = lockfile.pidlockfile.PIDLockFile(pidpath, threaded=False) |
109 try: | |
110 pidf.acquire(0) | |
111 pidf.release() | |
112 except lockfile.AlreadyLocked, e: | |
113 pid = pidf.read_pid() | |
114 print>>sys.stderr, "Locked by PID %d" % pid | |
115 if pid > 0: | |
116 try: | |
117 os.kill(pid, 0) | |
118 # must still be running PID | |
119 raise e | |
120 except OSError: | |
121 # isn't still running, steal the lock | |
122 print>>sys.stderr, "Unlinking stale lockfile %s for pid %d" % (pidpath, pid) | |
123 pidf.break_lock() | |
162
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
124 |
145 | 125 if '--daemon' in sys.argv: |
162
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
126 logpath = os.path.join(os.path.dirname(__file__), 'tempserver.log') |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
127 logf = open(logpath, 'a+') |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
128 with daemon.DaemonContext(pidfile=pidf, stdout=logf, stderr = logf): |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
129 start() |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
130 else: |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
131 with pidf: |
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
132 start() |
145 | 133 |
134 if __name__ == '__main__': | |
135 main() |