Source code for labgrid.util.agents.usb_hid_relay

"""
This module implements the communication protocol to switch the digital outputs
on a "dcttech" USB Relay.

Supported modules:

- USBRelay2 (and likely others)

Supported Functionality:

- Turn digital output on and off
"""
import usb.core
import usb.util

GET_REPORT = 0x1
SET_REPORT = 0x9
REPORT_TYPE_FEATURE = 3


[docs] class USBHIDRelay:
[docs] def __init__(self, **args): self._dev = usb.core.find(**args) if self._dev is None: raise ValueError("Device not found") if self._dev.is_kernel_driver_active(0): self._dev.detach_kernel_driver(0)
[docs] def set_output(self, number, status): assert 1 <= number <= 8 req = [0xFF if status else 0xFD, number] self._dev.ctrl_transfer( usb.util.CTRL_TYPE_CLASS | usb.util.CTRL_RECIPIENT_DEVICE | usb.util.ENDPOINT_OUT, SET_REPORT, (REPORT_TYPE_FEATURE << 8) | 0, # no report ID 0, req, # payload )
[docs] def get_output(self, number): assert 1 <= number <= 8 resp = self._dev.ctrl_transfer( usb.util.CTRL_TYPE_CLASS | usb.util.CTRL_RECIPIENT_DEVICE | usb.util.ENDPOINT_IN, GET_REPORT, (REPORT_TYPE_FEATURE << 8) | 0, # no report ID 0, 8, # size ) return bool(resp[7] & (1 << (number-1)))
[docs] def __del__(self): usb.util.release_interface(self._dev, 0)
[docs] def handle_set(busnum, devnum, number, status): relay = USBHIDRelay(bus=busnum, address=devnum) relay.set_output(number, status)
[docs] def handle_get(busnum, devnum, number): relay = USBHIDRelay(bus=busnum, address=devnum) return relay.get_output(number)
methods = { 'set': handle_set, 'get': handle_get, }