Mercurial > templog
annotate py/params.py @ 253:0a1b642e3086
long polling config updates
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 08 Jun 2015 22:29:46 +0800 |
parents | 19569cb5ed46 |
children | 26eee8591f61 |
rev | line source |
---|---|
145 | 1 # -*- coding: utf-8 -*- |
2 import collections | |
3 import json | |
157 | 4 import signal |
230 | 5 import io |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
6 import tempfile |
157 | 7 |
145 | 8 import config |
148 | 9 from utils import W,L,E,EX |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
10 import utils |
145 | 11 |
12 _FIELD_DEFAULTS = { | |
13 'fridge_setpoint': 16, | |
14 'fridge_difference': 0.2, | |
15 'overshoot_delay': 720, # 12 minutes | |
16 'overshoot_factor': 1, # ÂșC | |
162
d73077e8cd67
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
160
diff
changeset
|
17 'disabled': False, |
168 | 18 'nowort': False, |
170
78255c49bf9a
make fridge air range a parameter
Matt Johnston <matt@ucc.asn.au>
parents:
168
diff
changeset
|
19 'fridge_range_lower': 3, |
78255c49bf9a
make fridge air range a parameter
Matt Johnston <matt@ucc.asn.au>
parents:
168
diff
changeset
|
20 'fridge_range_upper': 3, |
145 | 21 } |
22 | |
23 class Params(dict): | |
24 class Error(Exception): | |
25 pass | |
26 | |
27 def __init__(self): | |
28 self.update(_FIELD_DEFAULTS) | |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
29 self._epoch = None |
145 | 30 |
31 def __getattr__(self, k): | |
32 return self[k] | |
33 | |
34 def __setattr__(self, k, v): | |
35 # fail if we set a bad value | |
36 self[k] | |
37 self[k] = v | |
38 | |
233
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
39 def _do_load(self, f): |
157 | 40 try: |
41 u = json.load(f) | |
230 | 42 except Exception as e: |
157 | 43 raise self.Error(e) |
44 | |
145 | 45 for k in u: |
166
5d5424acfed0
- use the fridge temperature for control too, keep it in a 6deg band
Matt Johnston <matt@ucc.asn.au>
parents:
162
diff
changeset
|
46 if k.startswith('_'): |
5d5424acfed0
- use the fridge temperature for control too, keep it in a 6deg band
Matt Johnston <matt@ucc.asn.au>
parents:
162
diff
changeset
|
47 continue |
145 | 48 if k not in self: |
49 raise self.Error("Unknown parameter %s=%s in file '%s'" % (str(k), str(u[k]), getattr(f, 'name', '???'))) | |
50 self.update(u) | |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
51 self._epoch = utils.hexnonce() |
145 | 52 |
160 | 53 L("Loaded parameters") |
54 L(self.save_string()) | |
55 | |
233
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
56 def load(self, f = None): |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
57 if f: |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
58 return self._do_load(f) |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
59 else: |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
60 with open(config.PARAMS_FILE, 'r') as f: |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
61 try: |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
62 return self._do_load(f) |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
63 except IOError as e: |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
64 W("Missing parameter file, using defaults. %s" % str(e)) |
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
65 return |
160 | 66 |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
67 def get_epoch(self): |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
68 return self._epoch |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
69 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
70 def receive(self, params, epoch): |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
71 """ updates parameters from the server. does some validation, |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
72 writes config file to disk. |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
73 Returns True on success, False failure |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
74 """ |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
75 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
76 if epoch != self._epoch: |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
77 return |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
78 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
79 def same_type(a, b): |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
80 ta = type(a) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
81 tb = type(b) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
82 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
83 if ta == int: |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
84 ta = float |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
85 if tb == int: |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
86 tb = float |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
87 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
88 return ta == tb |
157 | 89 |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
90 if self.keys() != new_params.keys(): |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
91 diff = self.keys() ^ new_params.keys() |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
92 E("Mismatching params, %s" % str(diff)) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
93 return False |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
94 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
95 for k, v in new_params.items(): |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
96 if not same_type(v, self[k]): |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
97 E("Bad type for %s" % k) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
98 return False |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
99 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
100 dir = os.path.dirname(config.PARAMS_FILE) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
101 try: |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
102 t = tempfile.NamedTemporaryFile(prefix='config', |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
103 dir = dir, |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
104 delete = False) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
105 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
106 t.write(json.dumps(new_params, sort_keys=True, indent=4)+'\n') |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
107 name = t.name |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
108 t.close() |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
109 |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
110 os.rename(name, config.PARAMS_FILE) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
111 return True |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
112 except Exception as e: |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
113 E("Problem: %s" % e) |
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
114 return False |
233
19569cb5ed46
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
231
diff
changeset
|
115 |
160 | 116 def save_string(self): |
253
0a1b642e3086
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
233
diff
changeset
|
117 return json.dumps(self, sort_keys=True, indent=4) |