Last active
February 4, 2025 18:26
-
-
Save martinlroth/cf001af25d060fc2d193c725def26588 to your computer and use it in GitHub Desktop.
Simple relay control for the Denkovi USB Relay Module 4 Channels, for Home Automation - v2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
# Simple relay control for the Denkovi USB Relay Module 4 Channels, for Home Automation - v2 | |
# http://denkovi.com/usb-relay-board-four-channels-for-home-automation-v2 | |
# | |
# Better tools are offered on http://denkovi.com but they need an internet | |
# connection, and are not open source. | |
# | |
__author__ = "Martin Roth" | |
__copyright__ = "Copyright 2017 Google Inc." | |
__license__ = "GPL v2" | |
__version__ = "0.0.1" | |
__email__ = "gaumless@gmail.com" | |
__status__ = "Development" | |
import usb.core | |
import usb.util | |
import sys | |
# Check for pyusb 1.0.0 - Lots of incompatibilities with older versions. | |
# We're not exiting, because it *COULD* work. | |
if hasattr(usb, 'version_info'): | |
if usb.version_info[0] < 1: | |
print "You probably want a newer version of pyusb" | |
else: | |
print "You probably want a newer version of pyusb" | |
# Set some global variables | |
list_devices = False # True if just listing devices | |
serial = 0 # Serial number from command line | |
serial_num = 0 # Serial number read from device | |
NewGPIO = -1 # Relay configuration from command line | |
reattach = [0,0,0] # Interfaces detatched from the kernel | |
# Define the command structures that are being used | |
get_status_cmd = chr(0x80)+chr(0x00)+chr(0x00)+chr(0x00) + \ | |
chr(0x00)+chr(0x00)+chr(0x00)+chr(0x00) + \ | |
chr(0x00)+chr(0x00)+chr(0x00)+chr(0x00) + \ | |
chr(0x00)+chr(0x00)+chr(0x00)+chr(0x00) | |
cfg_cmd = chr(0x10)+chr(0x00)+chr(0x00)+chr(0x00) + \ | |
chr(0x00)+chr(0x00)+chr(0x00)+chr(0x00) + \ | |
chr(0x04)+chr(0xe1)+chr(0x00)+chr(0x00) + \ | |
chr(0x00)+chr(0x00)+chr(0x00)+chr(0x00) | |
# Check command line arguments | |
if (len(sys.argv) == 1) or (sys.argv[1] == "--help"): | |
print "Usage: %s <list|serial No> <Hex GPIOs Enabled>" % sys.argv[0] | |
print "Examples:" | |
print " relay.py list - Shows all attached relay boards" | |
print " relay.py 0001652501 - Shows current relay status" | |
print " relay.py 0001652501 0x0f - Enable all relays" | |
print " relay.py 0001652501 0 - Disable all relays" | |
print " relay.py 0001652501 8 - Enable just relay 4" | |
exit(0) | |
if sys.argv[1] == 'list': | |
list_devices = True | |
else: | |
serial = sys.argv[1] | |
if (list_devices == False) and (len(sys.argv) > 2): | |
NewGPIO = int(sys.argv[2], 16) | |
# Find all the MCP2200 devices | |
usbdevs = usb.core.find(find_all=True, idVendor=0x04d8, idProduct=0x00df) | |
# Loop through and print devices found or select requested device | |
for dev in usbdevs: | |
serial_num = usb.util.get_string(dev,dev.iSerialNumber) | |
if list_devices == True: | |
print "Serial Number: ", serial_num | |
elif serial_num == serial: | |
break | |
# Make sure we found specified device, or exit if we were just listing | |
if serial_num == 0: | |
print "No devices found" | |
exit(1) | |
elif list_devices == True: | |
exit(0) | |
elif serial_num != serial: | |
print "Error: Serial Number %s not found." % serial | |
exit(1) | |
# Get the configuration, and detach every interface from the kernel | |
# We get a 'usb.core.USBError: [Errno 16] Resource busy' error otherwise | |
# Save the interfaces we detached for re-attachment later | |
cfg = dev.get_active_configuration() | |
for i in range(cfg.bNumInterfaces): | |
if dev.is_kernel_driver_active(i): | |
reattach[i]=1 | |
dev.detach_kernel_driver(i) | |
# Because we know the device, just set the endpoints directly | |
epin = dev[0][(2,0)][0] | |
epout = dev[0][(2,0)][1] | |
# No idea why this would happen, but hey, checking is good. | |
if (epin is None) or (epout is None): | |
print "endpoint not found." | |
exit(1) | |
# Get the current status of the relays | |
dev.write(epout.bEndpointAddress, get_status_cmd) | |
status = dev.read(epin.bEndpointAddress,16,1000) | |
# Set the relays if requested | |
if NewGPIO != -1: | |
dev.write(epout.bEndpointAddress, cfg_cmd[:6] + chr(status[6]) + cfg_cmd[7:]) | |
dev.write(epout.bEndpointAddress, cfg_cmd[:6] + chr(NewGPIO) + cfg_cmd[7:]) | |
dev.write(epout.bEndpointAddress, get_status_cmd) | |
status = dev.read(epin.bEndpointAddress,16,1000) | |
# Display the current value of the GPIOs / Relays | |
print "0x%02x"%status[6] | |
# Clean up and release the device | |
usb.util.dispose_resources(dev) | |
for i in range(cfg.bNumInterfaces): | |
if reattach[i] == 1: | |
dev.attach_kernel_driver(i) | |
exit(0) |
Hey, I tested this on a linux system. Honestly, I never thought about
testing in windows. :) I probably should do that.
Did you try running it as admin? It might not be able to talk directly to
the hardware?
Let me know how it goes, and thanks for letting me know about the issue.
Martin
…On Sun, Mar 20, 2022 at 10:04 PM Rufus V. Smith ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Was this for a linux or mac system? I tried running it on a Windows 10
system and pyusb is unable to enumerate the USB devices.
Working on solving that. I may try it on a linux system too.
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/cf001af25d060fc2d193c725def26588#gistcomment-4104513>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABHQDJWGRB7J47Z4U2NKYRTVA7YNZANCNFSM5RGQYEIA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you authored the thread.Message ID:
***@***.***>
I've been muddling about with the python hid module and hidapi. After muddling around with cmake and building hidapi (I think it was my efforts) I was able to import hid module. So far I have been able to open and read the status, now I am about to write the relays. I'll summarize and send you test code later, though I don't know if I have the energy to go back and figure out the hidapi install I got through, though if I install on another windows machine, I'll pay more attention.
Edit: Stupid me, I didn't have my proper libusb.dll installed. I was able to just download the binary from sourceforge thanks to an Adafruit learn guide...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Was this for a linux or mac system? I tried running it on a Windows 10 system and pyusb is unable to enumerate the USB devices.
Working on solving that. I may try it on a linux system too.
(Edit: problem solved. See later comment.)