diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 473321c..0f0217b 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -141,8 +141,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 @@ -628,6 +628,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""" @@ -642,8 +684,43 @@ def set_ledstrip_color_old(self): # DEPREACTION END - - + 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): @@ -802,6 +879,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']) @@ -821,6 +899,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: @@ -834,6 +918,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) @@ -1661,6 +1746,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) @@ -1700,6 +1788,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'] @@ -1716,6 +1818,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) @@ -1760,6 +1867,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) diff --git a/octoprint_enclosure/static/js/enclosure.js b/octoprint_enclosure/static/js/enclosure.js index e9c4847..0ff45cc 100644 --- a/octoprint_enclosure/static/js/enclosure.js +++ b/octoprint_enclosure/static/js/enclosure.js @@ -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; } @@ -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) { @@ -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(""), @@ -657,6 +684,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(); diff --git a/octoprint_enclosure/templates/enclosure_navbar.jinja2 b/octoprint_enclosure/templates/enclosure_navbar.jinja2 index 143bcaa..9b1039e 100644 --- a/octoprint_enclosure/templates/enclosure_navbar.jinja2 +++ b/octoprint_enclosure/templates/enclosure_navbar.jinja2 @@ -20,6 +20,20 @@ + +
  • + + + + on + + + off + + +
  • + +
  • diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index a30ca69..30233b6 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -35,6 +35,12 @@ +
    + +
    - +
    @@ -263,7 +269,7 @@
    - +
    + + +
    + + Use SPI Interface Directly (Ignores Data/Clock Pin settings)
    + Connect the Dotstar to the MOSI and MCLK pins on the Raspberry Pi
    +
    +
    + +
    + + Choose any GPIO pin to provide the Clock signal +
    + +
    + + Choose any GPIO pin to provide the Data +
    +
    +
    + +
    + + Number of led's on strip +
    +
    +
    + +
    + + Value between 0 and 1 +
    +
    +
    + +
    + + Value needs to follow the format rgb(value_red,value_green,value_blue) where values should be between 0 and 255 +
    +
    +
    diff --git a/octoprint_enclosure/templates/enclosure_tab.jinja2 b/octoprint_enclosure/templates/enclosure_tab.jinja2 index 9b4feba..ae8016f 100644 --- a/octoprint_enclosure/templates/enclosure_tab.jinja2 +++ b/octoprint_enclosure/templates/enclosure_tab.jinja2 @@ -226,6 +226,41 @@
    + +

    + + DotStar + + on + + + off + +

    + +
    + + + + + + +
    +
    + Color: + +
    +
    + Brightness: + +
    + + +