Mercurial > templog
comparison py/params.py @ 551:9499bd2f344b
long polling config updates
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 08 Jun 2015 22:29:46 +0800 |
parents | 9b1d71310c83 |
children | 26eee8591f61 |
comparison
equal
deleted
inserted
replaced
550:1040946133ea | 551:9499bd2f344b |
---|---|
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 import collections | 2 import collections |
3 import json | 3 import json |
4 import signal | 4 import signal |
5 import io | 5 import io |
6 import tempfile | |
6 | 7 |
7 import config | 8 import config |
8 from utils import W,L,E,EX | 9 from utils import W,L,E,EX |
10 import utils | |
9 | 11 |
10 _FIELD_DEFAULTS = { | 12 _FIELD_DEFAULTS = { |
11 'fridge_setpoint': 16, | 13 'fridge_setpoint': 16, |
12 'fridge_difference': 0.2, | 14 'fridge_difference': 0.2, |
13 'overshoot_delay': 720, # 12 minutes | 15 'overshoot_delay': 720, # 12 minutes |
22 class Error(Exception): | 24 class Error(Exception): |
23 pass | 25 pass |
24 | 26 |
25 def __init__(self): | 27 def __init__(self): |
26 self.update(_FIELD_DEFAULTS) | 28 self.update(_FIELD_DEFAULTS) |
29 self._epoch = None | |
27 | 30 |
28 def __getattr__(self, k): | 31 def __getattr__(self, k): |
29 return self[k] | 32 return self[k] |
30 | 33 |
31 def __setattr__(self, k, v): | 34 def __setattr__(self, k, v): |
43 if k.startswith('_'): | 46 if k.startswith('_'): |
44 continue | 47 continue |
45 if k not in self: | 48 if k not in self: |
46 raise self.Error("Unknown parameter %s=%s in file '%s'" % (str(k), str(u[k]), getattr(f, 'name', '???'))) | 49 raise self.Error("Unknown parameter %s=%s in file '%s'" % (str(k), str(u[k]), getattr(f, 'name', '???'))) |
47 self.update(u) | 50 self.update(u) |
51 self._epoch = utils.hexnonce() | |
48 | 52 |
49 L("Loaded parameters") | 53 L("Loaded parameters") |
50 L(self.save_string()) | 54 L(self.save_string()) |
51 | 55 |
52 def load(self, f = None): | 56 def load(self, f = None): |
58 return self._do_load(f) | 62 return self._do_load(f) |
59 except IOError as e: | 63 except IOError as e: |
60 W("Missing parameter file, using defaults. %s" % str(e)) | 64 W("Missing parameter file, using defaults. %s" % str(e)) |
61 return | 65 return |
62 | 66 |
63 def _do_save(self, f): | 67 def get_epoch(self): |
64 json.dump(self, f, sort_keys=True, indent=4) | 68 return self._epoch |
65 f.write('\n') | |
66 f.flush() | |
67 | 69 |
68 def save(self, f = None): | 70 def receive(self, params, epoch): |
69 if f: | 71 """ updates parameters from the server. does some validation, |
70 return self._do_save(f) | 72 writes config file to disk. |
71 else: | 73 Returns True on success, False failure |
72 with file(config.PARAMS_FILE, 'w') as f: | 74 """ |
73 return self._do_save(f) | 75 |
76 if epoch != self._epoch: | |
77 return | |
78 | |
79 def same_type(a, b): | |
80 ta = type(a) | |
81 tb = type(b) | |
82 | |
83 if ta == int: | |
84 ta = float | |
85 if tb == int: | |
86 tb = float | |
87 | |
88 return ta == tb | |
89 | |
90 if self.keys() != new_params.keys(): | |
91 diff = self.keys() ^ new_params.keys() | |
92 E("Mismatching params, %s" % str(diff)) | |
93 return False | |
94 | |
95 for k, v in new_params.items(): | |
96 if not same_type(v, self[k]): | |
97 E("Bad type for %s" % k) | |
98 return False | |
99 | |
100 dir = os.path.dirname(config.PARAMS_FILE) | |
101 try: | |
102 t = tempfile.NamedTemporaryFile(prefix='config', | |
103 dir = dir, | |
104 delete = False) | |
105 | |
106 t.write(json.dumps(new_params, sort_keys=True, indent=4)+'\n') | |
107 name = t.name | |
108 t.close() | |
109 | |
110 os.rename(name, config.PARAMS_FILE) | |
111 return True | |
112 except Exception as e: | |
113 E("Problem: %s" % e) | |
114 return False | |
74 | 115 |
75 def save_string(self): | 116 def save_string(self): |
76 s = io.StringIO() | 117 return json.dumps(self, sort_keys=True, indent=4) |
77 self.save(s) | |
78 return s.getvalue() |