10
10
11
11
- Turn digital output on and off
12
12
"""
13
+
13
14
import usb .core
14
15
import usb .util
15
16
@@ -23,46 +24,79 @@ def __init__(self, **args):
23
24
self ._dev = usb .core .find (** args )
24
25
if self ._dev is None :
25
26
raise ValueError ("Device not found" )
27
+
28
+ if self ._dev .idVendor == 0x16C0 :
29
+ self .set_output = self .set_output_dcttech
30
+ self .get_output = self .get_output_dcttech
31
+ elif self ._dev .idVendor == 0x5131 :
32
+ self .set_output = self .set_output_lcus
33
+ self .get_output = self .get_output_lcus
34
+ else :
35
+ raise ValueError (f"Unknown vendor/protocol for VID { self ._dev .idVendor :x} " )
36
+
26
37
if self ._dev .is_kernel_driver_active (0 ):
27
38
self ._dev .detach_kernel_driver (0 )
28
39
29
- def set_output (self , number , status ):
40
+ def set_output_dcttech (self , number , status ):
30
41
assert 1 <= number <= 8
31
42
req = [0xFF if status else 0xFD , number ]
32
43
self ._dev .ctrl_transfer (
33
44
usb .util .CTRL_TYPE_CLASS | usb .util .CTRL_RECIPIENT_DEVICE | usb .util .ENDPOINT_OUT ,
34
45
SET_REPORT ,
35
- (REPORT_TYPE_FEATURE << 8 ) | 0 , # no report ID
46
+ (REPORT_TYPE_FEATURE << 8 ) | 0 , # no report ID
36
47
0 ,
37
- req , # payload
48
+ req , # payload
38
49
)
39
50
40
- def get_output (self , number ):
51
+ def get_output_dcttech (self , number ):
41
52
assert 1 <= number <= 8
42
53
resp = self ._dev .ctrl_transfer (
43
54
usb .util .CTRL_TYPE_CLASS | usb .util .CTRL_RECIPIENT_DEVICE | usb .util .ENDPOINT_IN ,
44
55
GET_REPORT ,
45
- (REPORT_TYPE_FEATURE << 8 ) | 0 , # no report ID
56
+ (REPORT_TYPE_FEATURE << 8 ) | 0 , # no report ID
46
57
0 ,
47
- 8 , # size
58
+ 8 , # size
48
59
)
49
- return bool (resp [7 ] & (1 << (number - 1 )))
60
+ return bool (resp [7 ] & (1 << (number - 1 )))
61
+
62
+ def set_output_lcus (self , number , status ):
63
+ assert 1 <= number <= 8
64
+ ep_in = self ._dev [0 ][(0 , 0 )][0 ]
65
+ ep_out = self ._dev [0 ][(0 , 0 )][1 ]
66
+ req = [0xA0 , number , 0x01 if status else 0x00 , 0x00 ]
67
+ req [3 ] = sum (req ) & 0xFF
68
+ ep_out .write (req )
69
+ ep_in .read (64 )
70
+
71
+ def get_output_lcus (self , number ):
72
+ assert 1 <= number <= 8
73
+ # we have no information on how to read the current value
74
+ return False
50
75
51
76
def __del__ (self ):
52
77
usb .util .release_interface (self ._dev , 0 )
53
78
54
79
80
+ _relays = {}
81
+
82
+
83
+ def _get_relay (busnum , devnum ):
84
+ if (busnum , devnum ) not in _relays :
85
+ _relays [(busnum , devnum )] = USBHIDRelay (bus = busnum , address = devnum )
86
+ return _relays [(busnum , devnum )]
87
+
88
+
55
89
def handle_set (busnum , devnum , number , status ):
56
- relay = USBHIDRelay ( bus = busnum , address = devnum )
90
+ relay = _get_relay ( busnum , devnum )
57
91
relay .set_output (number , status )
58
92
59
93
60
94
def handle_get (busnum , devnum , number ):
61
- relay = USBHIDRelay ( bus = busnum , address = devnum )
95
+ relay = _get_relay ( busnum , devnum )
62
96
return relay .get_output (number )
63
97
64
98
65
99
methods = {
66
- ' set' : handle_set ,
67
- ' get' : handle_get ,
100
+ " set" : handle_set ,
101
+ " get" : handle_get ,
68
102
}
0 commit comments