25
|
1 import eg
|
|
2 import zb
|
|
3
|
|
4 class PluginInfo(eg.PluginInfo):
|
|
5 name = "ZigBee"
|
|
6 author = "Darius"
|
|
7 version = "1.0.0"
|
|
8 description = "Listen for data from a Max Stream ZigBee module"
|
|
9
|
|
10
|
|
11
|
|
12 class Text:
|
|
13 port = "Port:"
|
|
14 baudrate = "Baudrate:"
|
|
15 bytesize = "Number of bits:"
|
|
16 parity = "Parity:"
|
|
17 parities = ['No parity', 'Odd', 'Even'] #, 'Mark', 'Space']
|
|
18 stopbits = "Stopbits:"
|
|
19 flowcontrol = "Flow control:"
|
|
20 handshakes = ['None', 'Xon / Xoff', 'Hardware']
|
|
21 generateEvents = "Generate events on incoming data"
|
|
22 eventPrefix = "Event prefix:"
|
|
23
|
|
24
|
|
25 import wx
|
|
26 import threading
|
|
27 import win32event
|
|
28 import win32file
|
|
29
|
|
30 class Serial(eg.RawReceiverPlugin):
|
|
31 canMultiLoad = True
|
|
32 text = Text
|
|
33
|
|
34 def __init__(self):
|
|
35 eg.RawReceiverPlugin.__init__(self)
|
|
36 self.serial = None
|
|
37 self.up = zb.Packets()
|
|
38
|
|
39 def __start__(
|
|
40 self,
|
|
41 port,
|
|
42 baudrate,
|
|
43 bytesize=8,
|
|
44 parity=0,
|
|
45 stopbits=0,
|
|
46 handshake=0,
|
|
47 generateEvents=False,
|
|
48 prefix="Serial",
|
|
49 ):
|
|
50 xonxoff = 0
|
|
51 rtscts = 0
|
|
52 if handshake == 1:
|
|
53 xonxoff = 1
|
|
54 elif handshake == 2:
|
|
55 rtscts = 1
|
|
56
|
|
57 try:
|
|
58 self.serial = eg.SerialPort(
|
|
59 port,
|
|
60 baudrate=baudrate,
|
|
61 bytesize=(5, 6, 7, 8)[bytesize],
|
|
62 stopbits=(1, 2)[stopbits],
|
|
63 parity=('N', 'O', 'E')[parity],
|
|
64 xonxoff=xonxoff,
|
|
65 rtscts=rtscts,
|
|
66 )
|
|
67 except:
|
|
68 self.serial = None
|
|
69 raise eg.Exception("Can't open COM port.")
|
|
70 self.serial.timeout = 1.0
|
|
71 self.serial.setRTS()
|
|
72 self.info.eventPrefix = prefix
|
|
73 self.stopEvent = win32event.CreateEvent(None, 1, 0, None)
|
|
74 self.receiveThread = threading.Thread(target=self.ReceiveThread)
|
|
75 self.receiveThread.start()
|
|
76
|
|
77 def __stop__(self):
|
|
78 if self.serial is not None:
|
|
79 if self.receiveThread:
|
|
80 win32event.SetEvent(self.stopEvent)
|
|
81 self.receiveThread.join(1.0)
|
|
82 self.serial.close()
|
|
83 self.serial = None
|
|
84
|
|
85
|
|
86 def HandleChar(self, ch):
|
|
87 self.up.process(ch)
|
|
88 while (len(self.up.pktq) > 0):
|
|
89 p = self.up.pktq.pop(0)
|
|
90 if (p.PKT_TYPE == zb.RXIO_16_Bit.PKT_TYPE):
|
|
91 dios = (p._data[self.ADDR_SIZE + 5] << 8 |
|
|
92 self._data[self.ADDR_SIZE + 6]) & p.mask
|
|
93 self.TriggerEvent("0x%02x -> 0x%03x" % (p.sender, dios))
|
|
94 self.PrintError(str(p))
|
|
95 else:
|
|
96 self.PrintError("Got unknown packet: " + str(self.buffer))
|
|
97
|
|
98 def ReceiveThread(self):
|
|
99 from win32event import (
|
|
100 ResetEvent,
|
|
101 MsgWaitForMultipleObjects,
|
|
102 QS_ALLINPUT,
|
|
103 WAIT_OBJECT_0,
|
|
104 WAIT_TIMEOUT,
|
|
105 )
|
|
106 from win32file import ReadFile, AllocateReadBuffer, GetOverlappedResult
|
|
107 from win32api import GetLastError
|
|
108
|
|
109 continueLoop = True
|
|
110 overlapped = self.serial._overlappedRead
|
|
111 hComPort = self.serial.hComPort
|
|
112 hEvent = overlapped.hEvent
|
|
113 stopEvent = self.stopEvent
|
|
114 n = 1
|
|
115 waitingOnRead = False
|
|
116 buf = AllocateReadBuffer(n)
|
|
117 while continueLoop:
|
|
118 if not waitingOnRead:
|
|
119 ResetEvent(hEvent)
|
|
120 hr, _ = ReadFile(hComPort, buf, overlapped)
|
|
121 if hr == 997:
|
|
122 waitingOnRead = True
|
|
123 elif hr == 0:
|
|
124 pass
|
|
125 #n = GetOverlappedResult(hComPort, overlapped, 1)
|
|
126 #self.HandleChar(str(buf))
|
|
127 else:
|
|
128 self.PrintError("error")
|
|
129 raise
|
|
130
|
|
131 rc = MsgWaitForMultipleObjects(
|
|
132 (hEvent, stopEvent),
|
|
133 0,
|
|
134 1000,
|
|
135 QS_ALLINPUT
|
|
136 )
|
|
137 if rc == WAIT_OBJECT_0:
|
|
138 n = GetOverlappedResult(hComPort, overlapped, 1)
|
|
139 if n:
|
|
140 self.HandleChar(str(buf))
|
|
141 #else:
|
|
142 # print "WAIT_OBJECT_0", n, str(buf[:n])
|
|
143 waitingOnRead = False
|
|
144 elif rc == WAIT_OBJECT_0+1:
|
|
145 continueLoop = False
|
|
146 elif rc == WAIT_TIMEOUT:
|
|
147 pass
|
|
148 else:
|
|
149 self.PrintError("unknown message")
|
|
150
|
|
151
|
|
152 def Configure(
|
|
153 self,
|
|
154 port=0,
|
|
155 baudrate=9600,
|
|
156 bytesize=8,
|
|
157 parity=0,
|
|
158 stopbits=0,
|
|
159 handshake=0,
|
|
160 generateEvents=False,
|
|
161 prefix="ZB",
|
|
162 ):
|
|
163 text = self.text
|
|
164 dialog = eg.ConfigurationDialog(self)
|
|
165 portCtrl = eg.SerialPortChoice(dialog, value=port)
|
|
166
|
|
167 baudrateCtrl = wx.ComboBox(
|
|
168 dialog,
|
|
169 value=str(baudrate),
|
|
170 choices=[
|
|
171 '110', '300', '600', '1200', '2400', '4800', '9600',
|
|
172 '14400', '19200', '38400', '57600', '115200',
|
|
173 '128000', '256000'
|
|
174 ],
|
|
175 style=wx.CB_DROPDOWN,
|
|
176 validator=eg.DigitOnlyValidator()
|
|
177 )
|
|
178
|
|
179 bytesizeCtrl = wx.Choice(dialog, choices=['5', '6', '7', '8'])
|
|
180 bytesizeCtrl.SetSelection(8 - 5)
|
|
181
|
|
182 parityCtrl = wx.Choice(dialog, choices=text.parities)
|
|
183 parityCtrl.SetSelection(parity)
|
|
184
|
|
185 stopbitsCtrl = wx.Choice(dialog, choices=['1', '2'])
|
|
186 stopbitsCtrl.SetSelection(stopbits)
|
|
187
|
|
188 handshakeCtrl = wx.Choice(dialog, choices=text.handshakes)
|
|
189 handshakeCtrl.SetSelection(handshake)
|
|
190
|
|
191 generateEventsCtrl = wx.CheckBox(dialog, label=text.generateEvents)
|
|
192 generateEventsCtrl.SetValue(generateEvents)
|
|
193
|
|
194 prefixCtrl = wx.TextCtrl(dialog)
|
|
195 prefixCtrl.SetValue(prefix)
|
|
196 prefixCtrl.Enable(generateEvents)
|
|
197
|
|
198 def OnCheckBox(event):
|
|
199 flag = generateEventsCtrl.GetValue()
|
|
200 prefixCtrl.Enable(flag)
|
|
201 generateEventsCtrl.Bind(wx.EVT_CHECKBOX, OnCheckBox)
|
|
202
|
|
203 flags = wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL
|
|
204 mySizer = wx.GridBagSizer(5, 5)
|
|
205 Add = mySizer.Add
|
|
206 Add(wx.StaticText(dialog, -1, text.port), (0, 0), flag=flags)
|
|
207 Add(portCtrl, (0, 1), flag=wx.EXPAND)
|
|
208 Add(wx.StaticText(dialog, -1, text.baudrate), (1, 0), flag=flags)
|
|
209 Add(baudrateCtrl, (1, 1), flag=wx.EXPAND)
|
|
210 Add(wx.StaticText(dialog, -1, text.bytesize), (2, 0), flag=flags)
|
|
211 Add(bytesizeCtrl, (2, 1), flag=wx.EXPAND)
|
|
212 Add(wx.StaticText(dialog, -1, text.parity), (3, 0), flag=flags)
|
|
213 Add(parityCtrl, (3, 1), flag=wx.EXPAND)
|
|
214 Add(wx.StaticText(dialog, -1, text.stopbits), (4, 0), flag=flags)
|
|
215 Add(stopbitsCtrl, (4, 1), flag=wx.EXPAND)
|
|
216 Add(wx.StaticText(dialog, -1, text.flowcontrol), (5, 0), flag=flags)
|
|
217 Add(handshakeCtrl, (5, 1), flag=wx.EXPAND)
|
|
218
|
|
219 Add((5, 5), (6, 0), (1, 2), flag=flags)
|
|
220 Add(generateEventsCtrl, (7, 0), (1, 2), flag=flags)
|
|
221 Add(wx.StaticText(dialog, -1, text.eventPrefix), (9, 0), flag=flags)
|
|
222 Add(prefixCtrl, (9, 1), flag=wx.EXPAND)
|
|
223 dialog.sizer.Add(mySizer)
|
|
224
|
|
225 if dialog.AffirmedShowModal():
|
|
226 return (
|
|
227 portCtrl.GetValue(),
|
|
228 int(baudrateCtrl.GetValue()),
|
|
229 bytesizeCtrl.GetSelection(),
|
|
230 parityCtrl.GetSelection(),
|
|
231 stopbitsCtrl.GetSelection(),
|
|
232 handshakeCtrl.GetSelection(),
|
|
233 generateEventsCtrl.GetValue(),
|
|
234 prefixCtrl.GetValue(),
|
|
235 )
|
|
236
|
|
237
|
|
238
|
|
239
|