class GameVoice(eg.PluginClass): def __init__(self): self.thread = None def ButtonCallback(self, data): btnPressed = [] for num in data: btnPressed.append(ButtonMapping[num]) buttonsCount = len(btnPressed) if buttonsCount == 0: self.TriggerEvent("None") elif buttonsCount == 1: self.TriggerEvent(btnPressed[0]) else: self.TriggerEvent("+".join(btnPressed)) def StopCallback(self): self.TriggerEvent("Stopped") self.thread = None def GetMyDevicePath(self): path = GetDevicePath(None, VENDOR_ID, PRODUCT_ID, None, 0, True, 0) return path def SetupHidThread(self, newDevicePath): #create thread self.thread = HIDThread(self.name, newDevicePath, self.name) self.thread.start() self.thread.SetStopCallback(self.StopCallback) self.thread.SetButtonCallback(self.ButtonCallback) def SetFeature(self, buffer): if self.thread: self.thread.SetFeature(buffer) def ReconnectDevice(self, event): """method to reconnect a disconnect device""" if self.thread == None: if not IsDeviceName(event.payload, VENDOR_ID, PRODUCT_ID): return #check if the right device was connected #getting devicePath newDevicePath = self.GetMyDevicePath() if not newDevicePath: #wrong device return self.SetupHidThread(newDevicePath) def __start__(self): #Bind plug in to RegisterDeviceNotification message eg.Bind("System.DeviceAttached", self.ReconnectDevice) newDevicePath = self.GetMyDevicePath() if not newDevicePath: #device not found self.PrintError(Text.errorFind) else: self.SetupHidThread(newDevicePath) def __stop__(self): if self.thread: self.thread.AbortThread() #unbind from RegisterDeviceNotification message eg.Unbind("System.DeviceAttached", self.ReconnectDevice)
class HIDPS3(eg.PluginClass): def __init__(self): self.text = Text self.thread = None self.PS3Remote = PS3Remote self.batteryLevel = None self.AddAction(GetBatteryLevel) def RawCallback(self, data): #hexdata= binascii.hexlify(data).upper() #eg.PrintNotice( hexdata ) try: if len(data) != 12: raise PS3ParseError( 'length', 12, len(data) ) start= ord( data[0] ) mask= ord( data[1] )<<16 | ord( data[2] )<<8 | ord( data[3] ) code= ord( data[4] ) dummy= data[5:10] state= ord( data[10] ) battery= ord( data[11] ) if start != 0x01: raise PS3ParseError( 'data[0]', '0x01', hex(start) ) if dummy != "\xff\xff\xff\xff\xff": raise PS3ParseError( 'data[5:10]', '0xffffffffff', hex(dummy) ) if battery > 0x05: raise PS3ParseError( 'battery level', '0-5', battery ) if( battery < 0x02 ): eg.PrintNotice( 'PS3 Remote: Battery Level: ' + self.text.batteryLevel[battery] ) #self.TriggerEvent( # 'Code: ' + hex(code) + # ' State: ' + hex(state) + # ' Battery Level: ' + str(battery) + ':' + # self.text.batteryLevel[battery] + # ' Mask: ' + bin(mask), # payload= ( battery, self.text.batteryLevel[battery] ) #) if( code != 0xff and code not in self.PS3Remote.button ): raise PS3ParseError( 'Key code', 'various', hex(code) ) btnPressed = [] if( code != 0xff ): # single button pressed btnPressed.append( self.PS3Remote.button[code] ) else: # multiple buttons pressed if( mask != 0x00 ): for bit in range( 24 ): if( mask & 1<<bit ): if( bit not in self.PS3Remote.maskbit ): PS3ParseError( 'Mask', 'various', bin(mask) ) btnPressed.append( self.PS3Remote.maskbit[bit] ) if btnPressed == []: PS3ParseError( 'Mask', 'various','Empty Mask' ) if btnPressed != []: evtName = 'Button.' + '+'.join(btnPressed) if self.enduringEvents: self.TriggerEnduringEvent(evtName) else: self.TriggerEvent(evtName) elif self.enduringEvents: #no buttons pressed anymore self.EndLastEvent() elif self.ps3Release: #trigger event so that releasing all buttons #can get noticed even w/o enduring events self.TriggerEvent( 'Button.None' ) self.batteryLevel= battery except PS3ParseError as catchedError: eg.PrintError( 'PS3-HID Plugin: ' + catchedError + ' Data: 0x' + binascii.hexlify(data).lower() ) def StopCallback(self): self.TriggerEvent("Stopped") self.thread = None def GetMyDevicePath(self): path = GetDevicePath( self.devicePath, self.vendorID, self.productID, self.versionNumber, self.useDeviceIndex, self.deviceIndex, self.noOtherPort) return path; def SetupHidThread(self, newDevicePath): #create thread self.thread = HIDThread( self.vendorString + " " + self.productString, newDevicePath ) self.thread.start() self.thread.SetStopCallback(self.StopCallback) self.thread.SetRawCallback(self.RawCallback) def ReconnectDevice(self, event): """method to reconnect a disconnect device""" if self.thread == None: #updating device list #check if the right device was connected #getting devicePath newDevicePath = self.GetMyDevicePath() if not newDevicePath: #wrong device return self.SetupHidThread(newDevicePath) def GetLabel(self, eventName, enduringEvents, rawDataEvents, ps3DataEvents, ps3Release, ps3Zone, shortKeyTime, longKeyTime, sleepTime, hibernateTime, noOtherPort, devicePath, vendorID, vendorString, productID, productString, versionNumber, # For backwards-compatibility with 2.0.2 and 3.0.0 - if a new config option is added this can just be replaced dummy = None, useDeviceIndex = False, deviceIndex = 0 ): prefix = "PS3: " #one or both strings empty should not happen if not vendorString or not productString: return "PS3" #productString already contains manufacturer or vendor id only if productString.find(vendorString) != -1 or\ vendorString[0:len(self.text.vendorID)] == self.text.vendorID: return prefix + productString return prefix + vendorString + " " + productString def __start__(self, eventName, enduringEvents, rawDataEvents, ps3DataEvents, ps3Release, ps3Zone, shortKeyTime, longKeyTime, sleepTime, hibernateTime, noOtherPort, devicePath, vendorID, vendorString, productID, productString, versionNumber, # For backwards-compatibility with 2.0.2 and 3.0.0 - if a new config option is added this can just be replaced dummy = None, useDeviceIndex = False, deviceIndex = 0 ): #saving parameters so they can be used to reconnect a device self.eventName = eventName self.enduringEvents = enduringEvents self.noOtherPort = noOtherPort self.devicePath = devicePath self.vendorID = vendorID self.vendorString = vendorString self.productID = productID self.productString = productString self.versionNumber = versionNumber self.useDeviceIndex = useDeviceIndex self.deviceIndex = deviceIndex self.ps3Release = ps3Release self.oldValues = {} if eventName: self.info.eventPrefix = eventName else: self.info.eventPrefix = "PS3" #Bind plug in to RegisterDeviceNotification message eg.Bind("System.DeviceAttached", self.ReconnectDevice) newDevicePath = self.GetMyDevicePath() if not newDevicePath: #device not found self.PrintError(Text.errorFind) else: self.SetupHidThread(newDevicePath) def __stop__(self): if self.thread: self.thread.AbortThread() #unbind from RegisterDeviceNotification message eg.Unbind("System.DeviceAttached", self.ReconnectDevice) def Configure(self, eventName = "", enduringEvents = True, rawDataEvents = False, # no longer used ps3DataEvents = False, # no longer used ps3Release = False, ps3Zone = False, # no longer used shortKeyTime = 0.0, # no longer used longKeyTime = 0.0, # no longer used sleepTime = 5.0, hibernateTime = 60.0, noOtherPort = False, devicePath = None, vendorID = None, vendorString = None, productID = None, productString = None, versionNumber = None, # For backwards-compatibility with 2.0.2 and 3.0.0 - if a new config option is added this can just be replaced dummy = None, useDeviceIndex = False, deviceIndex = 0 ): deviceList = GetDeviceDescriptions() panel = eg.ConfigPanel(self, resizable=True) #building dialog hidList = wx.ListCtrl(panel, -1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_SINGLE_SEL) #create GUI hidList.InsertColumn(0, self.text.deviceName) hidList.InsertColumn(1, self.text.manufacturer) hidList.InsertColumn(2, self.text.connected) path = GetDevicePath( devicePath, vendorID, productID, versionNumber, noOtherPort, useDeviceIndex, deviceIndex, deviceList) #fill list devices = {} idx = 0 for item in deviceList: # eg.Print("VID=%X, PID=%X, name=%s" %(item.vendorId, item.productId, item.productString)) # filter device list - list only match VID:PID if( ( ( item.vendorId == 0x054C or item.vendorId == 0x609 ) and item.productId == 0x0306 ) or item.devicePath == path or item.productString == 'BD Remote Control' ): idx = hidList.InsertStringItem(sys.maxint, item.productString) hidList.SetStringItem(idx, 1, item.vendorString) hidList.SetStringItem(idx, 2, self.text.yes) if item.devicePath == path: hidList.Select(idx) devices[idx] = item #add not connected device to bottom of list if not path and devicePath: item = DeviceDescription( devicePath, vendorID, vendorString, productID, productString, versionNumber) idx = hidList.InsertStringItem(sys.maxint, item.productString) hidList.SetStringItem(idx, 1, item.vendorString) hidList.SetStringItem(idx, 2, self.text.no) hidList.Select(idx) devices[idx] = item #no device selected, disable ok and apply button panel.EnableButtons(hidList.GetFirstSelected() != -1) #layout for i in range(hidList.GetColumnCount()): hidList.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) size = hidList.GetColumnWidth(i) hidList.SetColumnWidth(i, wx.LIST_AUTOSIZE) hidList.SetColumnWidth(i, max(size, hidList.GetColumnWidth(i) + 5)) panel.sizer.Add(hidList, 1, flag = wx.EXPAND) #sizers optionsSizer = wx.GridBagSizer(0, 5) #eventname optionsSizer.Add( wx.StaticText(panel, -1, self.text.eventName), (0, 0), flag = wx.ALIGN_CENTER_VERTICAL) eventNameCtrl = wx.TextCtrl(panel, value = eventName) eventNameCtrl.SetMaxLength(32) optionsSizer.Add(eventNameCtrl, (0, 1), (1, 2), flag = wx.EXPAND) #checkbox for enduring event option enduringEventsCtrl = wx.CheckBox(panel, -1, self.text.enduringEvents) enduringEventsCtrl.SetValue(enduringEvents) optionsSizer.Add(enduringEventsCtrl, (1, 0), (1, 3)) #text optionsSizer.Add( wx.StaticText(panel, -1, self.text.multipleDeviceOptions), (3, 0), (1, 3), flag = wx.ALIGN_CENTER_VERTICAL) #checkbox for use first device useDeviceIndexCtrl = wx.CheckBox(panel, -1, self.text.useDeviceIndex) useDeviceIndexCtrl.SetValue(useDeviceIndex) optionsSizer.Add(useDeviceIndexCtrl, (4, 0), (1, 2), flag = wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) #device index spin control deviceIndexCtrl = eg.SpinIntCtrl(panel, -1, deviceIndex, 0, 99, size=(100,-1)) optionsSizer.Add(deviceIndexCtrl, (4, 2), (1, 1)) #checkbox for no other port option noOtherPortCtrl = wx.CheckBox(panel, -1, self.text.noOtherPort) noOtherPortCtrl.SetValue(noOtherPort) optionsSizer.Add(noOtherPortCtrl, (5, 0), (1, 3)) panel.sizer.Add(optionsSizer, 0, wx.TOP, 10) def OnHidListSelect(event): panel.EnableButtons(hidList.GetFirstSelected() != -1) event.Skip() def OnUseDeviceIndexCtrlChange(event): noOtherPortCtrl.Enable(not useDeviceIndexCtrl.GetValue()) deviceIndexCtrl.Enable(useDeviceIndexCtrl.GetValue()) event.Skip() def OnNoOtherPortChange(event): useDeviceIndexCtrl.Enable(not noOtherPortCtrl.GetValue()) deviceIndexCtrl.Enable(not noOtherPortCtrl.GetValue()) event.Skip() OnUseDeviceIndexCtrlChange(wx.CommandEvent()) OnNoOtherPortChange(wx.CommandEvent()) useDeviceIndexCtrl.Bind(wx.EVT_CHECKBOX, OnUseDeviceIndexCtrlChange) noOtherPortCtrl.Bind(wx.EVT_CHECKBOX, OnNoOtherPortChange) hidList.Bind(wx.EVT_LIST_ITEM_SELECTED, OnHidListSelect) hidList.Bind(wx.EVT_LIST_ITEM_DESELECTED, OnHidListSelect) ###################################################################### panel.sizer.Add((15,15)) #sizers ps3GroupSizer = wx.StaticBoxSizer( wx.StaticBox(panel, -1, self.text.ps3Settings), wx.VERTICAL ) ps3Sizer = wx.GridBagSizer(0, 5) #checkbox for ps3 release event ps3ReleaseCtrl = wx.CheckBox(panel, -1, self.text.ps3Release) ps3ReleaseCtrl.SetValue(ps3Release) ps3Sizer.Add(ps3ReleaseCtrl, (0, 0), (1, 3)) #sleep time ps3Sizer.Add( wx.StaticText(panel, -1, self.text.sleepTime), (2, 0), flag = wx.ALIGN_CENTER_VERTICAL) sleepTimeCtrl = eg.SpinNumCtrl( panel, -1, sleepTime, size=(200,-1), integerWidth=7, increment=1.00 ) ps3Sizer.Add(sleepTimeCtrl, (2, 1), flag = wx.EXPAND) ps3Sizer.Add( wx.StaticText(panel, -1, self.text.seconds), (2, 2), (1, 2), flag = wx.ALIGN_CENTER_VERTICAL) #hibernate time ps3Sizer.Add( wx.StaticText(panel, -1, self.text.hibernateTime), (3, 0), flag = wx.ALIGN_CENTER_VERTICAL) hibernateTimeCtrl = eg.SpinNumCtrl( panel, -1, hibernateTime, size=(200,-1), integerWidth=7, increment=1.00 ) ps3Sizer.Add(hibernateTimeCtrl, (3, 1), flag = wx.EXPAND) ps3Sizer.Add( wx.StaticText(panel, -1, self.text.seconds), (3, 2), (1, 2), flag = wx.ALIGN_CENTER_VERTICAL) ps3GroupSizer.Add(ps3Sizer, 0, wx.ALL, 10) panel.sizer.Add(ps3GroupSizer, 0, wx.EXPAND) def OnEnduringEventsChange(event): ps3ReleaseCtrl.Enable( not enduringEventsCtrl.GetValue() ) event.Skip() OnEnduringEventsChange(wx.CommandEvent()) enduringEventsCtrl.Bind(wx.EVT_CHECKBOX, OnEnduringEventsChange) ###################################################################### while panel.Affirmed(): device = devices[hidList.GetFirstSelected()] panel.SetResult( eventNameCtrl.GetValue(), enduringEventsCtrl.GetValue(), False, True, ps3ReleaseCtrl.GetValue(), False, 0.0, 0.0, sleepTimeCtrl.GetValue(), hibernateTimeCtrl.GetValue(), noOtherPortCtrl.GetValue(), device.devicePath, device.vendorId, device.vendorString, device.productId, device.productString, device.versionNumber, useDeviceIndexCtrl.GetValue(), )
class FS20PCE(eg.PluginClass): def __init__(self): self.version = None self.thread = None self.PendingEvents = {} self.mappings = None def RawCallback(self, data): if not data or len(data) != 13 or ord(data[0]) != 2 or ord( data[1]) != 11: self.PrintError("invalid data") return self.version = ord(data[12]) houseCode = binascii.hexlify(data[2:6]) deviceCode = binascii.hexlify(data[6:8]) command = ord(data[8]) names = self.GetGroupNames(houseCode, deviceCode) #cancel pending events for deviceName in names: if deviceName in self.PendingEvents: #cancel pending events for this device try: timerEntry = self.PendingEvents[deviceName] startTime, func, args, kwargs = timerEntry eg.scheduler.CancelTask(timerEntry) self.TriggerEvent(deviceName + ".Cancel", payload=args[1]) del self.PendingEvents[deviceName] except KeyError: #may happen due to multithreaded access to self.PendingEvents dict pass except ValueError: #may happen due to multithreaded access to eg.scheduler's internal list pass validTime = ord(data[9]) > 15 if validTime: timeStr = binascii.hexlify(data[9:12]) timeStr = timeStr[1:] #cut the one eventTime = float(timeStr) * 0.25 else: eventTime = 0 if command in DirectCommands: commandStr0 = DirectCommands[command] commandStr1 = None payload0 = (eventTime) elif command in DelayedCommands: if (validTime and eventTime): commandStr0 = None commandStr1 = DelayedCommands[command] payload0 = (eventTime, commandStr1) else: commandStr0 = DelayedCommands[command] commandStr1 = None payload0 = None elif command in DoubleCommands: commandStr0, commandStr1 = DoubleCommands[command] payload0 = (eventTime, commandStr1) else: commandStr0 = binascii.hexlify(data[8]).upper() commandStr1 = None payload0 = None if (commandStr0): self.TriggerEvent(deviceName + "." + commandStr0, payload=payload0) else: self.TriggerEvent(deviceName + ".Timer", payload=payload0) if (commandStr1): if (eventTime > 0): timerEntry = eg.scheduler.AddShortTask( eventTime, self.SchedulerCallback, deviceName, commandStr1) self.PendingEvents[deviceName] = timerEntry else: self.TriggerEvent(deviceName + "." + commandStr1) def SchedulerCallback(self, deviceName, commandStr): if deviceName in self.PendingEvents: #cancel pending events for this device try: timerEntry = self.PendingEvents[deviceName] startTime, func, args, kwargs = timerEntry if (args[1] == commandStr): #maybe an old entry if commandStr does not match self.TriggerEvent(deviceName + "." + commandStr) del self.PendingEvents[deviceName] except KeyError: #may happen due to multithreaded access to self.PendingEvents dict pass def GetGroupNames(self, houseCode, deviceCode): names = [houseCode + "." + deviceCode] if self.mappings: for houseCodePattern, deviceCodePattern, deviceName in self.mappings: if (deviceName in names): continue if CheckPattern(deviceCodePattern, deviceCode) and CheckPattern( houseCodePattern, houseCode): names.append(deviceName) return names def PrintVersion(self): #create the following python command to show version number #eg.plugins.FS20PCE.plugin.PrintVersion() if self.version == None: print "Need to receive data first. Please press a button and try again." else: versionMajor = self.version / 16 versionMinor = self.version % 16 print "Firmware version %d.%d" % (versionMajor, versionMinor) def StopCallback(self): self.TriggerEvent("Stopped") self.thread = None def GetMyDevicePath(self): path = GetDevicePath(None, VENDOR_ID, PRODUCT_ID, None, 0, True, 0) return path def SetupHidThread(self, newDevicePath): #create thread self.thread = HIDThread(self.name, newDevicePath, self.name) self.thread.start() self.thread.SetStopCallback(self.StopCallback) self.thread.SetRawCallback(self.RawCallback) def ReconnectDevice(self, event): """method to reconnect a disconnect device""" if self.thread == None: if not IsDeviceName(event.payload, VENDOR_ID, PRODUCT_ID): return #check if the right device was connected #getting devicePath newDevicePath = self.GetMyDevicePath() if not newDevicePath: #wrong device return self.SetupHidThread(newDevicePath) def __start__(self, mappings=None): self.mappings = mappings #Bind plug in to RegisterDeviceNotification message eg.Bind("System.DeviceAttached", self.ReconnectDevice) newDevicePath = self.GetMyDevicePath() if not newDevicePath: #device not found self.PrintError(Text.errorFind) else: self.SetupHidThread(newDevicePath) def __stop__(self): if self.thread: self.thread.AbortThread() #unbind from RegisterDeviceNotification message eg.Unbind("System.DeviceAttached", self.ReconnectDevice) def Configure( self, mappings=None, ): #gui callbacks and helper methods def ValidChars(input): for char in input: if char != '1' and char != '2' and char != '3' and char != '4' and char != '?': return False return True def ContainsItem(houseCode, deviceAddress, groupName): for i in range(0, mappingsList.GetItemCount()): if houseCode != mappingsList.GetItem(i, 0).GetText(): continue if deviceAddress != mappingsList.GetItem(i, 1).GetText(): continue if groupName != mappingsList.GetItem(i, 2).GetText(): continue return True return False def OnItemSelected(event): idx = mappingsList.GetFirstSelected() houseCodeTextCtrl.SetValue(mappingsList.GetItem(idx, 0).GetText()) deviceAddressTextCtrl.SetValue( mappingsList.GetItem(idx, 1).GetText()) groupNameCtrl.SetValue(mappingsList.GetItem(idx, 2).GetText()) def EnableButtons(event): idx = mappingsList.GetFirstSelected() houseCode = houseCodeTextCtrl.GetValue() deviceAddress = deviceAddressTextCtrl.GetValue() groupName = groupNameCtrl.GetValue() valid = houseCodeTextCtrl.IsValid( ) and deviceAddressTextCtrl.IsValid() and len(groupName) itemSelected = idx != -1 addButton.Enable( valid and not ContainsItem(houseCode, deviceAddress, groupName)) updateButton.Enable(valid and itemSelected and \ (houseCode != mappingsList.GetItem(idx, 0).GetText() \ or deviceAddress != mappingsList.GetItem(idx, 1).GetText() \ or groupName != mappingsList.GetItem(idx, 2).GetText()) \ and not ContainsItem(houseCode, deviceAddress, groupName)) deleteButton.Enable(itemSelected) event.Skip() def OnAddButton(event): idx = mappingsList.InsertStringItem(sys.maxint, houseCodeTextCtrl.GetValue()) mappingsList.SetStringItem(idx, 1, deviceAddressTextCtrl.GetValue()) mappingsList.SetStringItem(idx, 2, groupNameCtrl.GetValue()) mappingsList.Select(idx) EnableButtons(event) event.Skip() def OnUpdateButton(event): idx = mappingsList.GetFirstSelected() mappingsList.SetStringItem(idx, 0, houseCodeTextCtrl.GetValue()) mappingsList.SetStringItem(idx, 1, deviceAddressTextCtrl.GetValue()) mappingsList.SetStringItem(idx, 2, groupNameCtrl.GetValue()) EnableButtons(event) event.Skip() def OnDeleteButton(event): idx = mappingsList.GetFirstSelected() mappingsList.DeleteItem(idx) EnableButtons(event) event.Skip() panel = eg.ConfigPanel(self, resizable=True) #building dialog mappingsList = wx.ListCtrl(panel, -1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_SINGLE_SEL) #create list mappingsList.InsertColumn(0, Text.houseCode) mappingsList.InsertColumn(1, Text.deviceAddress) mappingsList.InsertColumn(2, Text.groupName) #add items if mappings: for item in mappings: idx = mappingsList.InsertStringItem(sys.maxint, item[0]) mappingsList.SetStringItem(idx, 1, item[1]) mappingsList.SetStringItem(idx, 2, item[2]) #layout for i in range(mappingsList.GetColumnCount()): mappingsList.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) size = mappingsList.GetColumnWidth(i) mappingsList.SetColumnWidth(i, wx.LIST_AUTOSIZE) mappingsList.SetColumnWidth( i, max(size, mappingsList.GetColumnWidth(i) + 5)) houseCodeTextCtrl = TextCtrl( panel, mask="XXXXXXXX", choiceRequired=True, validFunc=ValidChars, defaultValue="????????", formatcodes="F", ) deviceAddressTextCtrl = TextCtrl( panel, mask="XXXX", choiceRequired=True, validFunc=ValidChars, defaultValue="????", formatcodes="F", ) groupNameCtrl = wx.TextCtrl(panel) editSizer = wx.GridSizer(3, 2) editSizer.Add(wx.StaticText(panel, -1, Text.houseCode + ":"), wx.ALIGN_CENTER_VERTICAL) editSizer.Add(houseCodeTextCtrl, 0) editSizer.Add(wx.StaticText(panel, -1, Text.deviceAddress + ":"), wx.ALIGN_CENTER_VERTICAL) editSizer.Add(deviceAddressTextCtrl, 0) editSizer.Add(wx.StaticText(panel, -1, Text.groupName + ":"), wx.ALIGN_CENTER_VERTICAL) editSizer.Add(groupNameCtrl, 0) addButton = wx.Button(panel, -1, Text.add) updateButton = wx.Button(panel, -1, Text.update) deleteButton = wx.Button(panel, -1, Text.delete) buttonsSizer = wx.GridSizer(1, 3) buttonsSizer.Add(addButton) buttonsSizer.Add(deleteButton) buttonsSizer.Add(updateButton) houseCodeTextCtrl.Bind(wx.EVT_TEXT, EnableButtons) deviceAddressTextCtrl.Bind(wx.EVT_TEXT, EnableButtons) groupNameCtrl.Bind(wx.EVT_TEXT, EnableButtons) addButton.Bind(wx.EVT_BUTTON, OnAddButton) updateButton.Bind(wx.EVT_BUTTON, OnUpdateButton) deleteButton.Bind(wx.EVT_BUTTON, OnDeleteButton) mappingsList.Bind(wx.EVT_LIST_ITEM_SELECTED, OnItemSelected) mappingsList.Bind(wx.EVT_LIST_ITEM_SELECTED, EnableButtons) mappingsList.Bind(wx.EVT_LIST_ITEM_DESELECTED, EnableButtons) EnableButtons(wx.CommandEvent()) panel.sizer.Add(wx.StaticText(panel, -1, Text.help0)) panel.sizer.Add(wx.StaticText(panel, -1, Text.help1)) panel.sizer.Add(mappingsList, 1, flag=wx.EXPAND) panel.sizer.Add(editSizer) panel.sizer.Add(buttonsSizer) while panel.Affirmed(): newMappings = [] for i in range(0, mappingsList.GetItemCount()): item = mappingsList.GetItem(i, 0).GetText(), \ mappingsList.GetItem(i, 1).GetText(), \ mappingsList.GetItem(i, 2).GetText() newMappings.append(item) panel.SetResult(newMappings)
class HID(eg.PluginClass): def __init__(self): self.thread = None def RawCallback(self, data): self.TriggerEvent(binascii.hexlify(data).upper()) def ButtonCallback(self, data): if len(data): #one or more buttons pressed btnPressed = [] for num in data: btnPressed.append(str(num)) evtName = "Button." + "+".join(btnPressed) if self.enduringEvents: self.TriggerEnduringEvent(evtName) else: self.TriggerEvent(evtName) elif self.enduringEvents: #no buttons pressed anymore self.EndLastEvent() else: #trigger event so that releasing all buttons #can get noticed even w/o enduring events self.TriggerEvent("Button.None") def ValueCallback(self, data): for key, value in data.items(): if key in self.oldValues and value == self.oldValues[key]: continue self.oldValues[key] = value self.TriggerEvent("Value." + str(key), payload=value) def StopCallback(self): self.TriggerEvent("Stopped") self.thread = None def GetMyDevicePath(self): path = GetDevicePath(self.devicePath, self.vendorID, self.productID, self.versionNumber, self.useDeviceIndex, self.deviceIndex, self.noOtherPort) return path def SetupHidThread(self, newDevicePath): #create thread self.thread = HIDThread(self.vendorString + " " + self.productString, newDevicePath) self.thread.start() self.thread.SetStopCallback(self.StopCallback) if self.rawDataEvents: self.thread.SetRawCallback(self.RawCallback) else: self.thread.SetButtonCallback(self.ButtonCallback) self.thread.SetValueCallback(self.ValueCallback) def ReconnectDevice(self, event): """method to reconnect a disconnect device""" if self.thread == None: if not IsDeviceName(event.payload, self.vendorID, self.productID): return #check if the right device was connected #getting devicePath newDevicePath = self.GetMyDevicePath() if not newDevicePath: #wrong device return self.SetupHidThread(newDevicePath) def GetLabel(self, eventName, enduringEvents, rawDataEvents, noOtherPort, devicePath, vendorID, vendorString, productID, productString, versionNumber, useDeviceIndex=False, deviceIndex=0): prefix = "HID: " #one or both strings empty should not happen if not vendorString or not productString: return "HID" #productString already contains manufacturer or vendor id only if productString.find(vendorString) != -1 or\ vendorString[0:len(Text.vendorID)] == Text.vendorID: return prefix + productString return prefix + vendorString + " " + productString def __start__(self, eventName, enduringEvents, rawDataEvents, noOtherPort, devicePath, vendorID, vendorString, productID, productString, versionNumber, useDeviceIndex=False, deviceIndex=0): #saving parameters so they can be used to reconnect a device self.eventName = eventName self.enduringEvents = enduringEvents self.rawDataEvents = rawDataEvents self.noOtherPort = noOtherPort self.devicePath = devicePath self.vendorID = vendorID self.vendorString = vendorString self.productID = productID self.productString = productString self.versionNumber = versionNumber self.useDeviceIndex = useDeviceIndex self.deviceIndex = deviceIndex self.oldValues = {} if eventName: self.info.eventPrefix = eventName else: self.info.eventPrefix = "HID" #Bind plug in to RegisterDeviceNotification message eg.Bind("System.DeviceAttached", self.ReconnectDevice) newDevicePath = self.GetMyDevicePath() if not newDevicePath: #device not found self.PrintError(Text.errorFind) else: self.SetupHidThread(newDevicePath) def __stop__(self): if self.thread: self.thread.AbortThread() #unbind from RegisterDeviceNotification message eg.Unbind("System.DeviceAttached", self.ReconnectDevice) def Configure(self, eventName="", enduringEvents=True, rawDataEvents=False, noOtherPort=False, devicePath=None, vendorID=None, vendorString=None, productID=None, productString=None, versionNumber=None, useDeviceIndex=False, deviceIndex=0): deviceList = GetDeviceDescriptions() panel = eg.ConfigPanel(self, resizable=True) #building dialog hidList = wx.ListCtrl(panel, -1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_REPORT | wx.LC_SINGLE_SEL) #create GUI hidList.InsertColumn(0, Text.deviceName) hidList.InsertColumn(1, Text.manufacturer) hidList.InsertColumn(2, Text.connected) path = GetDevicePath(devicePath, vendorID, productID, versionNumber, noOtherPort, useDeviceIndex, deviceIndex, deviceList) #fill list devices = {} idx = 0 for item in deviceList: idx = hidList.InsertStringItem(sys.maxint, item.productString) hidList.SetStringItem(idx, 1, item.vendorString) hidList.SetStringItem(idx, 2, Text.yes) if item.devicePath == path: hidList.Select(idx) devices[idx] = item #add not connected device to bottom of list if not path and devicePath: item = DeviceDescription(devicePath, vendorID, vendorString, productID, productString, versionNumber) idx = hidList.InsertStringItem(sys.maxint, item.productString) hidList.SetStringItem(idx, 1, item.vendorString) hidList.SetStringItem(idx, 2, Text.no) hidList.Select(idx) devices[idx] = item #no device selected, disable ok and apply button panel.EnableButtons(hidList.GetFirstSelected() != -1) #layout for i in range(hidList.GetColumnCount()): hidList.SetColumnWidth(i, wx.LIST_AUTOSIZE_USEHEADER) size = hidList.GetColumnWidth(i) hidList.SetColumnWidth(i, wx.LIST_AUTOSIZE) hidList.SetColumnWidth(i, max(size, hidList.GetColumnWidth(i) + 5)) panel.sizer.Add(hidList, 1, flag=wx.EXPAND) #sizers optionsSizer = wx.GridBagSizer(0, 5) #eventname optionsSizer.Add(wx.StaticText(panel, -1, Text.eventName), (0, 0), flag=wx.ALIGN_CENTER_VERTICAL) eventNameCtrl = wx.TextCtrl(panel, value=eventName) eventNameCtrl.SetMaxLength(32) optionsSizer.Add(eventNameCtrl, (0, 1), (1, 2), flag=wx.EXPAND) #checkbox for enduring event option enduringEventsCtrl = wx.CheckBox(panel, -1, Text.enduringEvents) enduringEventsCtrl.SetValue(enduringEvents) optionsSizer.Add(enduringEventsCtrl, (1, 0), (1, 3)) #checkbox for raw data events rawDataEventsCtrl = wx.CheckBox(panel, -1, Text.rawDataEvents) rawDataEventsCtrl.SetValue(rawDataEvents) optionsSizer.Add(rawDataEventsCtrl, (2, 0), (1, 3)) #text optionsSizer.Add(wx.StaticText(panel, -1, Text.multipleDeviceOptions), (3, 0), (1, 3), flag=wx.ALIGN_CENTER_VERTICAL) #checkbox for use first device useDeviceIndexCtrl = wx.CheckBox(panel, -1, Text.useDeviceIndex) useDeviceIndexCtrl.SetValue(useDeviceIndex) optionsSizer.Add(useDeviceIndexCtrl, (4, 0), (1, 2), flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) #device index spin control deviceIndexCtrl = eg.SpinIntCtrl(panel, -1, deviceIndex, 0, 99, size=(100, -1)) optionsSizer.Add(deviceIndexCtrl, (4, 2), (1, 1)) #checkbox for no other port option noOtherPortCtrl = wx.CheckBox(panel, -1, Text.noOtherPort) noOtherPortCtrl.SetValue(noOtherPort) optionsSizer.Add(noOtherPortCtrl, (5, 0), (1, 3)) panel.sizer.Add(optionsSizer, 0, wx.TOP, 10) def OnHidListSelect(event): panel.EnableButtons(hidList.GetFirstSelected() != -1) event.Skip() def OnRawDataEventsChange(event): enduringEventsCtrl.Enable(not rawDataEventsCtrl.GetValue()) event.Skip() def OnEnduringEventsChange(event): rawDataEventsCtrl.Enable(not enduringEventsCtrl.GetValue()) event.Skip() def OnUseDeviceIndexCtrlChange(event): noOtherPortCtrl.Enable(not useDeviceIndexCtrl.GetValue()) deviceIndexCtrl.Enable(useDeviceIndexCtrl.GetValue()) event.Skip() def OnNoOtherPortChange(event): useDeviceIndexCtrl.Enable(not noOtherPortCtrl.GetValue()) deviceIndexCtrl.Enable(not noOtherPortCtrl.GetValue()) event.Skip() OnRawDataEventsChange(wx.CommandEvent()) OnEnduringEventsChange(wx.CommandEvent()) OnUseDeviceIndexCtrlChange(wx.CommandEvent()) OnNoOtherPortChange(wx.CommandEvent()) rawDataEventsCtrl.Bind(wx.EVT_CHECKBOX, OnRawDataEventsChange) enduringEventsCtrl.Bind(wx.EVT_CHECKBOX, OnEnduringEventsChange) useDeviceIndexCtrl.Bind(wx.EVT_CHECKBOX, OnUseDeviceIndexCtrlChange) noOtherPortCtrl.Bind(wx.EVT_CHECKBOX, OnNoOtherPortChange) hidList.Bind(wx.EVT_LIST_ITEM_SELECTED, OnHidListSelect) hidList.Bind(wx.EVT_LIST_ITEM_DESELECTED, OnHidListSelect) while panel.Affirmed(): device = devices[hidList.GetFirstSelected()] panel.SetResult( eventNameCtrl.GetValue(), enduringEventsCtrl.GetValue(), rawDataEventsCtrl.GetValue(), noOtherPortCtrl.GetValue(), device.devicePath, device.vendorId, device.vendorString, device.productId, device.productString, device.versionNumber, useDeviceIndexCtrl.GetValue(), deviceIndexCtrl.GetValue(), )
class USB_RFID(eg.PluginClass): text = Text def __init__(self): self.version = None self.thread = None self.AddNewAction("GreenLED", 0xf2, "Green LED", "Turn on green LED", "Turn on green LED for {0}0 ms") self.AddNewAction("RedLED", 0xf1, "Red LED", "Turn on red LED", "Turn on red LED for {0}0 ms") self.AddNewAction("Buzzer", 0xf3, "Buzzer", "Turn on buzzer", "Turn on buzzer for {0}0 ms") def AddNewAction(self, internalName, classFuncCode, externalName, classDescription, classLabelFormat): class MyText: labelFormat = classLabelFormat class tmpAction(ActionBase): text = MyText name = externalName description = classDescription funcCode = classFuncCode tmpAction.__name__ = internalName self.AddAction(tmpAction) def RawCallback(self, data): if eg.debugLevel: print "USB_RFID RawCallBack", binascii.hexlify(data) if len(data) != 9 or data[0:3] != "\x02\x07\xA0": self.PrintError( "data must have a length of 9 and start with 02 07 A0") errorId = ord(data[3:4]) if errorId == 0: pass #everything is fine elif errorId == 1: #Firmware version was requested self.version = ord(data[4:5]) elif errorId == 2: #Firmware version was requested self.version = ord(data[4:5]) elif errorId == 3: self.PrintError("invalid command length") elif errorId == 4 or errorId == 5: eventstring = binascii.hexlify( data[4:5]).upper() + "." + binascii.hexlify(data[5:]).upper() knownCode = False for eventHandler in eg.eventTable.get( self.info.eventPrefix + "." + eventstring, []): knownCode = True break self.TriggerEvent(eventstring) if not knownCode: self.TriggerEvent("Unknown") else: self.PrintError("Unknown Error") def PrintVersion(self): #create the following python command to show version number #eg.plugins.USB-RFID.plugin.PrintVersion() versionMajor = self.version / 16 versionMinor = self.version % 16 print "Firmware version %d.%d" % (versionMajor, versionMinor) def StopCallback(self): self.TriggerEvent("Stopped") self.thread = None def GetMyDevicePath(self): path = GetDevicePath(None, VENDOR_ID, PRODUCT_ID, None, 0, True, 0) return path def SetupHidThread(self, newDevicePath): #create thread self.thread = HIDThread(self.name, newDevicePath, self.name) self.thread.SetStopCallback(self.StopCallback) self.thread.SetRawCallback(self.RawCallback) self.thread.start() self.thread.WaitForInit() self.RequestVersion() def RequestVersion(self): self.thread.Write('\x01\x01\xf0\x00\x00', 1000) def ReconnectDevice(self, event): """method to reconnect a disconnect device""" if self.thread == None: if not IsDeviceName(event.payload, VENDOR_ID, PRODUCT_ID): return #check if the right device was connected #getting devicePath newDevicePath = self.GetMyDevicePath() if not newDevicePath: #wrong device return self.SetupHidThread(newDevicePath) def __start__(self): #Bind plug in to RegisterDeviceNotification message eg.Bind("System.DeviceAttached", self.ReconnectDevice) newDevicePath = self.GetMyDevicePath() if not newDevicePath: #device not found self.PrintError(Text.errorFind) else: self.SetupHidThread(newDevicePath) def __stop__(self): if self.thread: self.thread.AbortThread() #unbind from RegisterDeviceNotification message eg.Unbind("System.DeviceAttached", self.ReconnectDevice)