Skip to content

Commit

Permalink
✨ Add 'Reverse Progress Bar' and 'From Center' progress effects (#212)
Browse files Browse the repository at this point in the history
* Fixes issue #210 by adding the `reverse` parameter and setting the left/right `reverse_progress` parameter based on that

* Refactored progress bar effect into a shared method

* Refactored both ends effect to use the shared progress_bar_impl method

* Added the "From Center" progress effect

* Added the "Reversed Progress Bar" progress effect

* Remove `Reverse progress bar direction` from the UI and from being passed into the `EffectRunner`

* ↔️ Add settings migration

* 🎨 reverse is already a bool

Closes #209 
Closes #210

---------

Co-authored-by: Charlie Powell <[email protected]>
  • Loading branch information
CoryCharlton and cp2004 authored Jan 29, 2023
1 parent 95b73d4 commit 75dc70e
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 47 deletions.
4 changes: 3 additions & 1 deletion octoprint_ws281x_led_status/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,11 @@ class DeprecatedAtCommands:
}
PROGRESS_EFFECTS = {
"Progress Bar": progress.progress_bar,
"Reversed Progress Bar": progress.progress_bar_reversed,
"Gradient": progress.gradient,
"Single Pixel": progress.single_pixel,
"Both Ends": progress.both_ends,
"Both Ends": progress.progress_bar_from_both_ends,
"From Center": progress.progress_bar_from_center,
}
MODES = [
"startup",
Expand Down
106 changes: 64 additions & 42 deletions octoprint_ws281x_led_status/effects/progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,49 @@ def progress_bar(
value,
progress_color,
base_color,
reverse,
*args,
**kwargs
):
brightness_manager.reset_brightness()
num_pixels = strip.numPixels()
upper_bar = (value / 100) * num_pixels
upper_remainder, upper_whole = math.modf(upper_bar)
pixels_remaining = num_pixels

for i in range(int(upper_whole)):
pixel = ((num_pixels - 1) - i) if reverse else i
strip.setPixelColorRGB(pixel, *progress_color)
pixels_remaining -= 1

if upper_remainder > 0.0:
tween_color = blend_two_colors(progress_color, base_color, upper_remainder)
pixel = ((num_pixels - int(upper_whole)) - 1) if reverse else int(upper_whole)
strip.setPixelColorRGB(pixel, *tween_color)
pixels_remaining -= 1

for i in range(pixels_remaining):
pixel = (
((pixels_remaining - 1) - i)
if reverse
else ((num_pixels - pixels_remaining) + i)
)
strip.setPixelColorRGB(pixel, *base_color)
progress_bar_impl(strip, queue, brightness_manager, value, progress_color, base_color, False, False)

strip.show()
if not q_poll_sleep(0.1, queue):
return

def progress_bar_from_both_ends(
strip,
queue,
brightness_manager,
value,
progress_color,
base_color,
*args,
**kwargs
):
progress_bar_impl(strip, queue, brightness_manager, value, progress_color, base_color, False, True)


def progress_bar_from_center(
strip,
queue,
brightness_manager,
value,
progress_color,
base_color,
*args,
**kwargs
):
progress_bar_impl(strip, queue, brightness_manager, value, progress_color, base_color, True, True)


def progress_bar_reversed(
strip,
queue,
brightness_manager,
value,
progress_color,
base_color,
*args,
**kwargs
):
progress_bar_impl(strip, queue, brightness_manager, value, progress_color, base_color, True, False)


def gradient(
Expand Down Expand Up @@ -81,47 +92,58 @@ def single_pixel(
return


def both_ends(
strip, queue, brightness_manager, value, progress_color, base_color, *args, **kwargs
def progress_bar_impl(
strip,
queue,
brightness_manager,
value,
progress_color,
base_color,
reverse,
half_strip,
*args,
**kwargs
):
brightness_manager.reset_brightness()
num_pixels = strip.numPixels()
odd_pixel = 0
if num_pixels % 2 != 0:
num_pixels -= 1
# Set the unused pixel to off
strip.setPixelColorRGB(num_pixels, 0, 0, 0)
odd_pixel = 1

def progress(min_pixel, max_pixel, val, reverse):
def progress(min_pixel, max_pixel, val, reverse_progress):
number_pixels = max_pixel - min_pixel
upper_bar = (val / 100) * number_pixels
upper_remainder, upper_whole = math.modf(upper_bar)
pixels_remaining = number_pixels

for i in range(int(upper_whole)):
pixel = ((max_pixel - 1) - i) if reverse else i
pixel = ((max_pixel - 1) - i) if reverse_progress else (min_pixel + i)
strip.setPixelColorRGB(pixel, *progress_color)
pixels_remaining -= 1

if upper_remainder > 0.0:
tween_color = blend_two_colors(progress_color, base_color, upper_remainder)
pixel = (
((max_pixel - int(upper_whole)) - 1) if reverse else int(upper_whole)
((max_pixel - int(upper_whole)) - 1) if reverse_progress else (int(upper_whole) + min_pixel)
)
strip.setPixelColorRGB(pixel, *tween_color)
pixels_remaining -= 1

for i in range(pixels_remaining):
pixel = (
((min_pixel + pixels_remaining - 1) - i)
if reverse
else ((number_pixels - pixels_remaining) + i)
if reverse_progress
else (min_pixel + (number_pixels - pixels_remaining) + i)
)
strip.setPixelColorRGB(pixel, *base_color)

# Set the progress to either end of the strip

progress(0, num_pixels // 2, value, False)
progress(num_pixels // 2, num_pixels, value, True)
if half_strip:
# Set the progress to either end of the strip
progress(0, math.floor(num_pixels / 2) + odd_pixel, value, reverse)
progress(math.ceil(num_pixels / 2) - odd_pixel, num_pixels, value, not reverse)
else:
# Set the progress for the entire strip
progress(0, num_pixels, value, reverse)

strip.show()
if not q_poll_sleep(0.1, queue):
Expand Down
1 change: 0 additions & 1 deletion octoprint_ws281x_led_status/runner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ def progress_effect(self, mode, value):
"base_color": apply_color_correction(
self.color_correction, *hex_to_rgb(effect_settings["base"])
),
"reverse": self.strip_settings["reverse"],
},
name=mode,
)
Expand Down
21 changes: 20 additions & 1 deletion octoprint_ws281x_led_status/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
"dma": 10,
"invert": False,
"channel": 0,
"reverse": False,
"type": "WS2811_STRIP_GRB",
"brightness": 50,
"adjustment": {"R": 100, "G": 100, "B": 100},
Expand Down Expand Up @@ -139,6 +138,10 @@ def migrate_settings(target, current, settings):
# 1 => 2
migrate_one_to_two(settings)

if (current is None or current <= 2) and target == 3:
# 2 => 3
migrate_two_to_three(settings)


def migrate_none_to_one(settings):
new_settings = {
Expand Down Expand Up @@ -261,6 +264,22 @@ def migrate_one_to_two(settings):
settings.settings.remove(["plugins", "ws281x_led_status", "debug_logging"])


def migrate_two_to_three(settings):
# See PR #212 for changes
reverse = settings.get(["strip", "reverse"])

if reverse and settings.get(["effects", "progress_print", "effect"]) == "Progress Bar":
settings.set(["effects", "progress_print", "effect"], "Progress Bar Reversed")

if reverse and settings.get(["effects", "progress_heatup", "effect"]) == "Progress Bar":
settings.set(["effects", "progress_heatup", "effect"], "Progress Bar Reversed")

if reverse and settings.get(["effects", "progress_cooling", "effect"]) == "Progress Bar":
settings.set(["effects", "progress_cooling", "effect"], "Progress Bar Reversed")

settings.settings.remove(["plugins", "ws281x_led_status", "strip", "reverse"])


def filter_none(target):
"""
Recursively remove any key/value pairs where the value is None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@

<h5>Progress effects {{ docs.help_icon("configuration/progress-effects") }}</h5>
<form class="form-horizontal">
{{ labelled_checkbox("strip.reverse", "Reverse progress bar direction") }}
<hr>
{{ labelled_checkbox("effects.progress_print.enabled", "Enable Printing Progress") }}
<div class="form-inline" data-bind="visible: {{ binding.effect_binding("progress_print.enabled") }}">
{{ effect_select("progress_print") }}
Expand Down

0 comments on commit 75dc70e

Please sign in to comment.