Mercurial > templog
annotate py/params.py @ 581:b4d6f1ae0b9e
make overshoot_factor floating point
add a proper error message for noparamsyet
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 29 Nov 2015 09:30:36 +0800 |
parents | 54ef7f84487d |
children |
rev | line source |
---|---|
444 | 1 # -*- coding: utf-8 -*- |
2 import collections | |
3 import json | |
456 | 4 import signal |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
5 import tempfile |
556 | 6 import os |
7 import binascii | |
456 | 8 |
444 | 9 import config |
447 | 10 from utils import W,L,E,EX |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
11 import utils |
444 | 12 |
13 _FIELD_DEFAULTS = { | |
14 'fridge_setpoint': 16, | |
15 'fridge_difference': 0.2, | |
16 'overshoot_delay': 720, # 12 minutes | |
17 'overshoot_factor': 1, # ÂșC | |
461
1eb68df9f8ab
Add daemon mode with locking, add "disabled" parameter
Matt Johnston <matt@ucc.asn.au>
parents:
459
diff
changeset
|
18 'disabled': False, |
467 | 19 'nowort': False, |
469
de4abcbe8f46
make fridge air range a parameter
Matt Johnston <matt@ucc.asn.au>
parents:
467
diff
changeset
|
20 'fridge_range_lower': 3, |
de4abcbe8f46
make fridge air range a parameter
Matt Johnston <matt@ucc.asn.au>
parents:
467
diff
changeset
|
21 'fridge_range_upper': 3, |
444 | 22 } |
23 | |
24 class Params(dict): | |
25 class Error(Exception): | |
26 pass | |
27 | |
28 def __init__(self): | |
29 self.update(_FIELD_DEFAULTS) | |
556 | 30 self._set_epoch(None) |
444 | 31 |
32 def __getattr__(self, k): | |
33 return self[k] | |
34 | |
35 def __setattr__(self, k, v): | |
36 # fail if we set a bad value | |
37 self[k] | |
38 self[k] = v | |
39 | |
556 | 40 def _set_epoch(self, epoch): |
41 # since __setattr__ is overridden | |
42 object.__setattr__(self, '_epoch', epoch) | |
43 | |
532
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
44 def _do_load(self, f): |
456 | 45 try: |
556 | 46 u = utils.json_load_round_float(f.read()) |
529 | 47 except Exception as e: |
456 | 48 raise self.Error(e) |
49 | |
444 | 50 for k in u: |
463
f2cca8062128
- use the fridge temperature for control too, keep it in a 6deg band
Matt Johnston <matt@ucc.asn.au>
parents:
461
diff
changeset
|
51 if k.startswith('_'): |
f2cca8062128
- use the fridge temperature for control too, keep it in a 6deg band
Matt Johnston <matt@ucc.asn.au>
parents:
461
diff
changeset
|
52 continue |
444 | 53 if k not in self: |
54 raise self.Error("Unknown parameter %s=%s in file '%s'" % (str(k), str(u[k]), getattr(f, 'name', '???'))) | |
55 self.update(u) | |
556 | 56 # new epoch, 120 random bits |
57 self._set_epoch(binascii.hexlify(os.urandom(15)).decode()) | |
444 | 58 |
459 | 59 L("Loaded parameters") |
60 L(self.save_string()) | |
61 | |
532
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
62 def load(self, f = None): |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
63 if f: |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
64 return self._do_load(f) |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
65 else: |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
66 with open(config.PARAMS_FILE, 'r') as f: |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
67 try: |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
68 return self._do_load(f) |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
69 except IOError as e: |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
70 W("Missing parameter file, using defaults. %s" % str(e)) |
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
71 return |
459 | 72 |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
73 def get_epoch(self): |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
74 return self._epoch |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
75 |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
76 def receive(self, params, epoch): |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
77 """ updates parameters from the server. does some validation, |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
78 writes config file to disk. |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
79 Returns True on success, False failure |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
80 """ |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
81 |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
82 if epoch != self._epoch: |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
83 return |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
84 |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
85 def same_type(a, b): |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
86 ta = type(a) |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
87 tb = type(b) |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
88 |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
89 if ta == int: |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
90 ta = float |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
91 if tb == int: |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
92 tb = float |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
93 |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
94 return ta == tb |
456 | 95 |
556 | 96 if self.keys() != params.keys(): |
97 diff = self.keys() ^ params.keys() | |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
98 E("Mismatching params, %s" % str(diff)) |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
99 return False |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
100 |
556 | 101 for k, v in params.items(): |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
102 if not same_type(v, self[k]): |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
103 E("Bad type for %s" % k) |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
104 return False |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
105 |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
106 dir = os.path.dirname(config.PARAMS_FILE) |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
107 try: |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
108 t = tempfile.NamedTemporaryFile(prefix='config', |
561 | 109 mode='w+t', # NamedTemporaryFile is binary by default |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
110 dir = dir, |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
111 delete = False) |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
112 |
556 | 113 out = json.dumps(params, sort_keys=True, indent=4)+'\n' |
114 t.write(out) | |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
115 name = t.name |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
116 t.close() |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
117 |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
118 os.rename(name, config.PARAMS_FILE) |
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
119 except Exception as e: |
556 | 120 EX("Problem: %s" % e) |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
121 return False |
532
9b1d71310c83
better arg parser. seems close to ready
Matt Johnston <matt@ucc.asn.au>
parents:
530
diff
changeset
|
122 |
561 | 123 self.update(params) |
124 L("Received parameters") | |
125 L(self.save_string()) | |
126 return True | |
127 | |
459 | 128 def save_string(self): |
551
9499bd2f344b
long polling config updates
Matt Johnston <matt@ucc.asn.au>
parents:
532
diff
changeset
|
129 return json.dumps(self, sort_keys=True, indent=4) |