Last active
August 29, 2015 14:15
-
-
Save pklaus/bda63a3866f2a690b970 to your computer and use it in GitHub Desktop.
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/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() | |
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/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