Mercurial > ~darius > hgwebdir.cgi > ZigBee
changeset 25:2a1cea865cc0
Add EventGhost module.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Tue, 16 Apr 2013 08:23:00 +0930 |
parents | c6ee9eae9e49 |
children | ca8993488ac5 |
files | EventGhost.py |
diffstat | 1 files changed, 239 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EventGhost.py Tue Apr 16 08:23:00 2013 +0930 @@ -0,0 +1,239 @@ +import eg +import zb + +class PluginInfo(eg.PluginInfo): + name = "ZigBee" + author = "Darius" + version = "1.0.0" + description = "Listen for data from a Max Stream ZigBee module" + + + +class Text: + port = "Port:" + baudrate = "Baudrate:" + bytesize = "Number of bits:" + parity = "Parity:" + parities = ['No parity', 'Odd', 'Even'] #, 'Mark', 'Space'] + stopbits = "Stopbits:" + flowcontrol = "Flow control:" + handshakes = ['None', 'Xon / Xoff', 'Hardware'] + generateEvents = "Generate events on incoming data" + eventPrefix = "Event prefix:" + + +import wx +import threading +import win32event +import win32file + +class Serial(eg.RawReceiverPlugin): + canMultiLoad = True + text = Text + + def __init__(self): + eg.RawReceiverPlugin.__init__(self) + self.serial = None + self.up = zb.Packets() + + def __start__( + self, + port, + baudrate, + bytesize=8, + parity=0, + stopbits=0, + handshake=0, + generateEvents=False, + prefix="Serial", + ): + xonxoff = 0 + rtscts = 0 + if handshake == 1: + xonxoff = 1 + elif handshake == 2: + rtscts = 1 + + try: + self.serial = eg.SerialPort( + port, + baudrate=baudrate, + bytesize=(5, 6, 7, 8)[bytesize], + stopbits=(1, 2)[stopbits], + parity=('N', 'O', 'E')[parity], + xonxoff=xonxoff, + rtscts=rtscts, + ) + except: + self.serial = None + raise eg.Exception("Can't open COM port.") + self.serial.timeout = 1.0 + self.serial.setRTS() + self.info.eventPrefix = prefix + self.stopEvent = win32event.CreateEvent(None, 1, 0, None) + self.receiveThread = threading.Thread(target=self.ReceiveThread) + self.receiveThread.start() + + def __stop__(self): + if self.serial is not None: + if self.receiveThread: + win32event.SetEvent(self.stopEvent) + self.receiveThread.join(1.0) + self.serial.close() + self.serial = None + + + def HandleChar(self, ch): + self.up.process(ch) + while (len(self.up.pktq) > 0): + p = self.up.pktq.pop(0) + if (p.PKT_TYPE == zb.RXIO_16_Bit.PKT_TYPE): + dios = (p._data[self.ADDR_SIZE + 5] << 8 | + self._data[self.ADDR_SIZE + 6]) & p.mask + self.TriggerEvent("0x%02x -> 0x%03x" % (p.sender, dios)) + self.PrintError(str(p)) + else: + self.PrintError("Got unknown packet: " + str(self.buffer)) + + def ReceiveThread(self): + from win32event import ( + ResetEvent, + MsgWaitForMultipleObjects, + QS_ALLINPUT, + WAIT_OBJECT_0, + WAIT_TIMEOUT, + ) + from win32file import ReadFile, AllocateReadBuffer, GetOverlappedResult + from win32api import GetLastError + + continueLoop = True + overlapped = self.serial._overlappedRead + hComPort = self.serial.hComPort + hEvent = overlapped.hEvent + stopEvent = self.stopEvent + n = 1 + waitingOnRead = False + buf = AllocateReadBuffer(n) + while continueLoop: + if not waitingOnRead: + ResetEvent(hEvent) + hr, _ = ReadFile(hComPort, buf, overlapped) + if hr == 997: + waitingOnRead = True + elif hr == 0: + pass + #n = GetOverlappedResult(hComPort, overlapped, 1) + #self.HandleChar(str(buf)) + else: + self.PrintError("error") + raise + + rc = MsgWaitForMultipleObjects( + (hEvent, stopEvent), + 0, + 1000, + QS_ALLINPUT + ) + if rc == WAIT_OBJECT_0: + n = GetOverlappedResult(hComPort, overlapped, 1) + if n: + self.HandleChar(str(buf)) + #else: + # print "WAIT_OBJECT_0", n, str(buf[:n]) + waitingOnRead = False + elif rc == WAIT_OBJECT_0+1: + continueLoop = False + elif rc == WAIT_TIMEOUT: + pass + else: + self.PrintError("unknown message") + + + def Configure( + self, + port=0, + baudrate=9600, + bytesize=8, + parity=0, + stopbits=0, + handshake=0, + generateEvents=False, + prefix="ZB", + ): + text = self.text + dialog = eg.ConfigurationDialog(self) + portCtrl = eg.SerialPortChoice(dialog, value=port) + + baudrateCtrl = wx.ComboBox( + dialog, + value=str(baudrate), + choices=[ + '110', '300', '600', '1200', '2400', '4800', '9600', + '14400', '19200', '38400', '57600', '115200', + '128000', '256000' + ], + style=wx.CB_DROPDOWN, + validator=eg.DigitOnlyValidator() + ) + + bytesizeCtrl = wx.Choice(dialog, choices=['5', '6', '7', '8']) + bytesizeCtrl.SetSelection(8 - 5) + + parityCtrl = wx.Choice(dialog, choices=text.parities) + parityCtrl.SetSelection(parity) + + stopbitsCtrl = wx.Choice(dialog, choices=['1', '2']) + stopbitsCtrl.SetSelection(stopbits) + + handshakeCtrl = wx.Choice(dialog, choices=text.handshakes) + handshakeCtrl.SetSelection(handshake) + + generateEventsCtrl = wx.CheckBox(dialog, label=text.generateEvents) + generateEventsCtrl.SetValue(generateEvents) + + prefixCtrl = wx.TextCtrl(dialog) + prefixCtrl.SetValue(prefix) + prefixCtrl.Enable(generateEvents) + + def OnCheckBox(event): + flag = generateEventsCtrl.GetValue() + prefixCtrl.Enable(flag) + generateEventsCtrl.Bind(wx.EVT_CHECKBOX, OnCheckBox) + + flags = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL + mySizer = wx.GridBagSizer(5, 5) + Add = mySizer.Add + Add(wx.StaticText(dialog, -1, text.port), (0, 0), flag=flags) + Add(portCtrl, (0, 1), flag=wx.EXPAND) + Add(wx.StaticText(dialog, -1, text.baudrate), (1, 0), flag=flags) + Add(baudrateCtrl, (1, 1), flag=wx.EXPAND) + Add(wx.StaticText(dialog, -1, text.bytesize), (2, 0), flag=flags) + Add(bytesizeCtrl, (2, 1), flag=wx.EXPAND) + Add(wx.StaticText(dialog, -1, text.parity), (3, 0), flag=flags) + Add(parityCtrl, (3, 1), flag=wx.EXPAND) + Add(wx.StaticText(dialog, -1, text.stopbits), (4, 0), flag=flags) + Add(stopbitsCtrl, (4, 1), flag=wx.EXPAND) + Add(wx.StaticText(dialog, -1, text.flowcontrol), (5, 0), flag=flags) + Add(handshakeCtrl, (5, 1), flag=wx.EXPAND) + + Add((5, 5), (6, 0), (1, 2), flag=flags) + Add(generateEventsCtrl, (7, 0), (1, 2), flag=flags) + Add(wx.StaticText(dialog, -1, text.eventPrefix), (9, 0), flag=flags) + Add(prefixCtrl, (9, 1), flag=wx.EXPAND) + dialog.sizer.Add(mySizer) + + if dialog.AffirmedShowModal(): + return ( + portCtrl.GetValue(), + int(baudrateCtrl.GetValue()), + bytesizeCtrl.GetSelection(), + parityCtrl.GetSelection(), + stopbitsCtrl.GetSelection(), + handshakeCtrl.GetSelection(), + generateEventsCtrl.GetValue(), + prefixCtrl.GetValue(), + ) + + + +