-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Python API to control up to 256 LED #51
Open
areid-van
wants to merge
5
commits into
arvydas:master
Choose a base branch
from
areid-van:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
def53fa
Added new mode to address 128 LED
areid-van 767ff11
Patched to work on Raspbian
areid-van afbd612
Added 12bit color mode.
areid-van 83eb287
Merge branch 'pro-12bit'
areid-van 195c67f
Added method to control new frame repeat feature
areid-van File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,6 +188,7 @@ class BlinkStick(object): | |
inverse = False | ||
error_reporting = True | ||
max_rgb_value = 255 | ||
mode = 0 | ||
|
||
def __init__(self, device=None, error_reporting=True): | ||
""" | ||
|
@@ -207,16 +208,17 @@ def __init__(self, device=None, error_reporting=True): | |
self.open_device(device) | ||
|
||
self.bs_serial = self.get_serial() | ||
self.mode = self.get_mode() | ||
|
||
def _usb_get_string(self, device, index): | ||
def _usb_get_string(self, device, length, index): | ||
try: | ||
return usb.util.get_string(device, index) | ||
return usb.util.get_string(device, length, index) | ||
except usb.USBError: | ||
# Could not communicate with BlinkStick device | ||
# attempt to find it again based on serial | ||
|
||
if self._refresh_device(): | ||
return usb.util.get_string(self.device, index) | ||
return usb.util.get_string(self.device, length, index) | ||
else: | ||
raise BlinkStickException("Could not communicate with BlinkStick {0} - it may have been removed".format(self.bs_serial)) | ||
|
||
|
@@ -269,7 +271,7 @@ def get_serial(self): | |
if sys.platform == "win32": | ||
return self.device.serial_number | ||
else: | ||
return self._usb_get_string(self.device, 3) | ||
return self._usb_get_string(self.device, 256, 3) | ||
|
||
def get_manufacturer(self): | ||
""" | ||
|
@@ -281,7 +283,7 @@ def get_manufacturer(self): | |
if sys.platform == "win32": | ||
return self.device.vendor_name | ||
else: | ||
return self._usb_get_string(self.device, 1) | ||
return self._usb_get_string(self.device, 256, 1) | ||
|
||
|
||
def get_description(self): | ||
|
@@ -294,7 +296,7 @@ def get_description(self): | |
if sys.platform == "win32": | ||
return self.device.product_name | ||
else: | ||
return self._usb_get_string(self.device, 2) | ||
return self._usb_get_string(self.device, 256, 2) | ||
|
||
def set_error_reporting(self, error_reporting): | ||
""" | ||
|
@@ -350,7 +352,7 @@ def _determine_rgb(self, red=0, green=0, blue=0, name=None, hex=None): | |
try: | ||
if name: | ||
# Special case for name="random" | ||
if name == "random": | ||
if name is "random": | ||
red = randint(0, 255) | ||
green = randint(0, 255) | ||
blue = randint(0, 255) | ||
|
@@ -417,8 +419,8 @@ def get_color(self, index=0, color_format='rgb'): | |
raise BlinkStickException("Could not return current color in format %s" % color_format) | ||
|
||
def _determine_report_id(self, led_count): | ||
report_id = 9 | ||
max_leds = 64 | ||
report_id = 10 | ||
max_leds = 128 | ||
|
||
if led_count <= 8 * 3: | ||
max_leds = 8 | ||
|
@@ -432,6 +434,9 @@ def _determine_report_id(self, led_count): | |
elif led_count <= 64 * 3: | ||
max_leds = 64 | ||
report_id = 9 | ||
elif led_count <= 128 * 3: | ||
max_leds = 128 | ||
report_id = 10 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add support for report 10 here |
||
|
||
return report_id, max_leds | ||
|
||
|
@@ -445,15 +450,23 @@ def set_led_data(self, channel, data): | |
@param data: The LED data frame in GRB format | ||
""" | ||
|
||
report_id, max_leds = self._determine_report_id(len(data)) | ||
|
||
report = [0, channel] | ||
|
||
for i in range(0, max_leds * 3): | ||
if len(data) > i: | ||
report.append(data[i]) | ||
else: | ||
report.append(0) | ||
if self.mode == 3: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pack the data so each 24 bit RGB tuple is two interleaved 12 bit RGB tuples for mode 3 |
||
report_id, max_leds = self._determine_report_id(len(data)/2) | ||
offset = max_leds * 3 | ||
for i in range(0, offset): | ||
d = data[i]>>4 | ||
if len(data) > offset + i: | ||
d += data[offset+i]&240 | ||
report.append(d) | ||
else: | ||
report_id, max_leds = self._determine_report_id(len(data)) | ||
for i in range(0, max_leds * 3): | ||
if len(data) > i: | ||
report.append(data[i]) | ||
else: | ||
report.append(0) | ||
|
||
self._usb_ctrl_transfer(0x20, 0x9, report_id, 0, bytes(bytearray(report))) | ||
|
||
|
@@ -473,6 +486,16 @@ def get_led_data(self, count): | |
|
||
return device_bytes[2: 2 + count * 3] | ||
|
||
def set_repeat(self, repeat): | ||
""" | ||
Set the number of repeats on the frame | ||
|
||
@type repeat: int | ||
@param mode: number of times to repeat the frame | ||
""" | ||
control_string = bytes(bytearray([20, repeat])) | ||
self._usb_ctrl_transfer(0x20, 0x9, 0x14, 0, control_string) | ||
|
||
def set_mode(self, mode): | ||
""" | ||
Set device mode for BlinkStick Pro. Device currently supports the following modes: | ||
|
@@ -491,6 +514,7 @@ def set_mode(self, mode): | |
control_string = bytes(bytearray([4, mode])) | ||
|
||
self._usb_ctrl_transfer(0x20, 0x9, 0x0004, 0, control_string) | ||
self.mode = mode | ||
|
||
def get_mode(self): | ||
""" | ||
|
@@ -1527,7 +1551,7 @@ def find_by_serial(serial=None): | |
else: | ||
for d in _find_blicksticks(): | ||
try: | ||
if usb.util.get_string(d, 3) == serial: | ||
if usb.util.get_string(d, 256, 3) == serial: | ||
devices = [d] | ||
break | ||
except Exception as e: | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My USB library seemed to require a length parameter which required a lot of changes like this. Not sure if this is appropriate for master. I could revert.