def receive_messages(self, event): if not self.client: try: host, port = self.host_port self.client = SignalKClient(self.on_con, host, port, autoreconnect=False) self.timer.Start(100) except socket.error: self.timer.Start(1000) return refresh = False while True: result = False try: result = self.client.receive_single() except ConnectionLost: self.client = False return except: pass if not result: break if self.watches[result[0]]: if self.plot.read_data(result): refresh = True if refresh: self.glArea.Refresh()
def receive_messages(self, event): if not self.client: try: host, port = self.host_port self.client = SignalKClient(self.on_con, host, port, autoreconnect=False) self.timer.Start(100) except socket.error: self.timer.Start(1000) return while True: result = False try: result = self.client.receive() except ConnectionLost: self.SetTitle("signalk client - Disconnected") self.client = False return except: pass if not result: break for name in result: if not 'value' in result[name]: print 'no value', result raise 'no value' value = round3(result[name]['value']) strvalue = str(value) if len(strvalue) > 50: strvalue = strvalue[:47] + '...' self.values[name].SetLabel(strvalue) if name in self.controls: try: if str(type(self.controls[name]) ) == "<class 'wx._controls.Choice'>": if not self.controls[name].SetStringSelection( value): print 'warning, invalid choice value specified' elif str(type(self.controls[name]) ) == "<class 'wx._controls.Slider'>": r = self.sliderrange[name] self.controls[name].SetValue( float(value - r[0]) / (r[1] - r[0]) * 1000) else: self.controls[name].SetValue(value) except: self.controls[name].SetValue(str(value)) size = self.GetSize() self.Fit() self.SetSize(size)
def connect(self, dt): if self.client: return watchlist = [ 'ap.enabled', 'ap.mode', 'ap.heading', 'ap.heading_command' ] def on_con(client): for name in watchlist: client.watch(name) try: self.client = SignalKClient(on_con, autoreconnect=True) pass except: return
def __init__(self): super(SignalKScope, self).__init__(None) self.plot = SignalKPlot() self.glContext = wx.glcanvas.GLContext(self.glArea) self.client = SignalKClientFromArgs(sys.argv[:2], True, self.on_con) self.host_port = self.client.host_port self.client.autoreconnect = False self.value_list = self.client.list_values() self.plot.init(self.value_list) self.watches = {} watches = sys.argv[2:] for name in sorted(self.value_list): if self.value_list[name]['type'] != 'SensorValue': continue i = self.clValues.Append(name) self.watches[name] = False for arg in watches: if arg == name: self.clValues.Check(i, True) self.watches[name] = True watches.remove(name) for arg in watches: print 'value not found:', arg self.on_con(self.client) self.timer = wx.Timer(self, wx.ID_ANY) self.Bind(wx.EVT_TIMER, self.receive_messages, id=wx.ID_ANY) self.timer.Start(100) self.sTime.SetValue(self.plot.disptime) self.plot_reshape = False
class SignalKScope(SignalKScopeBase): def __init__(self): super(SignalKScope, self).__init__(None) self.plot = SignalKPlot() self.glContext = wx.glcanvas.GLContext(self.glArea) self.client = SignalKClientFromArgs(sys.argv[:2], True, self.on_con) self.host_port = self.client.host_port self.client.autoreconnect = False self.value_list = self.client.list_values() self.plot.init(self.value_list) self.watches = {} watches = sys.argv[2:] for name in sorted(self.value_list): if self.value_list[name]['type'] != 'SensorValue': continue i = self.clValues.Append(name) self.watches[name] = False for arg in watches: if arg == name: self.clValues.Check(i, True) self.watches[name] = True watches.remove(name) for arg in watches: print 'value not found:', arg self.on_con(self.client) self.timer = wx.Timer(self, wx.ID_ANY) self.Bind(wx.EVT_TIMER, self.receive_messages, id=wx.ID_ANY) self.timer.Start(100) self.sTime.SetValue(self.plot.disptime) self.plot_reshape = False def on_con(self, client): self.plot.add_blank() for i in range(self.clValues.GetCount()): if self.clValues.IsChecked(i): client.watch(self.clValues.GetString(i)) self.watches[self.clValues.GetString(i)] = True def receive_messages(self, event): if not self.client: try: host, port = self.host_port self.client = SignalKClient(self.on_con, host, port, autoreconnect=False) self.timer.Start(100) except socket.error: self.timer.Start(1000) return refresh = False while True: result = False try: result = self.client.receive_single() except ConnectionLost: self.client = False return except: pass if not result: break if self.watches[result[0]]: if self.plot.read_data(result): refresh = True if refresh: self.glArea.Refresh() def onValueSelected(self, event): self.plot.select(self.clValues.GetStringSelection()) def onValueToggled(self, event): value = self.clValues.IsChecked(event.GetInt()) self.watches[event.GetString()] = value self.client.watch(event.GetString(), value) self.plot.add_blank(event.GetString()) def onPaintGL(self, event): dc = wx.PaintDC(self.glArea) self.glArea.SetCurrent(self.glContext) self.plot.fft_on = self.cbfftw.GetValue() if self.plot_reshape: apply(self.plot.reshape, self.plot_reshape) self.plot_reshape = False self.plot.display() self.glArea.SwapBuffers() def onSizeGL(self, event): self.plot_reshape = (event.GetSize().x, event.GetSize().y) def onMouseEvents(self, event): self.glArea.SetFocus() pos = event.GetPosition() if event.LeftDown(): self.lastmouse = pos if event.RightDown(): self.plot.curtrace.center() self.glArea.Refresh() if event.Dragging(): offset = pos[1] - self.lastmouse[1] self.plot.adjustoffset(offset, self.glArea.GetSize().y) self.lastmouse = pos self.glArea.Refresh() rotation = event.GetWheelRotation() / 60 if rotation: if rotation > 0: self.plot.increasescale() else: self.plot.decreasescale() self.glArea.Refresh() def onKeyPress(self, event): wxglutkeypress(event, self.plot.special, self.plot.key) self.cbfftw.SetValue(self.plot.fft_on) self.glArea.Refresh() def onZero(self, event): if self.plot.curtrace: self.plot.curtrace.offset = 0 self.glArea.Refresh() def onCenter(self, event): if self.plot.curtrace: self.plot.curtrace.center() self.glArea.Refresh() def onScalePlus(self, event): self.plot.increasescale() self.glArea.Refresh() def onScaleMinus(self, event): self.plot.decreasescale() self.glArea.Refresh() def onOffsetPlus(self, event): self.plot.curtrace.offset -= self.plot.scale / 10.0 self.glArea.Refresh() def onOffsetMinus(self, event): self.plot.curtrace.offset += self.plot.scale / 10.0 self.glArea.Refresh() def onFreeze(self, event): self.plot.freeze = event.IsChecked() self.glArea.Refresh() def onReset(self, event): self.plot.reset() self.glArea.Refresh() def onTime(self, event): self.plot.disptime = self.sTime.GetValue() self.glArea.Refresh() def onClose(self, event): self.Close()
def __init__(self): wx.Frame.__init__(self, None, title="signalk client", size=(1000, 600)) self.value_list = [] self.client = SignalKClientFromArgs(sys.argv, True, self.on_con) self.host_port = self.client.host_port self.client.autoreconnect = False ssizer = wx.FlexGridSizer(0, 1, 0, 0) ssizer.AddGrowableRow(0) ssizer.AddGrowableCol(0) ssizer.SetFlexibleDirection(wx.BOTH) ssizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) self.scrolledWindow = wx.ScrolledWindow(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.HSCROLL | wx.VSCROLL) self.scrolledWindow.SetScrollRate(5, 5) sizer = wx.FlexGridSizer(0, 3, 0, 0) sizer.AddGrowableCol(2) sizer.SetFlexibleDirection(wx.BOTH) sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) self.values = {} self.controls = {} self.sliderrange = {} self.value_list = self.client.list_values() self.on_con(self.client) for name in sorted(self.value_list): sizer.Add(wx.StaticText(self.scrolledWindow, wx.ID_ANY, name), 0, wx.ALL, 5) self.values[name] = wx.StaticText(self.scrolledWindow, wx.ID_ANY) sizer.Add(self.values[name], 0, wx.ALL, 5) t = self.value_list[name]['type'] if t == 'Property': tb = wx.TextCtrl(self.scrolledWindow, wx.ID_ANY) sizer.Add(tb) self.controls[name] = tb elif t == 'BooleanProperty': def proc(): # encapsulate to fix scope cb = wx.CheckBox(self.scrolledWindow, wx.ID_ANY, '') sizer.Add(cb, 0, wx.EXPAND) self.controls[name] = cb cbname = name def oncheck(event): self.client.set(cbname, cb.GetValue()) cb.Bind(wx.EVT_CHECKBOX, oncheck) proc() elif t == 'RangeProperty': useSlider = True def proc(): r = self.value_list[name]['min'], self.value_list[name][ 'max'] if useSlider: s = wx.Slider(self.scrolledWindow) s.SetRange(0, 1000) else: s = wx.SpinCtrlDouble(self.scrolledWindow) s.SetRange(r[0], r[1]) s.SetIncrement(min(1, (r[1] - r[0]) / 100.0)) s.SetDigits(-math.log(s.GetIncrement()) / math.log(10) + 1) sizer.Add(s, 0, wx.EXPAND) self.controls[name] = s sname = name def onspin(event): if useSlider: v = s.GetValue() / 1000.0 * (r[1] - r[0]) + r[0] self.client.set(sname, v) else: self.client.set(sname, s.GetValue()) if useSlider: s.Bind(wx.EVT_SLIDER, onspin) self.sliderrange[name] = r else: s.Bind(wx.EVT_SPINCTRLDOUBLE, onspin) proc() elif t == 'EnumProperty': def proc(): c = wx.Choice(self.scrolledWindow, wx.ID_ANY) for choice in self.value_list[name]['choices']: c.Append(str(choice)) sizer.Add(c, 0, wx.EXPAND) self.controls[name] = c cname = name def onchoice(event): self.client.set(cname, str(c.GetStringSelection())) c.Bind(wx.EVT_CHOICE, onchoice) proc() elif t == 'ResettableValue': def proc(): b = wx.Button(self.scrolledWindow, wx.ID_ANY, 'Reset') sizer.Add(b, 0, wx.EXPAND) bname = name def onclick(event): self.client.set(bname, 0) b.Bind(wx.EVT_BUTTON, onclick) proc() else: sizer.Add(wx.StaticText(self.scrolledWindow, wx.ID_ANY, '')) self.scrolledWindow.SetSizer(sizer) self.scrolledWindow.Layout() sizer.Fit(self.scrolledWindow) ssizer.Add(self.scrolledWindow, 1, wx.EXPAND | wx.ALL, 5) bsizer = wx.FlexGridSizer(1, 0, 0, 0) self.bRefresh = wx.Button(self, wx.ID_ANY, 'Refresh') self.bRefresh.Bind(wx.EVT_BUTTON, self.Refresh) bsizer.Add(self.bRefresh) self.bScope = wx.Button(self, wx.ID_ANY, 'Scope') self.bScope.Bind( wx.EVT_BUTTON, lambda event: subprocess.Popen([ 'python', os.path.abspath(os.path.dirname(__file__)) + '/' + 'scope_wx.py' ] + sys.argv[1:])) bsizer.Add(self.bScope) self.bClose = wx.Button(self, wx.ID_ANY, 'Close') self.bClose.Bind(wx.EVT_BUTTON, exit) bsizer.Add(self.bClose) ssizer.Add(bsizer, 1, wx.EXPAND) self.SetSizer(ssizer) self.Layout() self.timer = wx.Timer(self, wx.ID_ANY) self.timer.Start(500) self.Bind(wx.EVT_TIMER, self.receive_messages, id=wx.ID_ANY) self.Refresh()
class MainFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, title="signalk client", size=(1000, 600)) self.value_list = [] self.client = SignalKClientFromArgs(sys.argv, True, self.on_con) self.host_port = self.client.host_port self.client.autoreconnect = False ssizer = wx.FlexGridSizer(0, 1, 0, 0) ssizer.AddGrowableRow(0) ssizer.AddGrowableCol(0) ssizer.SetFlexibleDirection(wx.BOTH) ssizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) self.scrolledWindow = wx.ScrolledWindow(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.HSCROLL | wx.VSCROLL) self.scrolledWindow.SetScrollRate(5, 5) sizer = wx.FlexGridSizer(0, 3, 0, 0) sizer.AddGrowableCol(2) sizer.SetFlexibleDirection(wx.BOTH) sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) self.values = {} self.controls = {} self.sliderrange = {} self.value_list = self.client.list_values() self.on_con(self.client) for name in sorted(self.value_list): sizer.Add(wx.StaticText(self.scrolledWindow, wx.ID_ANY, name), 0, wx.ALL, 5) self.values[name] = wx.StaticText(self.scrolledWindow, wx.ID_ANY) sizer.Add(self.values[name], 0, wx.ALL, 5) t = self.value_list[name]['type'] if t == 'Property': tb = wx.TextCtrl(self.scrolledWindow, wx.ID_ANY) sizer.Add(tb) self.controls[name] = tb elif t == 'BooleanProperty': def proc(): # encapsulate to fix scope cb = wx.CheckBox(self.scrolledWindow, wx.ID_ANY, '') sizer.Add(cb, 0, wx.EXPAND) self.controls[name] = cb cbname = name def oncheck(event): self.client.set(cbname, cb.GetValue()) cb.Bind(wx.EVT_CHECKBOX, oncheck) proc() elif t == 'RangeProperty': useSlider = True def proc(): r = self.value_list[name]['min'], self.value_list[name][ 'max'] if useSlider: s = wx.Slider(self.scrolledWindow) s.SetRange(0, 1000) else: s = wx.SpinCtrlDouble(self.scrolledWindow) s.SetRange(r[0], r[1]) s.SetIncrement(min(1, (r[1] - r[0]) / 100.0)) s.SetDigits(-math.log(s.GetIncrement()) / math.log(10) + 1) sizer.Add(s, 0, wx.EXPAND) self.controls[name] = s sname = name def onspin(event): if useSlider: v = s.GetValue() / 1000.0 * (r[1] - r[0]) + r[0] self.client.set(sname, v) else: self.client.set(sname, s.GetValue()) if useSlider: s.Bind(wx.EVT_SLIDER, onspin) self.sliderrange[name] = r else: s.Bind(wx.EVT_SPINCTRLDOUBLE, onspin) proc() elif t == 'EnumProperty': def proc(): c = wx.Choice(self.scrolledWindow, wx.ID_ANY) for choice in self.value_list[name]['choices']: c.Append(str(choice)) sizer.Add(c, 0, wx.EXPAND) self.controls[name] = c cname = name def onchoice(event): self.client.set(cname, str(c.GetStringSelection())) c.Bind(wx.EVT_CHOICE, onchoice) proc() elif t == 'ResettableValue': def proc(): b = wx.Button(self.scrolledWindow, wx.ID_ANY, 'Reset') sizer.Add(b, 0, wx.EXPAND) bname = name def onclick(event): self.client.set(bname, 0) b.Bind(wx.EVT_BUTTON, onclick) proc() else: sizer.Add(wx.StaticText(self.scrolledWindow, wx.ID_ANY, '')) self.scrolledWindow.SetSizer(sizer) self.scrolledWindow.Layout() sizer.Fit(self.scrolledWindow) ssizer.Add(self.scrolledWindow, 1, wx.EXPAND | wx.ALL, 5) bsizer = wx.FlexGridSizer(1, 0, 0, 0) self.bRefresh = wx.Button(self, wx.ID_ANY, 'Refresh') self.bRefresh.Bind(wx.EVT_BUTTON, self.Refresh) bsizer.Add(self.bRefresh) self.bScope = wx.Button(self, wx.ID_ANY, 'Scope') self.bScope.Bind( wx.EVT_BUTTON, lambda event: subprocess.Popen([ 'python', os.path.abspath(os.path.dirname(__file__)) + '/' + 'scope_wx.py' ] + sys.argv[1:])) bsizer.Add(self.bScope) self.bClose = wx.Button(self, wx.ID_ANY, 'Close') self.bClose.Bind(wx.EVT_BUTTON, exit) bsizer.Add(self.bClose) ssizer.Add(bsizer, 1, wx.EXPAND) self.SetSizer(ssizer) self.Layout() self.timer = wx.Timer(self, wx.ID_ANY) self.timer.Start(500) self.Bind(wx.EVT_TIMER, self.receive_messages, id=wx.ID_ANY) self.Refresh() def Refresh(self): for name in self.value_list: self.client.get(name) def on_con(self, client): self.SetTitle("signalk client - Connected") for name in sorted(self.value_list): t = self.value_list[name]['type'] if t != 'SensorValue': client.watch(name) else: client.get(name) def receive_messages(self, event): if not self.client: try: host, port = self.host_port self.client = SignalKClient(self.on_con, host, port, autoreconnect=False) self.timer.Start(100) except socket.error: self.timer.Start(1000) return while True: result = False try: result = self.client.receive() except ConnectionLost: self.SetTitle("signalk client - Disconnected") self.client = False return except: pass if not result: break for name in result: if not 'value' in result[name]: print 'no value', result raise 'no value' value = round3(result[name]['value']) strvalue = str(value) if len(strvalue) > 50: strvalue = strvalue[:47] + '...' self.values[name].SetLabel(strvalue) if name in self.controls: try: if str(type(self.controls[name]) ) == "<class 'wx._controls.Choice'>": if not self.controls[name].SetStringSelection( value): print 'warning, invalid choice value specified' elif str(type(self.controls[name]) ) == "<class 'wx._controls.Slider'>": r = self.sliderrange[name] self.controls[name].SetValue( float(value - r[0]) / (r[1] - r[0]) * 1000) else: self.controls[name].SetValue(value) except: self.controls[name].SetValue(str(value)) size = self.GetSize() self.Fit() self.SetSize(size)
class AutopilotControlApp(App): def build(self): self.client = False self.connect(3) Clock.schedule_interval(self.connect, 3) Clock.schedule_interval(self.update, .1) self.enabled = False self.mode = 'compass' self.heading_command = 0 self.heading = 0 self._anim = None self.texture = Image(source='compass.png').texture self.control = AutopilotControl() return self.control def connect(self, dt): if self.client: return watchlist = [ 'ap.enabled', 'ap.mode', 'ap.heading', 'ap.heading_command' ] def on_con(client): for name in watchlist: client.watch(name) try: self.client = SignalKClient(on_con, autoreconnect=True) pass except: return def update(self, dt): if not self.client: return result = self.client.receive() for msg in result: value = result[msg]['value'] if msg == 'ap.enabled' or msg == 'ap.mode': if msg == 'ap.enabled': self.enabled = value else: self.mode = value color = 'ff0000' if self.enabled: colors = { 'compass': '******', 'gps': '0000ff', 'wind': 'ffff00' } color = colors[self.mode] self.control.ap.text = '[color=' + color + ']AP' elif msg == 'ap.heading': self.control.heading_label.text = str(value) self.control.compass.heading = value #self.control.compass.canvas.needs_redraw = 1 elif msg == 'ap.heading_command': self.control.heading_command_label.text = str(value) self.heading_command = value def onAP(self): if not self.client: return self.client.set('servo.raw_command', False) if self.enabled: self.client.set('ap.heading_command', self.heading) self.client.set('ap.enabled', True) else: self.client.set('servo.command', 0) self.client.set('ap.enabled', False)