Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 131 additions & 2 deletions octoprint_enclosure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ def on_after_startup(self):
self.generate_temp_hum_control_status()
self.setup_gpio()
self.configure_gpio()
self.update_ui()
self.start_outpus_with_server()
self.update_ui()
self.handle_initial_gpio_control()
self.start_timer()
self.print_complete = False
Expand Down Expand Up @@ -682,6 +682,48 @@ def set_neopixel_old(self):

return jsonify(success=True)

@octoprint.plugin.BlueprintPlugin.route("/setDotstar", methods=["GET"])
def set_dotstar_old(self):
""" set_dotstar method get request from octoprint and send the command to dotstar"""
gpio_index = self.to_int(request.values["index_id"])
action = request.values["action"]

for rpi_output in self.rpi_outputs:
if gpio_index == self.to_int(rpi_output['index_id']):
#self._logger.info("DotStar Output Data: %s", rpi_output)
led_count = rpi_output['dotstar_count']
use_spi = rpi_output['dotstar_use_spi']
if use_spi == True:
data_pin = 0
clock_pin = 0
else:
data_pin =self.to_int(rpi_output['dotstar_data_pin'])
clock_pin = self.to_int(rpi_output['dotstar_clock_pin'])

if action == "setColor" :
active = True
red = request.values["red"]
green = request.values["green"]
blue = request.values["blue"]
led_brightness = request.values["brightness"]
elif action == "setPower":
led_brightness = rpi_output['dotstar_brightness']
#self._logger.info("DotStar Requested Power: %s", request.values["status"])
if request.values["status"] == "true":
active = True
else:
active = False

if rpi_output['dotstar_color'] is None:
red, green, blue = self.get_color_from_rgb(rpi_output['default_dotstar_color'])
else:
red, green, blue = self.get_color_from_rgb(rpi_output['dotstar_color'])


self.send_dotstar_command(gpio_index, active, data_pin, clock_pin, led_count, led_brightness, red, green, blue)

return jsonify(success=True)

@octoprint.plugin.BlueprintPlugin.route("/setLedstripColor", methods=["GET"])
def set_ledstrip_color_old(self):
""" set_ledstrip_color method get request from octoprint and send the command to Open-Smart RGB LED Strip"""
Expand All @@ -695,7 +737,6 @@ def set_ledstrip_color_old(self):

# DEPREACTION END


# GPIO over i2c

def gpio_i2c_input(self, output, active_low=None):
Expand Down Expand Up @@ -754,6 +795,44 @@ def gpio_i2c_write(self, output, state, queue_id=None):
pass


def send_dotstar_command(self, index_id, active, data_pin, clock_pin, led_count, led_brightness, red, green, blue, queue_id=None):
if queue_id is not None:
self._logger.debug("running scheduled queue id %s", queue_id)
self.stop_queue_item(queue_id)

# Import here so we don't rely on this library when no dotstar strip is in use.
try:
import board
import adafruit_dotstar as dotstar

self._logger.info("DotStar Modules Imported")

# Assume SPI if clock or data pin is 0
if ((self.to_int(data_pin) == 0) or (self.to_int(clock_pin) == 0)):
clock_pin = board.SCK
data_pin = board.MOSI

dots = dotstar.DotStar(clock_pin, data_pin, self.to_int(led_count), brightness=self.to_float(led_brightness))
if active:
self._logger.info("Setting DotStar color and brightness")
dots.fill((self.to_int(red),self.to_int(green),self.to_int(blue)))

# Update color, brightness, and power with current values sent to the strip
for rpi_output in self.rpi_outputs:
if self.to_int(index_id) == self.to_int(rpi_output['index_id']):
rpi_output['dotstar_color'] = 'rgb({0!s},{1!s},{2!s})'.format(red, green, blue)
rpi_output['dotstar_brightness'] = led_brightness
rpi_output['dotstar_active'] = True
else:
self._logger.info("Turning off DotStar")
dots.fill(0)
for rpi_output in self.rpi_outputs:
if self.to_int(index_id) == self.to_int(rpi_output['index_id']):
rpi_output['dotstar_active'] = False
self.update_ui_outputs()
except Exception as ex:
self._logger.warn(ex)

