bringing dev up to date #268
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
venv
|
||||
.vscode
|
||||
343
API.md
Normal file
343
API.md
Normal file
@@ -0,0 +1,343 @@
|
||||
# API Reference v2.0
|
||||
|
||||
The API is located at \<OctoPrintURL>/plugin/enclosure. This needs to be added before each endpoint in order for the API to function properly. The API either returns a `application/json` body or an empty body for a successful request.
|
||||
|
||||
A failed request will return an error code as well as a short error description.
|
||||
|
||||
## List all inputs
|
||||
|
||||
Endpoint: **GET** `/inputs`
|
||||
|
||||
Response (200):
|
||||
|
||||
```
|
||||
[
|
||||
{
|
||||
"index_id": number,
|
||||
"label": string
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Error Responses:
|
||||
- none
|
||||
|
||||
## List a specific input
|
||||
|
||||
Endpoint: **GET** `/inputs/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Response (200):
|
||||
```
|
||||
{
|
||||
"controlled_io": null,
|
||||
"filament_sensor_timeout": number,
|
||||
"filament_sensor_enabled": boolean,
|
||||
"temp_sensor_address": string,
|
||||
"printer_action": string,
|
||||
"controlled_io_set_value": string,
|
||||
"temp_sensor_type": string,
|
||||
"temp_sensor_navbar": boolean,
|
||||
"temp_sensor_humidity": number,
|
||||
"edge": string,
|
||||
"ds18b20_serial": string,
|
||||
"action_type": string,
|
||||
"input_pull_resistor": string,
|
||||
"input_type": string,
|
||||
"temp_sensor_temp": number,
|
||||
"label": string,
|
||||
"index_id": number,
|
||||
"use_fahrenheit": boolean,
|
||||
"gpio_pin": string
|
||||
}
|
||||
```
|
||||
|
||||
Error Responses:
|
||||
- 404 if specified id cannot be found
|
||||
|
||||
## List all outputs
|
||||
|
||||
Endpoint: **GET** `/outputs`
|
||||
|
||||
Response (200):
|
||||
```
|
||||
[
|
||||
{
|
||||
"index_id": number,
|
||||
"label": string
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Error Responses:
|
||||
- none
|
||||
|
||||
## List a specific output
|
||||
|
||||
Endpoint: **GET** `/outputs/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
|
||||
Response (200):
|
||||
```
|
||||
{
|
||||
"linked_temp_sensor": string,
|
||||
"ledstrip_gpio_dat": string,
|
||||
"startup_time": number,
|
||||
"temp_ctr_deadband": number,
|
||||
"neopixel_brightness": number,
|
||||
"new_duty_cycle": string,
|
||||
"gpio_pin": number,
|
||||
"default_duty_cycle": number,
|
||||
"neopixel_color": string,
|
||||
"hide_btn_ui": boolean,
|
||||
"temp_ctr_set_value": number,
|
||||
"temp_ctr_default_value": number,
|
||||
"default_neopixel_color": string,
|
||||
"controlled_io_set_value": string,
|
||||
"auto_shutdown": boolean,
|
||||
"shell_script": string,
|
||||
"label": string,
|
||||
"default_ledstrip_color": string,
|
||||
"duty_a": number,
|
||||
"toggle_timer_off": number,
|
||||
"alarm_set_temp": number,
|
||||
"ledstrip_gpio_clk": string,
|
||||
"auto_startup": boolean,
|
||||
"controlled_io": number,
|
||||
"shutdown_time": number,
|
||||
"temp_ctr_type": string,
|
||||
"gcode": string,
|
||||
"current_value": boolean,
|
||||
"shutdown_on_failed": boolean,
|
||||
"temperature_b": number,
|
||||
"ledstrip_color": string,
|
||||
"temperature_a": number,
|
||||
"neopixel_count": number,
|
||||
"duty_cycle": number,
|
||||
"toggle_timer_on": number,
|
||||
"show_on_navbar": boolean,
|
||||
"duty_b": number,
|
||||
"toggle_timer": boolean,
|
||||
"pwm_status": number,
|
||||
"gpio_status": boolean,
|
||||
"pwm_frequency": number,
|
||||
"new_ledstrip_color": string,
|
||||
"startup_with_server": boolean,
|
||||
"active_low": boolean,
|
||||
"temp_ctr_max_temp": number,
|
||||
"pwm_temperature_linked": boolean,
|
||||
"temp_ctr_new_set_value": string,
|
||||
"output_type": string,
|
||||
"microcontroller_address": number,
|
||||
"index_id": number,
|
||||
"new_neopixel_color": string
|
||||
}
|
||||
```
|
||||
|
||||
Error Responses:
|
||||
- 404 if specified id cannot be found
|
||||
|
||||
## Control specific output
|
||||
|
||||
Endpoint: **PATCH** `/outputs/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"status": boolean
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Enable/Disable Output auto-startup
|
||||
|
||||
Endpoint: **PATCH** `/outputs/<id>/auto-startup`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"status": boolean
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Control auto-shutdown for specific output
|
||||
|
||||
Endpoint: **PATCH** `/outputs/<id>/auto-shutdown`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"status": boolean
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Control temperature
|
||||
|
||||
Endpoint: **PATCH** `/temperature/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"temperature": number
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Control filament sensor
|
||||
|
||||
Endpoint: **PATCH** `/filament/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"status": boolean
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Set PWM value
|
||||
|
||||
Endpoint: **PATCH** `/pwm/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"duty_cycle": number
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Set RGB LED color
|
||||
|
||||
Endpoint: **PATCH** `/rgb-led/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"rgb": string (rgb(r,g,b))
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Set neopixel color
|
||||
|
||||
Endpoint: **PATCH** `/neopixel/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body (Content-Type: `application/json`):
|
||||
```
|
||||
{
|
||||
"red": number,
|
||||
"green": number,
|
||||
"blue": number
|
||||
}
|
||||
```
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- 400 - wrong Content-Type or malformed request
|
||||
- 406 - missing information (missing attribute given in response body)
|
||||
|
||||
## Clear GPIO Pins
|
||||
|
||||
Endpoint: **POST** `/clear-gpio`
|
||||
|
||||
Body: empty
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- none
|
||||
|
||||
## Update UI
|
||||
|
||||
Endpoint: **POST** `/update`
|
||||
|
||||
Body: empty
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- none
|
||||
|
||||
## Send shell command
|
||||
|
||||
Endpoint: **POST** `/shell/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body: empty
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- none
|
||||
|
||||
## Send gcode command
|
||||
|
||||
Endpoint: **POST** `/gcode/<id>`
|
||||
|
||||
*Note: id needs to be int (index_id)*
|
||||
|
||||
Body: empty
|
||||
|
||||
Response (204): No-Content
|
||||
|
||||
Error Responses:
|
||||
- none
|
||||
27
README.md
27
README.md
@@ -69,7 +69,7 @@ Start by adding the following line to /boot/config.txt
|
||||
<pre><code>dtoverlay=w1-gpio</code></pre>
|
||||
|
||||
After rebooting, you can check if the OneWire device was found properly with
|
||||
<pre><code>dmesg | grep w1-gpip</code></pre>
|
||||
<pre><code>dmesg | grep w1-gpio</code></pre>
|
||||
You should see something like
|
||||
<pre><code>[ 3.030368] w1-gpio onewire@0: gpio pin 4, external pullup pin -1, parasitic power 0</code></pre>
|
||||
|
||||
@@ -86,7 +86,7 @@ The response will either have YES or NO at the end of the first line. If it is y
|
||||
|
||||
Copy the serial number, you will need to configure the plugin. Note that for the serial number includes the 28-, for example 28-0000069834ff.
|
||||
|
||||
* For the SI7021, BME280 and TMP102 sensors
|
||||
* For the SI7021, BME280, TMP102 and MCP9808 sensors
|
||||
|
||||
Enable I2C on your raspberry pi, depending on raspi-config version, step by step can be different:
|
||||
|
||||
@@ -107,6 +107,27 @@ Find the address of the sensor:
|
||||
|
||||
<pre><code>i2cdetect -y 1</code></pre>
|
||||
|
||||
* For Neopixel
|
||||
|
||||
If your setup does not have pip install pip:
|
||||
`sudo apt-get install python-pip`
|
||||
|
||||
Install the required library:
|
||||
`sudo pip install rpi_ws281x`
|
||||
|
||||
rpi_ws281x really needs sudo, and you need to setup up so your rpi does not ask for a password when runing a python script, so run:
|
||||
|
||||
`sudo visudo`
|
||||
|
||||
and add `pi ALL=(ALL) NOPASSWD: ALL` to the end of the file.
|
||||
|
||||
Also backlist the audio kernel:
|
||||
|
||||
`sudo nano /etc/modprobe.d/snd-blacklist.conf`
|
||||
|
||||
add the `blacklist snd_bcm2835` to the end of the file:
|
||||
|
||||
|
||||
* GPIO
|
||||
|
||||
This release uses RPi.GPIO to control IO of raspberry pi, it should install and work automatically. If it doesn't please update your octoprint with the latest release of octopi.
|
||||
@@ -201,4 +222,4 @@ You just need to add the following section:
|
||||
- gcodeviewer
|
||||
- terminal
|
||||
- plugin_enclosure
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
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()
|
||||
27
octoprint_enclosure/max31855.py
Normal file
27
octoprint_enclosure/max31855.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import ctypes
|
||||
import struct
|
||||
import sys
|
||||
|
||||
import Adafruit_GPIO.SPI as SPI
|
||||
import Adafruit_MAX31855.MAX31855 as MAX31855
|
||||
|
||||
|
||||
def main():
|
||||
# Get bus address if provided or use default address
|
||||
SPI_DEVICE = 0
|
||||
if len(sys.argv) >= 2:
|
||||
SPI_DEVICE = int(sys.argv[1], 0)
|
||||
|
||||
if not 0 <= SPI_DEVICE <= 1:
|
||||
raise ValueError("Invalid address value")
|
||||
|
||||
# Raspberry Pi hardware SPI configuration.
|
||||
SPI_PORT = 0
|
||||
sensor = MAX31855.MAX31855(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE))
|
||||
|
||||
temp = sensor.readTempC()
|
||||
|
||||
print('{0:0.1f}'.format(temp))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
67
octoprint_enclosure/mcp9808.py
Normal file
67
octoprint_enclosure/mcp9808.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import sys
|
||||
import smbus
|
||||
|
||||
# default I2C address for device.
|
||||
MCP9808_I2CADDR_DEFAULT = 0x18
|
||||
|
||||
# register addresses.
|
||||
MCP9808_REG_CONFIG = 0x01
|
||||
MCP9808_REG_UPPER_TEMP = 0x02
|
||||
MCP9808_REG_LOWER_TEMP = 0x03
|
||||
MCP9808_REG_CRIT_TEMP = 0x04
|
||||
MCP9808_REG_AMBIENT_TEMP = 0x05
|
||||
MCP9808_REG_MANUF_ID = 0x06
|
||||
MCP9808_REG_DEVICE_ID = 0x07
|
||||
MCP9808_REG_RESOLUTION = 0x08
|
||||
|
||||
# configuration register values.
|
||||
MCP9808_REG_CONFIG_CONTCONV = 0x0000
|
||||
MCP9808_REG_CONFIG_SHUTDOWN = 0x0100
|
||||
MCP9808_REG_CONFIG_CRITLOCKED = 0x0080
|
||||
MCP9808_REG_CONFIG_WINLOCKED = 0x0040
|
||||
MCP9808_REG_CONFIG_INTCLR = 0x0020
|
||||
MCP9808_REG_CONFIG_ALERTSTAT = 0x0010
|
||||
MCP9808_REG_CONFIG_ALERTCTRL = 0x0008
|
||||
MCP9808_REG_CONFIG_ALERTSEL = 0x0002
|
||||
MCP9808_REG_CONFIG_ALERTPOL = 0x0002
|
||||
MCP9808_REG_CONFIG_ALERTMODE = 0x0001
|
||||
|
||||
|
||||
def main():
|
||||
# get bus address if provided or use default address
|
||||
address = MCP9808_I2CADDR_DEFAULT
|
||||
if len(sys.argv) == 2:
|
||||
address = int(sys.argv[1], 16)
|
||||
|
||||
# get I2C bus
|
||||
bus = smbus.SMBus(1)
|
||||
|
||||
# MCP9808 address, default 0x18(24)
|
||||
# configuration register, 0x01(1)
|
||||
# continuous conversion mode, power-up default
|
||||
config = [MCP9808_REG_CONFIG_CONTCONV, 0x00]
|
||||
bus.write_i2c_block_data(address, MCP9808_REG_CONFIG, config)
|
||||
|
||||
# MCP9808 address, default 0x18(24)
|
||||
# select resolution rgister, 0x08(8)
|
||||
# resolution = +0.0625 / C, 0x03(03)
|
||||
bus.write_byte_data(address, MCP9808_REG_RESOLUTION, 0x03)
|
||||
|
||||
# MCP9808 address, default 0x18(24)
|
||||
# read data back from 0x05(5), 2 bytes
|
||||
# temp MSB, TEMP LSB
|
||||
data = bus.read_i2c_block_data(address, MCP9808_REG_AMBIENT_TEMP, 2)
|
||||
|
||||
# convert the data to 13-bits
|
||||
ctemp = ((data[0] & 0x1F) * 256) + data[1]
|
||||
if ctemp > 4095:
|
||||
ctemp -= 8192
|
||||
ctemp = ctemp * 0.0625
|
||||
# ftemp = ctemp * 1.8 + 32
|
||||
|
||||
# output data
|
||||
print('{0:0.2f}'.format(ctemp))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +1,4 @@
|
||||
from neopixel import *
|
||||
from rpi_ws281x import *
|
||||
import sys
|
||||
import time
|
||||
|
||||
@@ -12,7 +12,7 @@ if len(sys.argv) == 8:
|
||||
red = int(sys.argv[4])
|
||||
green = int(sys.argv[5])
|
||||
blue = int(sys.argv[6])
|
||||
LED_DMA = int(sys.argv[7], 16)
|
||||
LED_DMA = int(sys.argv[7])
|
||||
else:
|
||||
print("fail")
|
||||
sys.exit(1)
|
||||
@@ -20,7 +20,7 @@ else:
|
||||
strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT)
|
||||
strip.begin()
|
||||
|
||||
color = Color(green, red, blue)
|
||||
color = Color(red, green, blue)
|
||||
|
||||
for i in range(LED_COUNT):
|
||||
strip.setPixelColor(i, color)
|
||||
|
||||
@@ -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" ) -->
|
||||
<!-- 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">
|
||||
@@ -95,8 +101,9 @@
|
||||
<!-- /ko -->
|
||||
<!-- ko if: ($data.output_type() == "neopixel_indirect") -->
|
||||
<span class="help-inline">
|
||||
<span class="label label-danger">Attention</span> Neopixel requires a microcontroler (ex: arduino) connected to I2C bus. This is the pin on the
|
||||
microcontroler that is connected to the Neopixel.
|
||||
<span class="label label-danger">Attention</span> Neopixel requires a microcontroller (ex: arduino)
|
||||
connected to I2C bus. This is the pin on the
|
||||
microcontroller that is connected to the Neopixel.
|
||||
</span>
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
@@ -110,7 +117,7 @@
|
||||
<input type="checkbox" data-bind="checked: pwm_temperature_linked"> {{ _('Link PWM to Temperature') }}
|
||||
</label>
|
||||
<span class="help-inline">Link PWM ouput to temperature. PWM output will be interpolated between the point from duty A, temperature A -> duty
|
||||
B, temperature B. This output will automatomatically start when a print starts and will default to the default
|
||||
B, temperature B. This output will automatically start when a print starts and will default to the default
|
||||
duty cycle when print is complete.
|
||||
</span>
|
||||
</div>
|
||||
@@ -150,7 +157,7 @@
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: toggle_timer"> {{ _('Timer Toggle') }}
|
||||
</label>
|
||||
<span class="help-inline">Toggle output every amount of secconds. It will start when the print starts and stop when print is complete. For
|
||||
<span class="help-inline">Toggle output every amount of seconds. It will start when the print starts and stop when print is complete. For
|
||||
PWM pins it will use the default PWM value when ON.
|
||||
</span>
|
||||
</div>
|
||||
@@ -160,7 +167,7 @@
|
||||
<label class="control-label">{{ _('On Time') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: toggle_timer_on">
|
||||
<span class="help-inline">Time in secconds that the GPIO will remain ON</span>
|
||||
<span class="help-inline">Time in seconds that the GPIO will remain ON</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
@@ -175,14 +182,14 @@
|
||||
|
||||
|
||||
<!-- ko ifnot: (($data.output_type() == "regular" || $data.output_type() == "pwm") && $data.toggle_timer()) -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" ) -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<!-- ko ifnot: ($data.output_type() == "pwm" && $data.pwm_temperature_linked()) -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: startup_with_server"> {{ _('Start with server') }}
|
||||
</label>
|
||||
<span class="help-inline">Choose if output should turn on automatomatically when octoprint starts</span>
|
||||
<span class="help-inline">Choose if output should turn on automatically when octoprint starts</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
@@ -190,7 +197,7 @@
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: auto_startup"> {{ _('Auto Startup') }}
|
||||
</label>
|
||||
<span class="help-inline">Choose if output should turn on automatomatically when print starts</span>
|
||||
<span class="help-inline">Choose if output should turn on automatically when print starts</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
@@ -200,7 +207,7 @@
|
||||
<label class="control-label">{{ _('Startup Delay / Hour') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: startup_time">
|
||||
<span class="help-inline">Time delay in secconds to turn on GPIO when print starts OR exact time that the event should happen, note that
|
||||
<span class="help-inline">Time delay in seconds to turn on GPIO when print starts OR exact time that the event should happen, note that
|
||||
events will only be scheduled after a print starts, time should be formated as HH:MM on a 24 hours format, don't
|
||||
forget to check timezone of your Raspberry Pi.</span>
|
||||
</div>
|
||||
@@ -208,7 +215,7 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" ) -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -251,12 +258,12 @@
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: active_low"> {{ _('Active Low') }}
|
||||
</label>
|
||||
<span class="help-inline">Active low means that the GPIO will turn on when receive a low signal (ground) from Raspbery PI</span>
|
||||
<span class="help-inline">Active low means that the GPIO will turn on when receive a low signal (ground) from Raspberry PI</span>
|
||||
</div>
|
||||
</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 +272,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 +282,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())) -->
|
||||
@@ -399,11 +407,32 @@
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Microcontroller Address') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: microcontroller_address">
|
||||
<span class="help-inline">Microcontroller address in HEX value, you can find it by runing
|
||||
<span class="help-inline">Microcontroller address in HEX value, you can find it by running
|
||||
<code>i2cdetect -y 1</code> on your Raspberry Pi</span>
|
||||
</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>
|
||||
@@ -508,6 +537,8 @@
|
||||
<option value="si7021">SI7021</option>
|
||||
<option value="bme280">BME280</option>
|
||||
<option value="tmp102">TMP102</option>
|
||||
<option value="max31855">MAX31855</option>
|
||||
<option value="mcp9808">MCP9808</option>
|
||||
</select>
|
||||
<span class="help-inline">
|
||||
<span class="label label-important">Attention</span> You need to install and configure the necessary libraries for the temperature sensor, check
|
||||
@@ -532,7 +563,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "tmp102") -->
|
||||
<!-- ko if: ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "tmp102") || ($data.temp_sensor_type() == "mcp9808") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
|
||||
<div class="controls">
|
||||
@@ -546,12 +577,35 @@
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Address') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: temp_sensor_address">
|
||||
<span class="help-inline">Sensor address in HEX value, you can find it by runing
|
||||
<span class="help-inline">Sensor address in HEX value, you can find it by running
|
||||
<code>i2cdetect -y 1</code> on your Raspberry Pi</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.temp_sensor_type() == "18b20") || ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "tmp102") -->
|
||||
<!-- ko if: ($data.temp_sensor_type() == "max31855") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" value="MISO / SCLK" disabled="true">
|
||||
<span class="help-inline">GPIO pin for temperature sensor need to connect the sensor to SPI. Serial Clock to GPIO 1 (SCLK) and Master In/Slave Out Data to GPIO
|
||||
9 (MISO)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Address (CE Select)') }}</label>
|
||||
<div class="controls">
|
||||
<select data-bind="value: temp_sensor_address">
|
||||
<option value="">Select CE</option>
|
||||
<option value="0">CE0</option>
|
||||
<option value="1">CE1</option>
|
||||
</select>
|
||||
<span class="help-inline">CE select: CE0 on GPIO 8 or CE1 on GPIO 7</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.temp_sensor_type() == "18b20") || ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "tmp102") || ($data.temp_sensor_type() == "max31855") || ($data.temp_sensor_type() == "mcp9808") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
|
||||
<div class="controls">
|
||||
@@ -584,14 +638,14 @@
|
||||
<span class="label label-info">Info:</span> PRINTER actions when a condition is met, that can be a filament sensor, button, etc. Actions can
|
||||
be Pause \ Resume \ Cancel a printer_control job, change the filament or disable Temperature Control. You can
|
||||
use the "change filament" action and set up the input GPIO acording to your sensor, for example, if your filament
|
||||
sensor conects to ground when detects the end of the filament, you should choose PULL UP resistors and detect
|
||||
sensor connects to ground when detects the end of the filament, you should choose PULL UP resistors and detect
|
||||
the event on the falling edge.</span>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: ($data.action_type() == "output_control") -->
|
||||
<span class="help-inline">
|
||||
<span class="label label-info">Info:</span> Action will control GPIO outputs when a condition is met, for example detect a press of a button.
|
||||
You can use this to control any previous configured OUTPUTS, basically beeing able to control your lights / fan
|
||||
/ pritner using mechanical buttons buttons instead of the octoprint interface. You can only control REGULAR outputs.
|
||||
/ printer using mechanical buttons buttons instead of the octoprint interface. You can only control REGULAR outputs.
|
||||
</span>
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
@@ -606,7 +660,7 @@
|
||||
<input type="text" class="input-block-level" data-bind="value: gpio_pin">
|
||||
<span class="help-inline">Input GPIO that will detect the event that should trigger the action. For example if you have a filament sensor
|
||||
you put the GPIO pin that the sensor is connected. This can also be a press of a button or any other signal that
|
||||
you want to detect. You can not use GPIO 4 here if you are using temeprature sensor DS18B20</span>
|
||||
you want to detect. You can not use GPIO 4 here if you are using temperature sensor DS18B20</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
||||
@@ -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>
|
||||
@@ -237,7 +250,7 @@
|
||||
|
||||
<!-- ko ifnot: ($data.output_type() == "pwm" && $data.pwm_temperature_linked()) -->
|
||||
<!-- ko ifnot: (($data.output_type() == "regular" || $data.output_type() == "pwm") && $data.toggle_timer()) -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm") -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<div>
|
||||
<h5>
|
||||
<!-- ko if: ($root.isUser()) -->
|
||||
|
||||
4
setup.py
4
setup.py
@@ -14,7 +14,7 @@ plugin_package = "octoprint_enclosure"
|
||||
plugin_name = "OctoPrint-Enclosure"
|
||||
|
||||
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
|
||||
plugin_version = "4.11"
|
||||
plugin_version = "4.13"
|
||||
|
||||
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
|
||||
# module
|
||||
@@ -33,7 +33,7 @@ plugin_url = "https://github.com/vitormhenrique/OctoPrint-Enclosure"
|
||||
plugin_license = "AGPLv3"
|
||||
|
||||
# Any additional requirements besides OctoPrint should be listed here
|
||||
plugin_requires = ["RPi.GPIO>=0.6","requests>=2.7"]
|
||||
plugin_requires = ["RPi.GPIO>=0.6.5","requests>=2.7"]
|
||||
|
||||
additional_setup_parameters = {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user