diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 3011479..5fd1b5a 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -3,6 +3,7 @@ from __future__ import absolute_import from octoprint.events import eventManager, Events from octoprint.util import RepeatedTimer from subprocess import Popen, PIPE +from .ledstrip import LEDStrip import octoprint.plugin import RPi.GPIO as GPIO import flask @@ -290,6 +291,17 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, return flask.jsonify(success=True) + @octoprint.plugin.BlueprintPlugin.route("/setLedstripColor", methods=["GET"]) + def set_ledstrip_color(self): + """ set_ledstrip_color method get request from octoprint and send the comand to Open-Smart RGB LED Strip""" + gpio_index = self.to_int(flask.request.values["index_id"]) + rgb = flask.request.values["rgb"] + for rpi_output in self.rpi_outputs: + if gpio_index == self.to_int(rpi_output['index_id']): + self.ledstrip_set_rgb(rpi_output, rgb) + + return flask.jsonify(success=True) + 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 @@ -1320,6 +1332,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, value = True if rpi_output['active_low'] else False self.add_regular_output_to_queue( shutdown_delay_seconds, rpi_output, value, sufix) + if rpi_output['output_type'] == 'ledstrip': + self.ledstrip_set_rgb(rpi_output) if rpi_output['output_type'] == 'pwm' and not rpi_output['pwm_temperature_linked']: value = 0 self.add_pwm_output_to_queue( @@ -1337,6 +1351,19 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, if self._settings.get(["debug"]) is True: self._logger.info("Events scheduled to run %s", self.event_queue) + def ledstrip_set_rgb(self, rpi_output, rgb=None): + clk = rpi_output["ledstrip_gpio_clk"] + data = rpi_output["ledstrip_gpio_dat"] + if clk is not None and data is not None: + ledstrip = LEDStrip(self.to_int(clk), self.to_int(data)) + if rgb is None: + red, green, blue = self.get_color_from_rgb(rpi_output['default_ledstrip_color']) + else: + red, green, blue = self.get_color_from_rgb(rgb) + + self._logger.info("LEDSTRIP set rgb color: %s, %s, %s", red, green, blue) + ledstrip.setcolourrgb(self.to_int(red), self.to_int(green), self.to_int(blue)) + def start_outpus_with_server(self): for rpi_output in self.rpi_outputs: if rpi_output['startup_with_server']: @@ -1344,6 +1371,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, if rpi_output['output_type'] == 'regular': value = False if rpi_output['active_low'] else True self.write_gpio(gpio, value) + if rpi_output['output_type'] == 'ledstrip': + self.ledstrip_set_rgb(rpi_output) if rpi_output['output_type'] == 'pwm' and not rpi_output['pwm_temperature_linked']: value = self.to_int(rpi_output['default_duty_cycle']) self.write_pwm(gpio, value) @@ -1366,6 +1395,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, value = False if rpi_output['active_low'] else True self.add_regular_output_to_queue( delay_seconds, rpi_output, value, sufix) + if rpi_output['output_type'] == 'ledstrip': + self.ledstrip_set_rgb(rpi_output) if rpi_output['output_type'] == 'pwm' and not rpi_output['pwm_temperature_linked']: value = self.to_int(rpi_output['default_duty_cycle']) self.add_pwm_output_to_queue( diff --git a/octoprint_enclosure/ledstrip.py b/octoprint_enclosure/ledstrip.py new file mode 100644 index 0000000..6876c32 --- /dev/null +++ b/octoprint_enclosure/ledstrip.py @@ -0,0 +1,143 @@ +""" +copyright 2017 Tim Richardson, github profile: https://github.com/GeekyTim + +This file is part of https://github.com/GeekyTim/Open-Smart-RGB-LED-Strip-Driver-for-Raspberry-Pi +Open-Smart-RGB-LED-Strip-Driver-for-Raspberry-Pi is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +Open-Smart-RGB-LED-Strip-Driver-for-Raspberry-Pi is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Open-Smart-RGB-LED-Strip-Driver-for-Raspberry-Pi. If not, see . + + +LEDStrip Class +-------------- +A Python class that drives the Open-Smart RGB LED Strip from a Raspberry Pi. +Hardware Obtained from http://www.dx.com/p/full-color-rgb-led-strip-driver-module-for-arduino-blue-black-314667 + +Code originally developed by Philip Leder (https://github.com/schlank/Catalex-Led-Strip-Driver-Raspberry-Pi) + +Pin Connections +Choose any two GPIO Pins; one to provide the Clock signal (CLK), the other the Data (DAT) + +Pi Open-Smart Controller +Gnd Gnd ++5v Vcc +DAT Din +CLK Cin + +Place this file in the same directory as your code. +In your code, import the file: + from ledstrip import LEDStrip + +Create a new LED Strip which uses your chosen pins (CLK and DAT) with, e.g.: + CLK = 17 + DAT = 18 + strip = LEDStrip(CLK, DAT) + +Set the colour of the LED strip with + strip.setcolor(red, green, blue): + +The following methods are public: + setcolourrgb(r, g, b) - Sets the LED strip to colour rgb where r, g, b are in the range 0 to 255 + setcolourwhite() - Sets the strip to white + setcolourred() - Sets the strip to Red + setcolourgreen() - Sets the strip to Green + setcolourblue() - Sets the strip to Blue + setcolouroff() - Turns the strip off + setcolourhex('hex') - Sets the LED strip to the hex colour 'hex' in range '000000' to 'FFFFFF' +""" + +import time +import RPi.GPIO as GPIO + + +class LEDStrip: + def __init__(self, clock, data): + GPIO.setwarnings(False) + GPIO.setmode(GPIO.BCM) + self.__clock = clock + self.__data = data + self.__delay = 0 + GPIO.setup(self.__clock, GPIO.OUT) + GPIO.setup(self.__data, GPIO.OUT) + + def __sendclock(self): + GPIO.output(self.__clock, False) + time.sleep(self.__delay) + GPIO.output(self.__clock, True) + time.sleep(self.__delay) + + def __send32zero(self): + for x in range(32): + GPIO.output(self.__data, False) + self.__sendclock() + + def __senddata(self, dx): + self.__send32zero() + for x in range(32): + if ((dx & 0x80000000) != 0): + GPIO.output(self.__data, True) + else: + GPIO.output(self.__data, False) + dx <<= 1 + self.__sendclock() + self.__send32zero() + + def __getcode(self, dat): + tmp = 0 + if ((dat & 0x80) == 0): + tmp |= 0x02 + if ((dat & 0x40) == 0): + tmp |= 0x01 + return tmp + + def setcolourrgb(self, red, green, blue): + dx = 0 + dx |= 0x03 << 30 + dx |= self.__getcode(blue) + dx |= self.__getcode(green) + dx |= self.__getcode(red) + + dx |= blue << 16 + dx |= green << 8 + dx |= red + + self.__senddata(dx) + + def setcolourwhite(self): + self.setcolourrgb(255, 255, 255) + + def setcolouroff(self): + self.setcolourrgb(0, 0, 0) + + def setcolourred(self): + self.setcolourrgb(255, 0, 0) + + def setcolourgreen(self): + self.setcolourrgb(0, 255, 0) + + def setcolourblue(self): + self.setcolourrgb(0, 0, 255) + + def setcolourhex(self, hex): + print('Hex') + try: + hexcolour = int(hex, 16) + red = int((hexcolour & 255 * 255 * 255) / (255 * 255)) + green = int((hexcolour & 255 * 255) / 255) + blue = hexcolour & 255 + self.setcolourrgb(red, green, blue) + except: + hexcolour = 0 + print("Error converting Hex input (%s) a colour." % hex) + + def cleanup(self): + self.setcolouroff() + GPIO.cleanup() \ No newline at end of file diff --git a/octoprint_enclosure/static/css/enclosure.css b/octoprint_enclosure/static/css/enclosure.css index 781a8e9..0909952 100644 --- a/octoprint_enclosure/static/css/enclosure.css +++ b/octoprint_enclosure/static/css/enclosure.css @@ -67,7 +67,7 @@ text-decoration: none; } -.neopixel-div{ +.ledstrip-div, .neopixel-div{ width: 25%; } diff --git a/octoprint_enclosure/static/js/enclosure.js b/octoprint_enclosure/static/js/enclosure.js index a0ae30d..383e740 100644 --- a/octoprint_enclosure/static/js/enclosure.js +++ b/octoprint_enclosure/static/js/enclosure.js @@ -225,6 +225,19 @@ $(function () { }) } + if (data.hasOwnProperty("rpi_output_ledstrip")) { + data.rpi_output_ledstrip.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.ledstrip_color(output['color']) + linked_output.auto_shutdown(output['auto_shutdown']) + linked_output.auto_startup(output['auto_startup']) + } + }) + } + if (data.hasOwnProperty("filament_sensor_status")) { data.filament_sensor_status.forEach(function (filament_sensor) { var linked_filament_sensor = ko.utils.arrayFilter(self.rpi_inputs(), function (item) { @@ -401,6 +414,11 @@ $(function () { new_neopixel_color: ko.observable(""), neopixel_count: ko.observable(0), neopixel_brightness: ko.observable(255), + ledstrip_color: ko.observable("rgb(0,0,0)"), + default_ledstrip_color: ko.observable(""), + new_ledstrip_color: ko.observable(""), + ledstrip_gpio_clk: ko.observable(""), + ledstrip_gpio_dat: ko.observable(""), microcontroller_address: ko.observable(0), gcode: ko.observable(""), show_on_navbar: ko.observable(false) @@ -638,6 +656,39 @@ $(function () { } }; + self.handleLedstripColor = function (item) { + var index = item.index_id() ; + var or_tempStr = item.new_ledstrip_color(); + var tempStr = or_tempStr.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, + "rgb": or_tempStr + }, + url: self.buildPluginUrl("/setLedstripColor"), + success: function (data) { + item.new_ledstrip_color(""); + self.getUpdateUI(); + } + }); + } + }; + self.isNumeric = function (n) { return !isNaN(parseFloat(n)) && isFinite(n); }; diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index 8203136..97c05e5 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -35,6 +35,12 @@ +
+ +
- +
@@ -256,7 +262,7 @@
- +
- +
+ @@ -404,6 +411,27 @@
+ +
+ +
+ + Choose any GPIO pin to provide the Clock signal +
+ +
+ + Choose any GPIO pin to provide the Data +
+
+
+ +
+ + 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 dff7479..9b4feba 100644 --- a/octoprint_enclosure/templates/enclosure_tab.jinja2 +++ b/octoprint_enclosure/templates/enclosure_tab.jinja2 @@ -160,6 +160,19 @@
+ +

+ + ledstrip +

+
+ + +
+ +