mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Fix Smoothing configuration (#1476)
* Fix Smoothing out of sync when saving * Only force Smoothing for new devices * Re-Add Max/Min Brightness titles * UI - Fix: Correctly lookup current Instance Name in case instance IDs are not in order * Fix/Update AtmoOrb Firmware images
This commit is contained in:
parent
8000c3e8b7
commit
c7a1fc6b32
@ -15,7 +15,7 @@
|
|||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
|
|
||||||
#define NUM_LEDS 24 // Number of leds
|
#define NUM_LEDS 24 // Number of leds
|
||||||
#define DATA_PIN 7 // Data pin for leds (the default pin 7 might correspond to pin 13 on some boards)
|
#define DATA_PIN D7 // Data pin for leds (the default pin 7 might correspond to pin 13 on some boards)
|
||||||
#define SERIAL_DEBUG 0 // Serial debugging (0=Off, 1=On)
|
#define SERIAL_DEBUG 0 // Serial debugging (0=Off, 1=On)
|
||||||
|
|
||||||
#define ID 1 // Id of this lamp
|
#define ID 1 // Id of this lamp
|
||||||
@ -348,7 +348,7 @@ void identify()
|
|||||||
{
|
{
|
||||||
FastLED.showColor(CRGB::LemonChiffon);
|
FastLED.showColor(CRGB::LemonChiffon);
|
||||||
delay(500);
|
delay(500);
|
||||||
FastLED.showColor(CRGB::Black);
|
FastLED.showColor(CRGB::Black);
|
||||||
delay(500);
|
delay(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
313
assets/firmware/particle/photon/AtmoOrb_UDP.ino
Normal file
313
assets/firmware/particle/photon/AtmoOrb_UDP.ino
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
#include <FastLED.h>
|
||||||
|
FASTLED_USING_NAMESPACE;
|
||||||
|
|
||||||
|
SYSTEM_THREAD(ENABLED);
|
||||||
|
|
||||||
|
#if FASTLED_VERSION < 3001000
|
||||||
|
#error "Requires FastLED 3.1 or later; check github for latest code."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// WiFi
|
||||||
|
#define timeout 30000
|
||||||
|
#define reconnect_delay 5000
|
||||||
|
|
||||||
|
// UDP
|
||||||
|
#define SERVER_PORT 49692
|
||||||
|
#define DISCOVERY_PORT 49692
|
||||||
|
UDP client;
|
||||||
|
IPAddress multicastIP(239, 15, 18, 2);
|
||||||
|
|
||||||
|
// ORB
|
||||||
|
unsigned int orbID = 1;
|
||||||
|
|
||||||
|
#define SERIAL_DEBUG 0 // Serial debugging (0=Off, 1=On)
|
||||||
|
|
||||||
|
// LED
|
||||||
|
#define DATA_PIN 6
|
||||||
|
#define NUM_LEDS 24
|
||||||
|
CRGB leds[NUM_LEDS];
|
||||||
|
|
||||||
|
// UDP
|
||||||
|
#define BUFFER_SIZE 8 // 5 + 3 channels for 1 LED
|
||||||
|
#define BUFFER_SIZE_DISCOVERY 5
|
||||||
|
#define TIMEOUT_MS 500
|
||||||
|
uint8_t buffer[BUFFER_SIZE];
|
||||||
|
uint8_t bufferDiscovery[BUFFER_SIZE_DISCOVERY];
|
||||||
|
unsigned long lastWiFiCheck = 0;
|
||||||
|
|
||||||
|
// SMOOTHING
|
||||||
|
#define SMOOTH_STEPS 50 // Steps to take for smoothing colors
|
||||||
|
#define SMOOTH_DELAY 4 // Delay between smoothing steps
|
||||||
|
#define SMOOTH_BLOCK 0 // Block incoming colors while smoothing
|
||||||
|
|
||||||
|
byte nextColor[3];
|
||||||
|
byte prevColor[3];
|
||||||
|
byte currentColor[3];
|
||||||
|
byte smoothStep = SMOOTH_STEPS;
|
||||||
|
unsigned long smoothMillis;
|
||||||
|
|
||||||
|
// CUSTOM COLOR CORRECTIONS
|
||||||
|
#define RED_CORRECTION 255
|
||||||
|
#define GREEN_CORRECTION 255
|
||||||
|
#define BLUE_CORRECTION 255
|
||||||
|
#include "Particle.h"
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// Leds - choose one correction method
|
||||||
|
// 1 - Custom color correction
|
||||||
|
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS).setCorrection(CRGB(RED_CORRECTION, GREEN_CORRECTION, BLUE_CORRECTION));
|
||||||
|
|
||||||
|
// Set color
|
||||||
|
//setColor(40, 21, 0);
|
||||||
|
|
||||||
|
// Uncomment the below lines to dim the single built-in led to 2%
|
||||||
|
::RGB.control(true);
|
||||||
|
::RGB.brightness(2);
|
||||||
|
::RGB.control(false);
|
||||||
|
|
||||||
|
// WiFi
|
||||||
|
lastWiFiCheck = millis();
|
||||||
|
initWiFi();
|
||||||
|
|
||||||
|
// 2 - FastLED predefined color correction
|
||||||
|
//FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS).setCorrection(TypicalSMD5050);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initWiFi()
|
||||||
|
{
|
||||||
|
// Delays added UDP client creation, required for WiFi reconnects as takes a bit for resources to be full available
|
||||||
|
|
||||||
|
// Wait for WiFi connection
|
||||||
|
delay(500);
|
||||||
|
waitFor(WiFi.ready, timeout);
|
||||||
|
delay(reconnect_delay);
|
||||||
|
|
||||||
|
// Multicast UDP
|
||||||
|
if(WiFi.ready())
|
||||||
|
{
|
||||||
|
#if SERIAL_DEBUG == 1
|
||||||
|
Serial.println("");
|
||||||
|
Serial.print(F("Connected to "));
|
||||||
|
Serial.println(WiFi.SSID());
|
||||||
|
Serial.print(F("IP address: "));
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
client.begin(SERVER_PORT);
|
||||||
|
delay(reconnect_delay);
|
||||||
|
client.joinMulticast(multicastIP);
|
||||||
|
|
||||||
|
#if SERIAL_DEBUG == 1
|
||||||
|
Serial.print(F("Listening to Multicast at "));
|
||||||
|
Serial.print(multicastIP);
|
||||||
|
Serial.print(F(":"));
|
||||||
|
Serial.println(SERVER_PORT);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
if (Network.listening())
|
||||||
|
{
|
||||||
|
// If we are in listening mode (blinking dark blue), don't
|
||||||
|
// output by USB serial, because it can conflict with
|
||||||
|
// serial commands.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(WiFi.ready() == false) {
|
||||||
|
#if SERIAL_DEBUG == 1
|
||||||
|
Serial.print(F("Lost connection to "));
|
||||||
|
Serial.print(WiFi.SSID());
|
||||||
|
Serial.println(F("."));
|
||||||
|
Serial.println(F("Trying to reconnect."));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
initWiFi();
|
||||||
|
}
|
||||||
|
|
||||||
|
int packetSize = client.parsePacket();
|
||||||
|
|
||||||
|
if(packetSize == BUFFER_SIZE){
|
||||||
|
|
||||||
|
#if SERIAL_DEBUG == 1
|
||||||
|
Serial.print(F("Packet size: "));
|
||||||
|
Serial.println(packetSize);
|
||||||
|
#endif
|
||||||
|
client.read(buffer, BUFFER_SIZE);
|
||||||
|
//client.flush();
|
||||||
|
|
||||||
|
#if SERIAL_DEBUG == 1
|
||||||
|
Serial.print(F("UDP Packet from "));
|
||||||
|
Serial.println(client.remoteIP());
|
||||||
|
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||||
|
{
|
||||||
|
Serial.print(buffer[i]);
|
||||||
|
Serial.print(F(" "));
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
#endif
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
// Look for 0xC0FFEE
|
||||||
|
if(buffer[i++] == 0xC0 && buffer[i++] == 0xFF && buffer[i++] == 0xEE)
|
||||||
|
{
|
||||||
|
byte commandOptions = buffer[i++];
|
||||||
|
byte rcvOrbID = buffer[i++];
|
||||||
|
|
||||||
|
byte red = buffer[i++];
|
||||||
|
byte green = buffer[i++];
|
||||||
|
byte blue = buffer[i++];
|
||||||
|
|
||||||
|
// Command options
|
||||||
|
// 1 = force off
|
||||||
|
// 2 = use lamp smoothing and validate by Orb ID
|
||||||
|
// 4 = validate by Orb ID
|
||||||
|
// 8 = discovery
|
||||||
|
// 9 = light-up Orb to identify by Orb ID
|
||||||
|
if(commandOptions == 1)
|
||||||
|
{
|
||||||
|
// Orb ID 0 = turn off all lights
|
||||||
|
// Otherwise turn off selectively
|
||||||
|
if(rcvOrbID == 0 || rcvOrbID == orbID)
|
||||||
|
{
|
||||||
|
smoothStep = SMOOTH_STEPS;
|
||||||
|
forceLedsOFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(commandOptions == 2)
|
||||||
|
{
|
||||||
|
if(rcvOrbID != orbID)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSmoothColor(red, green, blue);
|
||||||
|
}
|
||||||
|
else if(commandOptions == 4)
|
||||||
|
{
|
||||||
|
if(rcvOrbID != orbID)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothStep = SMOOTH_STEPS;
|
||||||
|
setColor(red, green, blue);
|
||||||
|
setSmoothColor(red, green, blue);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(commandOptions == 8)
|
||||||
|
{
|
||||||
|
#if SERIAL_DEBUG == 1
|
||||||
|
Serial.print(F("Announce myself. OrbID: "));
|
||||||
|
Serial.println(orbID);
|
||||||
|
#endif
|
||||||
|
// Respond to remote IP address with Orb ID
|
||||||
|
IPAddress remoteIP = client.remoteIP();
|
||||||
|
bufferDiscovery[0] = orbID;
|
||||||
|
|
||||||
|
client.sendPacket(bufferDiscovery, BUFFER_SIZE_DISCOVERY, remoteIP, DISCOVERY_PORT);
|
||||||
|
|
||||||
|
// Clear buffer
|
||||||
|
memset(bufferDiscovery, 0, sizeof(bufferDiscovery));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(commandOptions == 9)
|
||||||
|
{
|
||||||
|
if(rcvOrbID == 0 || rcvOrbID == orbID)
|
||||||
|
{
|
||||||
|
#if SERIAL_DEBUG == 1
|
||||||
|
Serial.print(F("Identify myself. OrbID: "));
|
||||||
|
Serial.println(orbID);
|
||||||
|
#endif
|
||||||
|
identify();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if(packetSize > 0){
|
||||||
|
// Got malformed packet
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smoothStep < SMOOTH_STEPS && millis() >= (smoothMillis + (SMOOTH_DELAY * (smoothStep + 1))))
|
||||||
|
{
|
||||||
|
smoothColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set color
|
||||||
|
void setColor(byte red, byte green, byte blue)
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < NUM_LEDS; i++)
|
||||||
|
{
|
||||||
|
leds[i] = CRGB(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
FastLED.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set a new color to smooth to
|
||||||
|
void setSmoothColor(byte red, byte green, byte blue)
|
||||||
|
{
|
||||||
|
if (smoothStep == SMOOTH_STEPS || SMOOTH_BLOCK == 0)
|
||||||
|
{
|
||||||
|
if (nextColor[0] == red && nextColor[1] == green && nextColor[2] == blue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevColor[0] = currentColor[0];
|
||||||
|
prevColor[1] = currentColor[1];
|
||||||
|
prevColor[2] = currentColor[2];
|
||||||
|
|
||||||
|
nextColor[0] = red;
|
||||||
|
nextColor[1] = green;
|
||||||
|
nextColor[2] = blue;
|
||||||
|
|
||||||
|
smoothMillis = millis();
|
||||||
|
smoothStep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display one step to the next color
|
||||||
|
void smoothColor()
|
||||||
|
{
|
||||||
|
smoothStep++;
|
||||||
|
currentColor[0] = prevColor[0] + (((nextColor[0] - prevColor[0]) * smoothStep) / SMOOTH_STEPS);
|
||||||
|
currentColor[1] = prevColor[1] + (((nextColor[1] - prevColor[1]) * smoothStep) / SMOOTH_STEPS);
|
||||||
|
currentColor[2] = prevColor[2] + (((nextColor[2] - prevColor[2]) * smoothStep) / SMOOTH_STEPS);
|
||||||
|
|
||||||
|
setColor(currentColor[0], currentColor[1], currentColor[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force all leds OFF
|
||||||
|
void forceLedsOFF()
|
||||||
|
{
|
||||||
|
setColor(0,0,0);
|
||||||
|
clearSmoothColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear smooth color byte arrays
|
||||||
|
void clearSmoothColors()
|
||||||
|
{
|
||||||
|
memset(prevColor, 0, sizeof(prevColor));
|
||||||
|
memset(currentColor, 0, sizeof(nextColor));
|
||||||
|
memset(nextColor, 0, sizeof(nextColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
void identify()
|
||||||
|
{
|
||||||
|
for (byte i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
FastLED.showColor(CRGB::LemonChiffon);
|
||||||
|
delay(500);
|
||||||
|
FastLED.showColor(CRGB::Black);
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
}
|
@ -546,6 +546,8 @@
|
|||||||
"edt_dev_spec_baudrate_title": "Baudrate",
|
"edt_dev_spec_baudrate_title": "Baudrate",
|
||||||
"edt_dev_spec_blackLightsTimeout_title": "Signal detection timeout on black",
|
"edt_dev_spec_blackLightsTimeout_title": "Signal detection timeout on black",
|
||||||
"edt_dev_spec_brightnessFactor_title": "Brightness factor",
|
"edt_dev_spec_brightnessFactor_title": "Brightness factor",
|
||||||
|
"edt_dev_spec_brightnessMax_title": "Brightness maximum",
|
||||||
|
"edt_dev_spec_brightnessMin_title": "Brightness minimum",
|
||||||
"edt_dev_spec_brightnessOverwrite_title": "Overwrite brightness",
|
"edt_dev_spec_brightnessOverwrite_title": "Overwrite brightness",
|
||||||
"edt_dev_spec_brightnessThreshold_title": "Signal detection brightness minimum",
|
"edt_dev_spec_brightnessThreshold_title": "Signal detection brightness minimum",
|
||||||
"edt_dev_spec_brightness_title": "Brightness",
|
"edt_dev_spec_brightness_title": "Brightness",
|
||||||
|
@ -1631,7 +1631,10 @@ function saveLedConfig(genDefLayout = false) {
|
|||||||
case "cololight":
|
case "cololight":
|
||||||
|
|
||||||
var host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
var host = conf_editor.getEditor("root.specificOptions.host").getValue();
|
||||||
result.smoothing = { enable: false };
|
if (window.serverConfig.device.type !== ledType) {
|
||||||
|
//smoothing off, if new device
|
||||||
|
result.smoothing = { enable: false };
|
||||||
|
}
|
||||||
|
|
||||||
if (genDefLayout === true) {
|
if (genDefLayout === true) {
|
||||||
|
|
||||||
@ -1667,7 +1670,11 @@ function saveLedConfig(genDefLayout = false) {
|
|||||||
|
|
||||||
case "nanoleaf":
|
case "nanoleaf":
|
||||||
case "wled":
|
case "wled":
|
||||||
result.smoothing = { enable: false };
|
case "yeelight":
|
||||||
|
if (window.serverConfig.device.type !== ledType) {
|
||||||
|
//smoothing off, if new device
|
||||||
|
result.smoothing = { enable: false };
|
||||||
|
}
|
||||||
|
|
||||||
case "adalight":
|
case "adalight":
|
||||||
case "atmo":
|
case "atmo":
|
||||||
|
@ -171,7 +171,7 @@ function initLanguageSelection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateUiOnInstance(inst) {
|
function updateUiOnInstance(inst) {
|
||||||
$("#active_instance_friendly_name").text(window.serverInfo.instance[inst].friendly_name);
|
$("#active_instance_friendly_name").text(getInstanceNameByIndex(inst));
|
||||||
if (window.serverInfo.instance.filter(entry => entry.running).length > 1) {
|
if (window.serverInfo.instance.filter(entry => entry.running).length > 1) {
|
||||||
$('#btn_hypinstanceswitch').toggle(true);
|
$('#btn_hypinstanceswitch').toggle(true);
|
||||||
$('#active_instance_dropdown').prop('disabled', false);
|
$('#active_instance_dropdown').prop('disabled', false);
|
||||||
|
@ -1126,15 +1126,19 @@ function beginWizardHue() {
|
|||||||
d.useEntertainmentAPI = false;
|
d.useEntertainmentAPI = false;
|
||||||
d.hardwareLedCount = finalLightIds.length;
|
d.hardwareLedCount = finalLightIds.length;
|
||||||
d.verbose = false;
|
d.verbose = false;
|
||||||
//smoothing off
|
if (window.serverConfig.device.type !== d.type) {
|
||||||
sc.smoothing.enable = false;
|
//smoothing off, if new device
|
||||||
|
sc.smoothing = { enable: false };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hueType == 'philipshueentertainment') {
|
if (hueType == 'philipshueentertainment') {
|
||||||
d.useEntertainmentAPI = true;
|
d.useEntertainmentAPI = true;
|
||||||
d.hardwareLedCount = groupLights.length;
|
d.hardwareLedCount = groupLights.length;
|
||||||
//smoothing on
|
if (window.serverConfig.device.type !== d.type) {
|
||||||
sc.smoothing.enable = true;
|
//smoothing on, if new device
|
||||||
|
sc.smoothing = { enable: true };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.serverConfig.device = d;
|
window.serverConfig.device = d;
|
||||||
@ -1430,6 +1434,8 @@ function beginWizardYeelight() {
|
|||||||
window.serverConfig.leds = yeelightLedConfig;
|
window.serverConfig.leds = yeelightLedConfig;
|
||||||
|
|
||||||
//LED device config
|
//LED device config
|
||||||
|
var currentDeviceType = window.serverConfig.device.type;
|
||||||
|
|
||||||
//Start with a clean configuration
|
//Start with a clean configuration
|
||||||
var d = {};
|
var d = {};
|
||||||
|
|
||||||
@ -1454,9 +1460,10 @@ function beginWizardYeelight() {
|
|||||||
|
|
||||||
window.serverConfig.device = d;
|
window.serverConfig.device = d;
|
||||||
|
|
||||||
//smoothing off
|
if (currentDeviceType !== d.type) {
|
||||||
if (!(window.serverConfig.smoothing == null))
|
//smoothing off, if new device
|
||||||
window.serverConfig.smoothing.enable = false;
|
window.serverConfig.smoothing = { enable: false };
|
||||||
|
}
|
||||||
|
|
||||||
requestWriteConfig(window.serverConfig, true);
|
requestWriteConfig(window.serverConfig, true);
|
||||||
resetWizard();
|
resetWizard();
|
||||||
|
@ -113,10 +113,8 @@ void LinearColorSmoothing::handleSettingsUpdate(settings::type type, const QJson
|
|||||||
if (type == settings::type::SMOOTHING)
|
if (type == settings::type::SMOOTHING)
|
||||||
{
|
{
|
||||||
QJsonObject obj = config.object();
|
QJsonObject obj = config.object();
|
||||||
if (enabled() != obj["enable"].toBool(true))
|
|
||||||
{
|
setEnable(obj["enable"].toBool(_enabled));
|
||||||
setEnable(obj["enable"].toBool(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
SmoothingCfg cfg(false,
|
SmoothingCfg cfg(false,
|
||||||
static_cast<int64_t>(obj[SETTINGS_KEY_SETTLING_TIME].toInt(DEFAULT_SETTLINGTIME)),
|
static_cast<int64_t>(obj[SETTINGS_KEY_SETTLING_TIME].toInt(DEFAULT_SETTLINGTIME)),
|
||||||
|
Loading…
Reference in New Issue
Block a user