def send_neopixel_command(self, led_pin, led_count, led_brightness, red, green, blue, address, neopixel_dirrect,
index_id, queue_id=None):
"""Send neopixel command
Expand Down Expand Up @@ -920,6 +999,7 @@ def update_ui_outputs(self):
regular_status = []
pwm_status = []
neopixel_status = []
dotstar_status = []
temp_control_status = []
for output in self.rpi_outputs:
index = self.to_int(output['index_id'])
Expand All @@ -945,6 +1025,12 @@ def update_ui_outputs(self):
val = output['neopixel_color']
neopixel_status.append(
dict(index_id=index, color=val, auto_startup=startup, auto_shutdown=shutdown))
if output['output_type'] == 'dotstar':
col = output['dotstar_color']
level = output['dotstar_brightness']
pwr = output['dotstar_active']
dotstar_status.append(
dict(index_id=index, color=col, brightness=level, active=pwr, auto_startup=startup, auto_shutdown=shutdown))
if output['output_type'] == 'pwm':
for pwm in self.pwm_instances:
if pin in pwm:
Expand All @@ -958,6 +1044,7 @@ def update_ui_outputs(self):
self._plugin_manager.send_plugin_message(self._identifier,
dict(rpi_output_regular=regular_status, rpi_output_pwm=pwm_status,
rpi_output_neopixel=neopixel_status,
rpi_output_dotstar=dotstar_status,
rpi_output_temp_hum_ctrl=temp_control_status))
except Exception as ex:
self.log_error(ex)
Expand Down Expand Up @@ -1883,6 +1970,9 @@ def schedule_auto_shutdown_outputs(self, rpi_output, shutdown_delay_seconds):
self.schedule_pwm_duty_on_queue(shutdown_delay_seconds, rpi_output, 0, sufix)
if (rpi_output['output_type'] == 'neopixel_indirect' or rpi_output['output_type'] == 'neopixel_direct'):
self.add_neopixel_output_to_queue(rpi_output, shutdown_delay_seconds, 0, 0, 0, sufix)
if (rpi_output['output_type'] == 'dotstar'):
active = False
self.add_dotstar_output_to_queue(rpi_output, shutdown_delay_seconds, active, 0, 0, 0, 0, sufix)
if rpi_output['output_type'] == 'temp_hum_control':
value = 0
self.add_temperature_output_temperature_queue(shutdown_delay_seconds, rpi_output, value, sufix)
Expand Down Expand Up @@ -1925,6 +2015,20 @@ def start_outpus_with_server(self):
neopixel_direct = rpi_output['output_type'] == 'neopixel_direct'
self.send_neopixel_command(self.to_int(rpi_output['gpio_pin']), led_count, led_brightness, red,
green, blue, address, neopixel_direct, index_id)
if (rpi_output['output_type'] == 'dotstar'):
index_id = self.to_int(rpi_output['index_id'])
red, green, blue = self.get_color_from_rgb(rpi_output['default_dotstar_color'])
brightness = rpi_output['default_dotstar_brightness']
led_count = rpi_output['dotstar_count']
use_spi = rpi_output['dotstar_use_spi']
if use_spi == True:
data_pin = 0
clock_pin = 0
else:
data_pin =self.to_int(rpi_output['dotstar_data_pin'])
clock_pin = self.to_int(rpi_output['dotstar_clock_pin'])
active = True
self.send_dotstar_command(index_id, active, data_pin, clock_pin, led_count, brightness, red, green, blue)
if rpi_output['output_type'] == 'temp_hum_control':
rpi_output['temp_ctr_set_value'] = rpi_output['temp_ctr_default_value']

Expand All @@ -1941,6 +2045,11 @@ def schedule_auto_startup_outputs(self, rpi_output, delay_seconds):
if (rpi_output['output_type'] == 'neopixel_indirect' or rpi_output['output_type'] == 'neopixel_direct'):
red, green, blue = self.get_color_from_rgb(rpi_output['default_neopixel_color'])
self.add_neopixel_output_to_queue(rpi_output, delay_seconds, red, green, blue, sufix)
if (rpi_output['output_type'] == 'dotstar'):
red, green, blue = self.get_color_from_rgb(rpi_output['default_dotstar_color'])
brightness = rpi_output['default_dotstar_brightness']
active = True
self.add_dotstar_output_to_queue(rpi_output, delay_seconds, active, red, green, blue, brightness, sufix)
if rpi_output['output_type'] == 'temp_hum_control':
value = rpi_output['temp_ctr_default_value']
self.add_temperature_output_temperature_queue(delay_seconds, rpi_output, value, sufix)
Expand Down Expand Up @@ -1985,6 +2094,26 @@ def add_neopixel_output_to_queue(self, rpi_output, delay_seconds, red, green, bl

self.event_queue.append(dict(queue_id=queue_id, thread=thread))

def add_dotstar_output_to_queue(self, rpi_output, delay_seconds, active, red, green, blue, brightness, sufix):
led_count = rpi_output['dotstar_count']
use_spi = rpi_output['dotstar_use_spi']
if use_spi == True:
data_pin = 0
clock_pin = 0
else:
data_pin =self.to_int(rpi_output['dotstar_data_pin'])
clock_pin = self.to_int(rpi_output['dotstar_clock_pin'])

index_id = self.to_int(rpi_output['index_id'])
queue_id = '{0!s}_{1!s}'.format(index_id, sufix)

self._logger.debug("Scheduling dotstar output id %s for on %s delay_seconds", queue_id, delay_seconds)

thread = threading.Timer(delay_seconds, self.send_dotstar_command,
args=[index_id, active, data_pin, clock_pin, led_count, brightness, red, green, blue, queue_id])
# (self, index_id, active, data_pin, clock_pin, led_count, led_brightness, red, green, blue
self.event_queue.append(dict(queue_id=queue_id, thread=thread))

def add_pwm_output_to_queue(self, delay_seconds, rpi_output, value, sufix):
queue_id = '{0!s}_{1!s}'.format(rpi_output['index_id'], sufix)

Expand Down
96 changes: 95 additions & 1 deletion octoprint_enclosure/static/js/enclosure.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ $(function () {
self.hasAnyNavbarOutput = function(){
return_value = false;
self.rpi_outputs().forEach(function (output) {
if ((output.output_type()=="regular" || output.output_type()=="gcode_output") && output.show_on_navbar()) {
if ((output.output_type()=="regular" || output.output_type()=="gcode_output" || output.output_type()=="dotstar" ) && output.show_on_navbar()) {
return_value = true;
return false;
}
Expand Down Expand Up @@ -225,6 +225,21 @@ $(function () {
})
}

if (data.hasOwnProperty("rpi_output_dotstar")) {
data.rpi_output_dotstar.forEach(function (output) {
var linked_output = ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
return (output['index_id'] == item.index_id());
}).pop();
if (linked_output) {
linked_output.dotstar_color(output['color'])
linked_output.dotstar_active(output['active'])
linked_output.dotstar_brightness(output['brightness'])
linked_output.auto_shutdown(output['auto_shutdown'])
linked_output.auto_startup(output['auto_startup'])
}
})
}

if (data.hasOwnProperty("rpi_output_ledstrip")) {
data.rpi_output_ledstrip.forEach(function (output) {
var linked_output = ko.utils.arrayFilter(self.rpi_outputs(), function (item) {
Expand Down Expand Up @@ -414,6 +429,18 @@ $(function () {
new_neopixel_color: ko.observable(""),
neopixel_count: ko.observable(0),
neopixel_brightness: ko.observable(255),
dotstar_color: ko.observable("rgb(0,0,0)"),
default_dotstar_color: ko.observable(""),
new_dotstar_color: ko.observable(""),
new_dotstar_brightness: ko.observable(""),
dotstar_count: ko.observable(0),
dotstar_brightness: ko.observable(1),
default_dotstar_brightness: ko.observable(""),
dotstar_use_spi: ko.observable(true),
dotstar_gpio_clk: ko.observable(""),
dotstar_gpio_dat: ko.observable(""),
dotstar_brightness: ko.observable(""),
dotstar_active: ko.observable(false),
ledstrip_color: ko.observable("rgb(0,0,0)"),
default_ledstrip_color: ko.observable(""),
new_ledstrip_color: ko.observable(""),
Expand Down Expand Up @@ -670,6 +697,73 @@ $(function () {
}
};

self.handleDotstarColor = function (item) {
self.handleDotstar(item, item.new_dotstar_color(), item.dotstar_brightness())
}

self.handleDotstarBrightness = function (item) {
self.handleDotstar(item, item.dotstar_color(), item.new_dotstar_brightness())
}

self.handleDotstar = function (item, color, brightness) {

var index = item.index_id() ;
//var or_tempStr = item.new_dotstar_color();
var tempStr = color.replace("rgb(", "");

var r = parseInt(tempStr.substring(0, tempStr.indexOf(",")));
tempStr = tempStr.slice(tempStr.indexOf(",") + 1);
var g = parseInt(tempStr.substring(0, tempStr.indexOf(",")));
tempStr = tempStr.slice(tempStr.indexOf(",") + 1);
var b = parseInt(tempStr.substring(0, tempStr.indexOf(")")));

if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255 || isNaN(r) || isNaN(g) || isNaN(b)) {
new PNotify({
title: "Enclosure",
text: "Color needs to follow the format rgb(value_red,value_green,value_blue)!",
type: "error"
});
} else {
$.ajax({
type: "GET",
dataType: "json",
data: {
"index_id": index,
"action": "setColor",
"red": r,
"green": g,
"blue": b,
"brightness": brightness
},
url: self.buildPluginUrl("/setDotstar"),
success: function (data) {
item.new_dotstar_color("");
self.getUpdateUI();
}
});
}
};

self.handleDotstarPower = function (item, form) {

var request = {
"status": !item.dotstar_active(),
"index_id": item.index_id(),
"action": "setPower"
};

$.ajax({
type: "GET",
dataType: "json",
data: request,
url: self.buildPluginUrl("/setDotstar"),
success: function (data) {
self.getUpdateUI();
}
});
};


self.handleLedstripColor = function (item) {
var index = item.index_id() ;
var or_tempStr = item.new_ledstrip_color();
Expand Down
14 changes: 14 additions & 0 deletions octoprint_enclosure/templates/enclosure_navbar.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@
</li>
<!-- /ko -->

<!-- ko if: ($data.output_type() == "dotstar") -->
<li>
<a href="javascript:void(0)" data-bind="click: $root.handleDotstarPower">
<span data-bind="html: label"> </span>
<!-- ko if: ($data.dotstar_active()) -->
<span class="badge badge-success help-inline">on</span>
<!-- /ko -->
<!-- ko ifnot: ($data.dotstar_active()) -->
<span class="badge badge-important help-inline">off</span>
<!-- /ko -->
</a>
</li>
<!-- /ko -->

<!-- ko if: ($data.output_type() == "gcode_output") -->
<!-- ko if: ($root.isOperational()) -->
<li>
Expand Down
Loading