Add Open-Smart-RGB-LED-Strip-Driver
This commit is contained in:
@@ -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(
|
||||
|
||||
143
octoprint_enclosure/ledstrip.py
Normal file
143
octoprint_enclosure/ledstrip.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
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()
|
||||
@@ -67,7 +67,7 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.neopixel-div{
|
||||
.ledstrip-div, .neopixel-div{
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
<input type="radio" value="ledstrip" data-bind="checked: output_type, attr: {name: 'output_type_' + $index() }"> {{ _('RGB LED Strip') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
<input type="radio" value="temp_hum_control" data-bind="checked: output_type, attr: {name: 'output_type_' + $index() }"> {{ _('Temperature / Humidity Control') }}
|
||||
@@ -85,7 +91,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output" || $data.output_type() == "ledstrip") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('IO Number') }}</label>
|
||||
<div class="controls">
|
||||
@@ -256,7 +262,7 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "gcode_output" || $data.output_type() == "shell_output") -->
|
||||
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "gcode_output" || $data.output_type() == "shell_output" || $data.output_type() == "ledstrip") -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -265,7 +271,7 @@
|
||||
<span class="help-inline">If you plan to use a physical button (INPUT) and want to hide the button from enclosure tab check this.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ko ifnot: ($data.output_type() == "ledstrip") -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -275,6 +281,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
|
||||
|
||||
<!-- ko if: ($data.output_type() == "temperature_alarm" || $data.output_type() == "temp_hum_control" || ($data.output_type() == "pwm" && $data.pwm_temperature_linked())) -->
|
||||
@@ -404,6 +411,27 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: ($data.output_type() == "ledstrip") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('CLK') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: ledstrip_gpio_clk">
|
||||
<span class="help-inline">Choose any GPIO pin to provide the Clock signal</span>
|
||||
</div>
|
||||
<label class="control-label">{{ _('DAT') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: ledstrip_gpio_dat">
|
||||
<span class="help-inline">Choose any GPIO pin to provide the Data</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Color') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: default_ledstrip_color, attr: {name: 'colorpicker' } , click: $root.showColorPicker()">
|
||||
<span class="help-inline">Value needs to follow the format rgb(value_red,value_green,value_blue) where values should be between 0 and 255</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: ($data.output_type() == "neopixel_indirect" || $data.output_type() == "neopixel_direct") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Number of LEDS') }}</label>
|
||||
|
||||
@@ -160,6 +160,19 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "ledstrip") -->
|
||||
<h4>
|
||||
<span data-bind="html: label"> </span>
|
||||
<span class="badge">ledstrip</span>
|
||||
</h4>
|
||||
<div class="input-append ledstrip-div">
|
||||
<input type="text" class="input-block-level" data-bind="click: $root.showColorPicker(), value: new_ledstrip_color, valueUpdate: 'input', attr: {placeholder:ledstrip_color, name: 'colorpicker'}">
|
||||
<button type="submit" class="btn btn-input-inc" title="Set Color" data-bind="enable: $root.isUser(), click: $root.handleLedstripColor">
|
||||
<i class="fa fa-check"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "gcode_output") -->
|
||||
<h4>
|
||||
<span data-bind="html: label"> </span>
|
||||
|
||||
Reference in New Issue
Block a user