# Delcom Product USB HID G2 Python 3 Example # Rev 0.2 Apr 27, 2021 - Converted to Python3 # Uses the hidapi # Tested on Python 3, Win10 # This code defines the DelcomUSBDevice class and if run as main will run the examplecode() # When using with your code import this file and examplecode() will not run. #-----------------------------------------------------------------------------------# # For a quick example copy the code below in to a python file and run it # Make sure the DelcomPython.py is in the same directory """ from DelcomPython3 import DelcomUSBDevice import sys myDevice = DelcomUSBDevice() # Start the class and find the device if myDevice.open() == 0 : # Test for find print ("Failed to find/open the device. Program terminated.") sys.exit(0) myDevice.open() # Open the device print ("Port0= ", myDevice.ReadPort0()) # Read port 0 value myDevice.LEDControl(myDevice.LED3, myDevice.LEDON) # Turn LED3 ON myDevice.close() # Close the device """ #-----------------------------------------------------------------------------------# #-----------------------------------------------------------------------------------# # USB Linux Access Rights # By default all USB devices only have root rights. So you may need # to either run the python script with sudo rights (sudo python name.py) # or change the rights on the usb device. You can use chmod to change the # rights temporally or you can use the the following to make it permanment. # Edit this file-> $ sudo nano /etc/udev/rules.d/50-myusb.rules # Add this line -> SUBSYSTEMS=="usb", ATTRS{idVendor}=="0fC5", ATTRS{idProducts}=="b080", GROUP="users", MODE="0666" # Save the file and reboot for changes to be effective. The above will make all USB devices with a vendor # number of 0F5C and product number of B080 have all rights. #-----------------------------------------------------------------------------------# # uncomment for debugging #import os #os.environ['PYUSB_DEBUG'] = 'debug' # import sys import struct import time import hid # pip install hid #--------------------------------------------------------------------# #------------------- CLASS: DelcomUSBDevice -------------------------# #--------------------------------------------------------------------# class DelcomUSBDevice(object): """ Delcom Python Object """ def __init__(self): """Initiaze the object """ self.VENDOR_ID = 0x0FC5 #: Delcom Product ID self.PRODUCT_ID = 0xB080 #: Delcom Product ID self.INTERFACE_ID = 0 #: The interface we use self.TIMEOUT = 100 #: 100ms timeout self.LED1,self.LED2,self.LED3,self.LED4,self.LEDALL=1,2,4,8,0xF self.LEDOFF,self.LEDON,self.LEDBLINK = 0,1,2 def display(self): """Display all delcom device attached""" cnt = 0 #print("Searching for Delcom devices...") for d in hid.enumerate(self.VENDOR_ID, self.PRODUCT_ID): for key in sorted(d.keys()): print(f"{key} : {d[key]}") print() cnt=cnt+1 if cnt==0: print(" No devices found.") def open(self): """ Trys to find and open the Delcom device by VID & PID """ #print ('DelcomUSBDevice.Open') try: self.h = hid.device() self.h.open(self.VENDOR_ID, self.PRODUCT_ID) # Vendor Id, Product Id return(1) except OSError as e: print(f"Error: Failed to find/open device: {e}") return(0) def close(self): try: self.h.close() except : print ("ERROR - Failed to close device.") # Delcom Commands documentation: # https://www.delcomproducts.com/downloads/USBIOHID.pdf # https://www.delcomproducts.com/downloads/USBIOG3MIG.pdf def ReadPacket(self, RxCmd, RxLen=16): """ Reads command packet from the Delcom device. RxCom: The read command - For description of commands see the Delcom HID DataSheet RxLen: The read command lenght. Usally 8 or 16 (default is 16) Returns array of data """ return(self.h.get_feature_report(RxCmd, RxLen)) def SendPacket(self, MajorCmd, MinorCmd, DataLSB, DataMSB, DataHID, DataExt): """ Writes the command packet to the Delcom device. For a description of commands see the Delcom HID DataSheet MajorCmd(1Byte): 101 for 8byte commands, 102 for 16byte commands MinorCmd(1Byte): Minor Command DataLSB(1Byte): DataLSB(1Byte): DataHID(4Byte): DataExt(8Bytes): Returns length written on success, else zero on error """ #print(" SendPacket(",MajorCmd, MinorCmd, DataLSB, DataMSB, DataHID,")") sentbytes = 0 if MajorCmd == 101 : data = struct.pack('BBBBL', MajorCmd, MinorCmd, DataLSB, DataMSB, DataHID) sentbytes = self.h.send_feature_report(data) if MajorCmd == 102 : data = struct.pack('BBBBLQ', MajorCmd, MinorCmd, DataLSB, DataMSB, DataHID, DataExt) sentbytes = self.h.send_feature_report(data) return(sentbytes) def LEDControl(self, LED, MODE): """ Controls the LED on port 1 LED = LED number (bitwise): 0=none, 0x1=LED1, 0x2=LED2,0x4=LED3, 0x8=LED4, 0xF=ALL LEDS MODE = LED CONTROL: 0=Off, 1=ON, 2=Blink Returns length written on success, else zero on error Examples: myDevice.LEDControl(myDevice.LEDALL, myDevice.LEDOFF) myDevice.LEDControl(myDevice.LED1, myDevice.LEDON) myDevice.LEDControl(myDevice.LED1, myDevice.LEDBLINK) """ if(MODE==self.LEDON): # if MODE=ON MajorCmd, MinorCmd, DataLSB, DataMSB = 101, 20, LED, 0 # First turn LED flash mode off if( self.SendPacket(MajorCmd, MinorCmd, DataLSB,DataMSB,0,0) == 0): return(0) MajorCmd, MinorCmd, DataLSB, DataMSB = 101, 12, LED, 0 # Then turn LED On return( self.SendPacket(MajorCmd, MinorCmd, DataLSB,DataMSB,0,0) == 0) else : # if MODE OFF OR FLASH MajorCmd, MinorCmd, DataLSB, DataMSB = 101, 20, LED, 0 # First turn LED flash mode off if( self.SendPacket(MajorCmd, MinorCmd, DataLSB,DataMSB,0,0) == 0): return(0) MajorCmd, MinorCmd, DataLSB, DataMSB = 101, 12, 0, LED # Then turn LED Off if( self.SendPacket(MajorCmd, MinorCmd, DataLSB,DataMSB,0,0) == 0): return(0) if(MODE==self.LEDBLINK): #if MODE = BLINK MajorCmd, MinorCmd, DataLSB, DataMSB = 101, 20, 0, LED # LED flash mode on if( self.SendPacket(MajorCmd, MinorCmd, DataLSB,DataMSB,0,0) == 0): return(0) return(8) # success def LEDPower(self, LED, POWER): """ Controls the LED on port 1 LED = LED number (bitwise): 0=none, 0x1=LED1, 0x2=LED2,0x4=LED3, 0x8=LED4, 0xF=ALL LEDS POWER = LED POWER: 0-100 0=Off, 100=FULL POWER Returns length written on success, else zero on error Example: myDevice.LEDPower(myDevice.LED1,25) # sets LED1 to 25% power """ MajorCmd, MinorCmd, DataLSB, DataMSB = 101, 34, LED, POWER if LED == self.LED1: DataLSB=0 elif LED == self.LED2: DataLSB=1 elif LED == self.LED3: DataLSB=2 elif LED == self.LED4: DataLSB=3 return(self.SendPacket(MajorCmd, MinorCmd, DataLSB,DataMSB,0,0)) def DisplayInfo(self): """ Prints the firmware information """ info = self.ReadPacket(104) SerialNum = info[8] + (info[9]<<8) + (info[10]<<16) + (info[11]<<24) print ("Firmwar Version:", info[4], " Date:", info[5],"/",info[6],"/",info[7]+2000," FamilyCode:",info[0], " SerialNum:",SerialNum) def ReadPort0(self): # Reads port 0 value data = self.ReadPacket(100) return(data[0]) def ReadPort1(self): # Reads port 1 value data = self.ReadPacket(100) return(data[1]) #--------------------------------------------------------------------# #------------------------------------------------------------------------------------------# # example code - sample code on how to find, open, read, write and close the Delcom Device #------------------------------------------------------------------------------------------# def examplecode(): print("Starting Delcom Python sample code...") myDevice = DelcomUSBDevice() # Start the class and try and open the device #myDevice.display() # Display all Delcom devices attached to the computer if myDevice.open() == 0 : # Test for find print ("Failed to find the device. Program terminated.") sys.exit(0) else : print ("Delcom device found!") #print ("DisplayInfo") myDevice.DisplayInfo() # Display the device info #print ("Port0= ", myDevice.ReadPort0()) # Read port 0 value print ("Turn all LEDs off") myDevice.LEDControl(myDevice.LEDALL, myDevice.LEDOFF) print ("Turn LED1 on") myDevice.LEDControl(myDevice.LED1, myDevice.LEDON) time.sleep(1) print ("Turn LED1 off") myDevice.LEDControl(myDevice.LED1, myDevice.LEDOFF) print ("Turn LED2 on and blink it") myDevice.LEDControl(myDevice.LED2, myDevice.LEDBLINK) print ("Close device") myDevice.close() # You must close the device when your done, else you wont be able to open it again. #print ("All done................") #------------------------------------------------------------------------------------------# # Calls the examplecode() - Only calls this examplecode() if this is the main file. # If imported into your code this examplecode() won't run #------------------------------------------------------------------------------------------# if __name__ == '__main__': examplecode()