Skip to content

Instantly share code, notes, and snippets.

@pklaus
Last active August 29, 2015 14:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pklaus/bda63a3866f2a690b970 to your computer and use it in GitHub Desktop.
Save pklaus/bda63a3866f2a690b970 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""
Read from a DCF77 USB HID RTC using PyUSB/libusb.
You need root access to get this to work.
"""
import sys
from time import sleep
from datetime import datetime
try:
import usb.core
import usb.util
pyusb_missing = False
except ImportError:
pyusb_missing = True
idVendor = 0x2341
idProduct = 0x8036
requestType = 0xa1 # usb.util.CTRL_IN | usb.util.CTRL_TYPE_CLASS | usb.util.CTRL_RECIPIENT_INTERFACE
def main():
global idVendor, idProduct, requestType
import argparse
from inspect import cleandoc
import logging
parser = argparse.ArgumentParser(description=cleandoc(__doc__))
parser.add_argument('-v', '--verbose', action='store_true', help='Increase verbosity')
parser.add_argument('-d', '--debug', action='store_true', help='Enable debug mode')
args = parser.parse_args()
if pyusb_missing: parser.error("You need to install PyUSB first!")
loglevel = logging.WARNING
if args.verbose:
loglevel = logging.INFO
if args.debug:
loglevel = logging.DEBUG
logging.basicConfig(format='%(message)s', level=loglevel)
try:
logging.info("Looking for the USB/HID Adapter")
dev = usb.core.find(idVendor=idVendor, idProduct=idProduct)
if dev is None:
raise NameError('Device not found')
# Check that the connected device has the endpoint we are looking for
cfg = dev.get_active_configuration()
hid_interface = usb.util.find_descriptor(cfg, bInterfaceNumber=2)
ep = usb.util.find_descriptor( \
hid_interface, \
custom_match = lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN )
assert ep is not None
assert ep.bEndpointAddress == 0x84
#for iface in [2, 1, 0]:
#for iface in [0, 1, 2]:
for iface in [0, 2]:
if dev.is_kernel_driver_active(iface) is True:
logging.info('Detaching kernel driver for iface ' + str(iface))
dev.detach_kernel_driver(iface)
dev.set_configuration()
try:
# Let's start talking to the device
# Sometimes there's a timeout on the first read.
# So request data twice for the first time.
#dev.ctrl_transfer(requestType, 1, 0x0101, 2, 10)
while True:
dev.ctrl_transfer(requestType, 1, 0x0101, 2, 10)
answer = dev.read(ep.bEndpointAddress, \
ep.wMaxPacketSize, timeout=100)
if len(answer) != 10: continue
year = 2000 + answer[1]
month = answer[2]
day = answer[3]
hour = answer[4]
minute = answer[5]
second = answer[6]
now = datetime( \
year=2000+answer[1], month=answer[2], \
day=answer[3], hour=answer[5], \
minute=answer[6], second=answer[7])
print(now.isoformat())
sleep(1.0)
except KeyboardInterrupt:
logging.info("You pressed CTRL-C, stopping...")
try:
dev.read(ep.bEndpointAddress, \
ep.wMaxPacketSize, timeout=1000)
except:
pass
#for iface in [2, 1, 0]:
#for iface in [0, 1, 2]:
for iface in [0, 2]:
if dev.is_kernel_driver_active(iface) is True:
logging.info('Reattaching kernel driver for iface ' + str(iface))
dev.attach_kernel_driver(iface)
except usb.core.USBError as ex:
logging.error("USB Error occured: " + str(ex))
except Exception as ex:
logging.error(ex)
if __name__ == "__main__":
main()
#!/usr/bin/env python
"""
Read from a DCF77 USB HID RTC using PyUSB/libusb.
You need root access to get this to work.
"""
import sys
import usb.core
import usb.util
from time import sleep
from datetime import datetime
dev = usb.core.find(idVendor=0x2341, idProduct=0x8036)
for iface in [0, 1, 2]:
if dev.is_kernel_driver_active(iface) is True:
dev.detach_kernel_driver(iface)
dev.set_configuration()
# Check that the connected device has the endpoint we are looking for
cfg = dev.get_active_configuration()
hid_interface = usb.util.find_descriptor(cfg, bInterfaceNumber=2)
ep = usb.util.find_descriptor( \
hid_interface, \
custom_match = lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN )
assert ep is not None
assert ep.bEndpointAddress == 0x84
requestType = usb.util.CTRL_IN | usb.util.CTRL_TYPE_CLASS | usb.util.CTRL_RECIPIENT_INTERFACE # = 0xa1
# Let's start talking to the device
# Sometimes there's a timeout on the first read.
# So request data twice for the first time.
dev.ctrl_transfer(requestType, 1, 0x0101, 2, 10)
while True:
dev.ctrl_transfer(requestType, 1, 0x0101, 2, 10)
answer = dev.read(ep.bEndpointAddress, ep.wMaxPacketSize, timeout=1000)
if len(answer) != 10: continue
year = 2000 + answer[1]
month = answer[2]
day = answer[3]
hour = answer[4]
minute = answer[5]
second = answer[6]
now = datetime(year=2000+answer[1], month=answer[2], day=answer[3], hour=answer[5], minute=answer[6], second=answer[7])
print(now.isoformat())
break
sleep(1.0)
for iface in [0, 1, 2]:
if dev.is_kernel_driver_active(iface) is True:
dev.attach_kernel_driver(iface)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment