]> sigrok.org Git - sigrok-meter.git/blame - sigrok-meter
Support all units.
[sigrok-meter.git] / sigrok-meter
CommitLineData
5add80f6
JS
1#!/usr/bin/env python
2
c09ca11b
UH
3##
4## This file is part of the sigrok-meter project.
5##
6## Copyright (C) 2013 Uwe Hermann <uwe@hermann-uwe.de>
7##
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21##
22
782f5926 23import argparse
13e332b7
UH
24from multiprocessing import Process, Queue
25from gi.repository import Gtk, GObject
f94bb73f 26import re
efdef4fa 27import sigrok.core as sr
782f5926 28import sys
f94bb73f 29import textwrap
13e332b7 30
f94bb73f 31default_drivers = [('demo', {'analog_channels': 1})]
782f5926
JS
32default_loglevel = sr.LogLevel.WARN
33
fdb40b43
JS
34def format_unit(u):
35 units = {
36 sr.Unit.VOLT: 'V',
37 sr.Unit.AMPERE: 'A',
38 sr.Unit.OHM: u'\u03A9',
39 sr.Unit.FARAD: 'F',
40 sr.Unit.KELVIN: 'K',
41 sr.Unit.CELSIUS: u'\u00B0C',
42 sr.Unit.FAHRENHEIT: u'\u00B0F',
43 sr.Unit.HERTZ: 'Hz',
44 sr.Unit.PERCENTAGE: '%',
45 # sr.Unit.BOOLEAN
46 sr.Unit.SECOND: 's',
47 sr.Unit.SIEMENS: 'S',
48 sr.Unit.DECIBEL_MW: 'dBu',
49 sr.Unit.DECIBEL_VOLT: 'dBV',
50 # sr.Unit.UNITLESS
51 sr.Unit.DECIBEL_SPL: 'dB',
52 # sr.Unit.CONCENTRATION
53 sr.Unit.REVOLUTIONS_PER_MINUTE: 'rpm',
54 sr.Unit.VOLT_AMPERE: 'VA',
55 sr.Unit.WATT: 'W',
56 sr.Unit.WATT_HOUR: 'Wh',
57 sr.Unit.METER_SECOND: 'm/s',
58 sr.Unit.HECTOPASCAL: 'hPa',
59 sr.Unit.HUMIDITY_293K: '%rF',
60 sr.Unit.DEGREE: u'\u00B0',
61 sr.Unit.HENRY: 'H'
62 }
63
64 return units.get(u, '')
65
f94bb73f 66def init_and_run(queue, drivers, loglevel):
13e332b7 67 def datafeed_in(device, packet):
efdef4fa 68 if packet.type == sr.PacketType.ANALOG:
13e332b7 69 data = packet.payload.data
fdb40b43 70 unit_str = format_unit(packet.payload.unit)
92ba651c 71 mqflags, mqflags_str = packet.payload.mq_flags, ""
fdb40b43 72
efdef4fa 73 if sr.QuantityFlag.AC in mqflags:
fdb40b43 74 mqflags_str = "AC"
efdef4fa 75 elif sr.QuantityFlag.DC in mqflags:
fdb40b43
JS
76 mqflags_str = "DC"
77
13e332b7 78 for i in range(packet.payload.num_samples):
53fed2c3 79 dev = "%s %s" % (device.vendor, device.model)
fdb40b43
JS
80 mag_str = "%f" % data[0][i]
81 val = ' '.join([mag_str, unit_str, mqflags_str])
49e0ee28 82 queue.put((dev, val))
13e332b7 83
efdef4fa 84 context = sr.Context_create()
782f5926 85 context.log_level = loglevel
f94bb73f
JS
86
87 devices = []
88 for name, options in drivers:
89 try:
90 dr = context.drivers[name]
91 devices.append(dr.scan(**options)[0])
92 except:
93 print('error getting device for driver "{}", skipping'.format(name))
94
95 if not devices:
96 print('no devices found')
97 return
98
92ba651c 99 session = context.create_session()
49e0ee28
UH
100 for dev in devices:
101 session.add_device(dev)
92ba651c
JS
102 dev.open()
103 session.add_datafeed_callback(datafeed_in)
13e332b7
UH
104 session.start()
105 session.run()
106 session.stop()
c09ca11b 107
730cbd1f
UH
108class SigrokMeter:
109 def __init__(self):
110 self.builder = Gtk.Builder()
111 self.builder.add_from_file("sigrok-meter.glade")
112 self.builder.connect_signals(self)
13e332b7 113 self.value_label = self.builder.get_object("value_label")
49e0ee28 114 self.value_label2 = self.builder.get_object("value_label2")
fd029d02 115 self.win = self.builder.get_object("mainwindow")
730cbd1f 116 self.win.show_all()
13e332b7
UH
117 self.queue = Queue()
118 GObject.timeout_add(100, self.update_label_if_needed)
119
120 def update_label_if_needed(self):
121 try:
122 t = self.queue.get_nowait()
49e0ee28
UH
123 l = self.value_label if t[0] != "Victor" else self.value_label2
124 l.set_text("%s: %s" % (t[0], t[1]))
13e332b7
UH
125 except:
126 pass
127 GObject.timeout_add(100, self.update_label_if_needed)
730cbd1f 128
fd029d02 129 def on_quit(self, *args):
2f5ef701 130 Gtk.main_quit(*args)
730cbd1f 131
fd029d02 132 def on_about(self, action):
730cbd1f 133 about = self.builder.get_object("aboutdialog")
efdef4fa 134 context = sr.Context_create()
92ba651c
JS
135 sr_pkg = context.package_version
136 sr_lib = context.lib_version
a683a5e2
UH
137 s = "Using libsigrok %s (lib version %s)." % (sr_pkg, sr_lib)
138 about.set_comments(s)
dd73092b
UH
139 about.run()
140 about.hide()
2f5ef701 141
f94bb73f 142def parse_cli():
782f5926 143 parser = argparse.ArgumentParser(
f94bb73f
JS
144 description='Simple sigrok GUI for multimeters and dataloggers.',
145 epilog=textwrap.dedent('''\
146 The DRIVER string is the same as for sigrok-cli(1).
147
148 examples:
149
150 %(prog)s --driver tecpel-dmm-8061-ser:conn=/dev/ttyUSB0
151
152 %(prog)s --driver uni-t-ut61e:conn=1a86.e008
153 '''),
154 formatter_class=argparse.RawDescriptionHelpFormatter)
155
156 parser.add_argument('-d', '--driver',
157 action='append',
158 help='The driver to use')
782f5926
JS
159 parser.add_argument('-l', '--loglevel',
160 type=int,
161 help='Set loglevel (5 is most verbose)')
162 args = parser.parse_args()
163
f94bb73f
JS
164 result = {
165 'drivers': default_drivers,
166 'loglevel': default_loglevel
167 }
168
169 if args.driver:
170 result['drivers'] = []
171 for d in args.driver:
172 m = re.match('(?P<name>[^:]+)(?P<opts>(:[^:=]+=[^:=]+)*)', d)
173 if not m:
174 sys.exit('error parsing option "{}"'.format(d))
175
176 opts = m.group('opts').split(':')[1:]
177 opts = [tuple(kv.split('=')) for kv in opts]
178 opts = dict(opts)
179
180 result['drivers'].append((m.group('name'), opts))
181
782f5926
JS
182 if args.loglevel != None:
183 try:
f94bb73f 184 result['loglevel'] = sr.LogLevel.get(args.loglevel)
782f5926
JS
185 except:
186 sys.exit('error: invalid log level')
187
f94bb73f
JS
188 return result
189
190if __name__ == '__main__':
191 args = parse_cli()
9e7bd3d2 192 s = SigrokMeter()
f94bb73f
JS
193 process = Process(target=init_and_run,
194 args=(s.queue, args['drivers'], args['loglevel']))
9e7bd3d2
UH
195 process.start()
196 Gtk.main()
197 process.terminate()
c09ca11b 198