Skip to content

Instantly share code, notes, and snippets.

@fpoussin
Last active July 5, 2017 08:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fpoussin/6c10f4a80e2792aed91bfb20c868dbca to your computer and use it in GitHub Desktop.
Save fpoussin/6c10f4a80e2792aed91bfb20c868dbca to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
import usb.core
import usb.util
import struct
CLINK_USB_PID = 0x1b1c
CLINK_USB_VIP = 0x1c0c
CLINK_GET_PRODUCT = (0x03, 0x9a) + (0,)*(64 - 2)
CLINK_GET_POWER = (0x03, 0xee) + (0,)*(64 - 2)
CLINK_GET_INPUT = (0x03, 0x88) + (0,)*(64 - 2)
def array_to_float(arr):
if len(arr) != 2:
raise ValueError("Length must be 2")
int16 = (arr[1] << 8) | arr[0]
exponent = int16 >> 11
fraction = int16 & 2047
if exponent > 15:
exponent = -(32 - exponent)
if fraction > 1023:
fraction = -(2048 - fraction)
if (fraction & 1) == 1:
fraction += 1
return float(fraction) * pow(2.0, float(exponent))
def request_value(name):
ep_write.write(name)
read_buf = ep_read.read(64)
return array_to_float(read_buf[2:4])
def request_string(name):
ep_write.write(name)
read_buf = ep_read.read(64)
return "".join([chr(n) for n in read_buf[2:]]).strip()
# find our device
dev = usb.core.find(idVendor=CLINK_USB_PID, idProduct=CLINK_USB_VIP)
if dev.is_kernel_driver_active(0):
print('Kernel driver was active, detaching')
dev.detach_kernel_driver(0)
# was it found?
if dev is None:
raise ValueError('Device not found')
# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep_read = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN)
ep_write = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT)
assert ep_read is not None
assert ep_write is not None
product = request_string(CLINK_GET_PRODUCT)
print('Device: {}'.format(product))
output_power = request_value(CLINK_GET_POWER)
input_voltage = request_value(CLINK_GET_INPUT)
print('Input: {}V'.format(input_voltage))
power_sq = output_power ** 2
# Only for RM850i
if 'RM850i' in product:
input_power = (0.0001282672 * power_sq + 1.015599 * output_power + 12.41156) if (input_voltage < 180.0) else (7.752753E-05 * power_sq + 1.030425 * output_power + 9.844185)
print('Input Power: {:.2f}W'.format(input_power))
print('Efficiency: {:.2f}%'.format(output_power*100/input_power))
print('Output Power: {:.2f}W'.format(output_power))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment