Mercurial > ~darius > hgwebdir.cgi > ZigBee
comparison EventGhost.py @ 25:2a1cea865cc0
Add EventGhost module.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Tue, 16 Apr 2013 08:23:00 +0930 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
24:c6ee9eae9e49 | 25:2a1cea865cc0 |
---|---|
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 |