]> Pileus Git - ~andy/csm213a-hw/blob - vis/visual.py
Save control options
[~andy/csm213a-hw] / vis / visual.py
1 #!/usr/bin/env python
2
3 from gi.repository import Gtk
4 from gi.repository import GLib
5
6 class Visual:
7         def __init__(self, config, device, logger):
8                 def get_objects(names):
9                         return list(map(lambda x:
10                                 self.builder.get_object(x), names))
11
12                 self.config   = config
13                 self.device   = device
14                 self.logger   = logger
15                 self.builder  = Gtk.Builder()
16
17                 self.builder.add_from_file('visual.ui')
18                 self.builder.connect_signals(self)
19                 self.window   = self.builder.get_object("window")
20                 self.settings = self.builder.get_object("settings")
21
22                 self.accs     = get_objects(['accx', 'accy', 'accz'])
23                 self.mags     = get_objects(['magx', 'magy', 'magz'])
24                 self.touch    = get_objects(['touch'])
25                 self.light    = get_objects(['light'])
26                 self.a2ds     = get_objects(['a2d0', 'a2d1', 'a2d2', 'a2d3', 'a2d4', 'a2d5'])
27
28         # Signal handlers
29         def on_hide(self, win, *args):
30                 self.settings.hide()
31                 return True
32
33         def on_show(self, act):
34                 self.settings.show()
35                 return True
36
37         def on_serial(self, act):
38                 if act.get_active():
39                         self.status(self.device.connect())
40                 else:
41                         self.status(self.device.disconnect())
42                 return True
43
44         def on_xively(self, act):
45                 if act.get_active():
46                         self.status(self.logger.connect())
47                 else:
48                         self.status(self.logger.disconnect())
49                 return True
50
51         def on_flush(self, act):
52                 self.logger.flush()
53
54         def on_enable(self, obj):
55                 name  = Gtk.Buildable.get_name(obj)
56                 name  = name.replace('_btn', '')
57                 state = obj.get_active()
58                 if self.config.enable[name] != state:
59                         self.config.enable[name] = state
60                         self.device.control()
61                         self.config.save()
62
63         def on_rate(self, obj):
64                 name  = Gtk.Buildable.get_name(obj)
65                 name  = name.replace('_spin', '')
66                 value = obj.get_value()
67                 if self.config.rate[name] != value:
68                         self.config.rate[name] = value
69                         self.device.control()
70                         self.config.save()
71
72         def on_config(self, obj):
73                 name = Gtk.Buildable.get_name(obj)
74                 if isinstance(obj, Gtk.SpinButton):
75                         value = obj.get_value()
76                 else:
77                         value = obj.get_text()
78                 if getattr(self.config, name) != value:
79                         setattr(self.config, name, value)
80                         self.config.save()
81
82         def on_key(self, win, ev):
83                 if ev.string == 'q':
84                         Gtk.main_quit();
85
86         def on_destroy(self, win):
87                 Gtk.main_quit()
88
89         # Methods
90         def load_config(self):
91                 def set_val(name, val):
92                         self.builder.get_object(name).set_value(val)
93                 def set_txt(name, val):
94                         self.builder.get_object(name).set_text(val)
95                 def set_act(name, val):
96                         self.builder.get_object(name).set_active(val)
97
98                 # Serial settings
99                 set_txt('device',   self.config.device)
100                 set_val('baudrate', self.config.baudrate)
101                 set_txt('parity',   self.config.parity)
102                 set_val('databits', self.config.databits)
103                 set_val('stopbits', self.config.stopbits)
104
105                 # Xively settings
106                 set_txt('feedid',   self.config.feedid)
107                 set_txt('apikey',   self.config.apikey)
108                 set_val('maxrate',  self.config.maxrate)
109
110                 # Sensor settings
111                 for key in list(self.config.enable.keys()):
112                         set_act(key+'_btn',  self.config.enable[key])
113                         set_val(key+'_spin', self.config.rate[key])
114
115
116         def update(self, state):
117                 def setxyz(objs, vals):
118                         if vals[0]: objs[0].set_text('X: %f' % vals[0])
119                         if vals[1]: objs[1].set_text('Y: %f' % vals[1])
120                         if vals[2]: objs[2].set_text('Z: %f' % vals[2])
121                 def setabs(objs, vals):
122                         for i in range(0,len(objs)):
123                                 if vals[i]: objs[i].set_text('%f' % vals[i])
124
125                 setxyz(self.accs,  state.acc)
126                 setxyz(self.mags,  state.mag)
127                 setabs(self.touch, state.touch)
128                 setabs(self.light, state.light)
129                 setabs(self.a2ds,  state.a2d)
130
131         def debug(self, state):
132                 print('update: ' + str(state))
133                 print('\tacc - ' + str(state.acc))
134                 print('\tmag - ' + str(state.mag))
135                 print('\tlgt - ' + str(state.light))
136                 print('\ttch - ' + str(state.touch))
137                 print('\ta2d - ' + str(state.a2d))
138
139         def timer(self):
140                 def check(state, name):
141                         btn = self.builder.get_object(name + '_btn')
142                         con = self.builder.get_object(name + '_con')
143                         img = Gtk.STOCK_YES if state else Gtk.STOCK_NO
144                         btn.set_active(state)
145                         con.set_from_stock(img, Gtk.IconSize.BUTTON)
146
147                 check(self.device.running(), "serial")
148                 check(self.logger.running(), "xively")
149
150                 for item in self.device.process():
151                         self.update(item)
152                         self.logger.append(item)
153                         #self.debug(item)
154
155                 return True
156
157         def run(self):
158                 self.load_config()
159                 self.window.show()
160                 GLib.timeout_add(1000/60, self.timer)
161                 Gtk.main()
162
163         # Private methods
164         def status(self, msg):
165                 if not msg:
166                         return
167                 status = self.builder.get_object("status")
168                 status.push(text=('Error: ' + msg), context_id=0)