Loxone support added (#1185)
* A separate socket for UDP api has been added. This uses the same API as HTML. Commands for Loxone were added to the API. * html files for udp api newly generated * codm pixel controller board configurations added to platformio.ini file * Parser for LX/LY commands adapted. Calculation of the values corrected. Segment handling for LX/LY removed. * Lox parser moved to own file. Lox parser added to the JSON api. Within a segment LX and LY are now supported. * serial port removed * F() macro added Co-authored-by: Marius Groos <marius.groos@codm.de>
This commit is contained in:
parent
cac974b8e1
commit
b10ab358da
@ -375,3 +375,43 @@ build_flags = ${common.build_flags_esp8266} ${common.debug_flags} ${common.build
|
|||||||
extends = env:esp32dev
|
extends = env:esp32dev
|
||||||
build_type = debug
|
build_type = debug
|
||||||
build_flags = ${common.build_flags_esp32} ${common.debug_flags} ${common.build_flags_all_features}
|
build_flags = ${common.build_flags_esp32} ${common.debug_flags} ${common.build_flags_all_features}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# codm pixel controller board configurations
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[env:codm-controller-0.4]
|
||||||
|
board = esp_wroom_02
|
||||||
|
platform = ${common.platform_wled_default}
|
||||||
|
board_build.ldscript = ${common.ldscript_2m1m}
|
||||||
|
build_flags = ${common.build_flags_esp8266} -D LEDPIN=3
|
||||||
|
|
||||||
|
[env:codm-controller-0.4-WS2801]
|
||||||
|
board = esp_wroom_02
|
||||||
|
platform = ${common.platform_latest}
|
||||||
|
board_build.ldscript = ${common.ldscript_2m1m}
|
||||||
|
build_flags = ${common.build_flags_esp8266} -D USE_WS2801 -D CLKPIN=13 -D DATAPIN=3
|
||||||
|
|
||||||
|
[env:codm-controller-0.4-APA102]
|
||||||
|
board = esp_wroom_02
|
||||||
|
platform = ${common.platform_latest}
|
||||||
|
board_build.ldscript = ${common.ldscript_2m1m}
|
||||||
|
build_flags = ${common.build_flags_esp8266} -D USE_APA102 -D CLKPIN=13 -D DATAPIN=3
|
||||||
|
|
||||||
|
[env:codm-controller-0.5]
|
||||||
|
board = esp_wroom_02
|
||||||
|
platform = ${common.platform_wled_default}
|
||||||
|
board_build.ldscript = ${common.ldscript_2m1m}
|
||||||
|
build_flags = ${common.build_flags_esp8266}
|
||||||
|
|
||||||
|
[env:codm-controller-0.5-WS2801]
|
||||||
|
board = esp_wroom_02
|
||||||
|
platform = ${common.platform_latest}
|
||||||
|
board_build.ldscript = ${common.ldscript_2m1m}
|
||||||
|
build_flags = ${common.build_flags_esp8266} -D USE_WS2801 #-D CLKPIN=0 -D DATAPIN=2
|
||||||
|
|
||||||
|
[env:codm-controller-0.5-APA102]
|
||||||
|
board = esp_wroom_02
|
||||||
|
platform = ${common.platform_latest}
|
||||||
|
board_build.ldscript = ${common.ldscript_2m1m}
|
||||||
|
build_flags = ${common.build_flags_esp8266} -D USE_APA102 #-D CLKPIN=0 -D DATAPIN=2
|
||||||
|
@ -38,6 +38,10 @@ Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
|||||||
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
||||||
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
||||||
Send notifications twice: <input type="checkbox" name="S2">
|
Send notifications twice: <input type="checkbox" name="S2">
|
||||||
|
<h3>UDP Api</h3>
|
||||||
|
Enable UDP Api: <input type="checkbox" name="UAE"><br>
|
||||||
|
Port: <input name="UAP" type="number" min="1" max="65535" class="d5"><br>
|
||||||
|
<i>Reboot required to apply changes. </i>
|
||||||
<h3>Realtime</h3>
|
<h3>Realtime</h3>
|
||||||
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
|
||||||
<i>Network DMX input</i><br>
|
<i>Network DMX input</i><br>
|
||||||
|
@ -223,4 +223,7 @@ void sappend(char stype, const char* key, int val);
|
|||||||
void sappends(char stype, const char* key, char* val);
|
void sappends(char stype, const char* key, char* val);
|
||||||
void getSettingsJS(byte subPage, char* dest);
|
void getSettingsJS(byte subPage, char* dest);
|
||||||
|
|
||||||
|
//lx_parser.cpp
|
||||||
|
bool parseLx(int lxValue, int rgbw[4]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -167,163 +167,163 @@ const char PAGE_settings_dmx[] PROGMEM = R"=====()=====";
|
|||||||
// Autogenerated from wled00/data/settings_ui.htm, do not edit!!
|
// Autogenerated from wled00/data/settings_ui.htm, do not edit!!
|
||||||
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport"
|
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport"
|
||||||
content="width=500"><title>UI Settings</title><script>var d = document;
|
content="width=500"><title>UI Settings</title><script>var d = document;
|
||||||
var initial_ds, initial_st;
|
var initial_ds, initial_st;
|
||||||
var sett = null;
|
var sett = null;
|
||||||
var l = {
|
var l = {
|
||||||
"comp":{
|
"comp":{
|
||||||
"labels":"Show button labels",
|
"labels":"Show button labels",
|
||||||
"colors":{
|
"colors":{
|
||||||
"LABEL":"Color selection methods",
|
"LABEL":"Color selection methods",
|
||||||
"picker": "Color Wheel",
|
"picker": "Color Wheel",
|
||||||
"rgb": "RGB sliders",
|
"rgb": "RGB sliders",
|
||||||
"quick": "Quick color selectors",
|
"quick": "Quick color selectors",
|
||||||
"hex": "HEX color input"
|
"hex": "HEX color input"
|
||||||
},
|
},
|
||||||
"pcmbot": "Show bottom tab bar in PC mode"
|
"pcmbot": "Show bottom tab bar in PC mode"
|
||||||
},
|
},
|
||||||
"theme":{
|
"theme":{
|
||||||
"alpha": {
|
"alpha": {
|
||||||
"bg":"Background opacity",
|
"bg":"Background opacity",
|
||||||
"tab":"Button opacity"
|
"tab":"Button opacity"
|
||||||
},
|
},
|
||||||
"bg":{
|
"bg":{
|
||||||
"url":"BG image URL"
|
"url":"BG image URL"
|
||||||
},
|
},
|
||||||
"color":{
|
"color":{
|
||||||
"bg":"BG HEX color"
|
"bg":"BG HEX color"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
function gId(s)
|
||||||
|
{
|
||||||
|
return d.getElementById(s);
|
||||||
|
}
|
||||||
|
function isObject(item) {
|
||||||
|
return (item && typeof item === 'object' && !Array.isArray(item));
|
||||||
|
}
|
||||||
|
function set(path, obj, val) {
|
||||||
|
var tar = obj;
|
||||||
|
var pList = path.split('_');
|
||||||
|
var len = pList.length;
|
||||||
|
for(var i = 0; i < len-1; i++) {
|
||||||
|
var elem = pList[i];
|
||||||
|
if( !tar[elem] ) tar[elem] = {}
|
||||||
|
tar = tar[elem];
|
||||||
|
}
|
||||||
|
|
||||||
};
|
tar[pList[len-1]] = val;
|
||||||
function gId(s)
|
}
|
||||||
{
|
|
||||||
return d.getElementById(s);
|
|
||||||
}
|
|
||||||
function isObject(item) {
|
|
||||||
return (item && typeof item === 'object' && !Array.isArray(item));
|
|
||||||
}
|
|
||||||
function set(path, obj, val) {
|
|
||||||
var tar = obj;
|
|
||||||
var pList = path.split('_');
|
|
||||||
var len = pList.length;
|
|
||||||
for(var i = 0; i < len-1; i++) {
|
|
||||||
var elem = pList[i];
|
|
||||||
if( !tar[elem] ) tar[elem] = {}
|
|
||||||
tar = tar[elem];
|
|
||||||
}
|
|
||||||
|
|
||||||
tar[pList[len-1]] = val;
|
function addRec(s, path = "", label = null)
|
||||||
}
|
{
|
||||||
|
var str = "";
|
||||||
|
for (i in s)
|
||||||
|
{
|
||||||
|
var fk = path + (path?'_':'') + i;
|
||||||
|
if (isObject(s[i])) {
|
||||||
|
if (label && label[i] && label[i]["LABEL"]) str += `<h3>${label[i]["LABEL"]}</h3>`;
|
||||||
|
str += addRec(s[i], fk, label? label[i] : null);
|
||||||
|
} else {
|
||||||
|
var lb = fk;
|
||||||
|
if (label && label[i]) lb = label[i];
|
||||||
|
else if (s[i+'LABEL']) lb = s[i+'LABEL'];
|
||||||
|
if (i.indexOf('LABEL') > 0) continue;
|
||||||
|
var t = typeof s[i];
|
||||||
|
if (gId(fk)) { //already exists
|
||||||
|
if(t === 'boolean')
|
||||||
|
{
|
||||||
|
gId(fk).checked = s[i];
|
||||||
|
} else {
|
||||||
|
gId(fk).value = s[i];
|
||||||
|
}
|
||||||
|
if (gId(fk).previousElementSibling.matches('.l')) {
|
||||||
|
gId(fk).previousElementSibling.innerHTML = lb;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(t === 'boolean')
|
||||||
|
{
|
||||||
|
str += `${lb}: <input class="agi cb" type="checkbox" id=${fk} ${s[i]?"checked":""}><br>`;
|
||||||
|
} else if (t === 'number')
|
||||||
|
{
|
||||||
|
str += `${lb}: <input class="agi" type="number" id=${fk} value=${s[i]}><br>`;
|
||||||
|
} else if (t === 'string')
|
||||||
|
{
|
||||||
|
str += `${lb}:<br><input class="agi" id=${fk} value=${s[i]}><br>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
function addRec(s, path = "", label = null)
|
function genForm(s) {
|
||||||
{
|
var str = "";
|
||||||
var str = "";
|
str = addRec(s,"",l);
|
||||||
for (i in s)
|
|
||||||
{
|
gId('gen').innerHTML = str;
|
||||||
var fk = path + (path?'_':'') + i;
|
}
|
||||||
if (isObject(s[i])) {
|
function GetLS()
|
||||||
if (label && label[i] && label[i]["LABEL"]) str += `<h3>${label[i]["LABEL"]}</h3>`;
|
{
|
||||||
str += addRec(s[i], fk, label? label[i] : null);
|
sett = localStorage.getItem('wledUiCfg');
|
||||||
} else {
|
if (!sett) gId('lserr').style.display = "inline";
|
||||||
var lb = fk;
|
try {
|
||||||
if (label && label[i]) lb = label[i];
|
sett = JSON.parse(sett);
|
||||||
else if (s[i+'LABEL']) lb = s[i+'LABEL'];
|
} catch (e) {
|
||||||
if (i.indexOf('LABEL') > 0) continue;
|
sett = {};
|
||||||
var t = typeof s[i];
|
gId('lserr').style.display = "inline";
|
||||||
if (gId(fk)) { //already exists
|
gId('lserr').innerHTML = "⚠ Settings JSON parsing failed. (" + e + ")";
|
||||||
if(t === 'boolean')
|
}
|
||||||
{
|
genForm(sett);
|
||||||
gId(fk).checked = s[i];
|
gId('dm').checked = (gId('theme_base').value === 'light');
|
||||||
} else {
|
}
|
||||||
gId(fk).value = s[i];
|
|
||||||
}
|
function SetLS()
|
||||||
if (gId(fk).previousElementSibling.matches('.l')) {
|
{
|
||||||
gId(fk).previousElementSibling.innerHTML = lb;
|
var l = d.querySelectorAll('.agi');
|
||||||
}
|
for (var i = 0; i < l.length; i++) {
|
||||||
} else {
|
var e = l[i];
|
||||||
if(t === 'boolean')
|
var val = e.classList.contains('cb') ? e.checked : e.value;
|
||||||
{
|
set(e.id, sett, val);
|
||||||
str += `${lb}: <input class="agi cb" type="checkbox" id=${fk} ${s[i]?"checked":""}><br>`;
|
console.log(`${e.id} set to ${val}`);
|
||||||
} else if (t === 'number')
|
}
|
||||||
{
|
try {
|
||||||
str += `${lb}: <input class="agi" type="number" id=${fk} value=${s[i]}><br>`;
|
localStorage.setItem('wledUiCfg', JSON.stringify(sett));
|
||||||
} else if (t === 'string')
|
gId('lssuc').style.display = "inline";
|
||||||
{
|
} catch (e) {
|
||||||
str += `${lb}:<br><input class="agi" id=${fk} value=${s[i]}><br>`;
|
gId('lssuc').style.display = "none";
|
||||||
}
|
gId('lserr').style.display = "inline";
|
||||||
}
|
gId('lserr').innerHTML = "⚠ Settings JSON saving failed. (" + e + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return str;
|
|
||||||
}
|
function Save() {
|
||||||
|
SetLS();
|
||||||
function genForm(s) {
|
if (d.Sf.DS.value != initial_ds || d.Sf.ST.checked != initial_st) d.Sf.submit();
|
||||||
var str = "";
|
}
|
||||||
str = addRec(s,"",l);
|
|
||||||
|
function S()
|
||||||
gId('gen').innerHTML = str;
|
{
|
||||||
}
|
GetV();
|
||||||
function GetLS()
|
initial_ds = d.Sf.DS.value;
|
||||||
{
|
initial_st = d.Sf.ST.checked;
|
||||||
sett = localStorage.getItem('wledUiCfg');
|
GetLS();
|
||||||
if (!sett) gId('lserr').style.display = "inline";
|
}
|
||||||
try {
|
function H()
|
||||||
sett = JSON.parse(sett);
|
{
|
||||||
} catch (e) {
|
window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");
|
||||||
sett = {};
|
}
|
||||||
gId('lserr').style.display = "inline";
|
function B()
|
||||||
gId('lserr').innerHTML = "⚠ Settings JSON parsing failed. (" + e + ")";
|
{
|
||||||
}
|
window.open("/settings","_self");
|
||||||
genForm(sett);
|
}
|
||||||
gId('dm').checked = (gId('theme_base').value === 'light');
|
function UI()
|
||||||
}
|
{
|
||||||
|
gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
|
||||||
function SetLS()
|
var f = gId('theme_base');
|
||||||
{
|
if (f) f.value = (gId('dm').checked) ? 'light':'dark';
|
||||||
var l = d.querySelectorAll('.agi');
|
}
|
||||||
for (var i = 0; i < l.length; i++) {
|
function GetV() {var d=document;
|
||||||
var e = l[i];
|
|
||||||
var val = e.classList.contains('cb') ? e.checked : e.value;
|
|
||||||
set(e.id, sett, val);
|
|
||||||
console.log(`${e.id} set to ${val}`);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
localStorage.setItem('wledUiCfg', JSON.stringify(sett));
|
|
||||||
gId('lssuc').style.display = "inline";
|
|
||||||
} catch (e) {
|
|
||||||
gId('lssuc').style.display = "none";
|
|
||||||
gId('lserr').style.display = "inline";
|
|
||||||
gId('lserr').innerHTML = "⚠ Settings JSON saving failed. (" + e + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Save() {
|
|
||||||
SetLS();
|
|
||||||
if (d.Sf.DS.value != initial_ds || d.Sf.ST.checked != initial_st) d.Sf.submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function S()
|
|
||||||
{
|
|
||||||
GetV();
|
|
||||||
initial_ds = d.Sf.DS.value;
|
|
||||||
initial_st = d.Sf.ST.checked;
|
|
||||||
GetLS();
|
|
||||||
}
|
|
||||||
function H()
|
|
||||||
{
|
|
||||||
window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");
|
|
||||||
}
|
|
||||||
function B()
|
|
||||||
{
|
|
||||||
window.open("/settings","_self");
|
|
||||||
}
|
|
||||||
function UI()
|
|
||||||
{
|
|
||||||
gId('idonthateyou').style.display = (gId('dm').checked) ? 'inline':'none';
|
|
||||||
var f = gId('theme_base');
|
|
||||||
if (f) f.value = (gId('dm').checked) ? 'light':'dark';
|
|
||||||
}
|
|
||||||
function GetV() {var d=document;
|
|
||||||
%CSS%%SCSS%</head><body onload="S()">
|
%CSS%%SCSS%</head><body onload="S()">
|
||||||
<form id="form_s" name="Sf" method="post"><div
|
<form id="form_s" name="Sf" method="post"><div
|
||||||
style="position:sticky;top:0;background-color:#222"><div class="helpB"><button
|
style="position:sticky;top:0;background-color:#222"><div class="helpB"><button
|
||||||
@ -377,21 +377,24 @@ type="checkbox" name="RX">Effects<br>Send notifications on direct change: <input
|
|||||||
type="checkbox" name="SB"><br>Send Alexa notifications: <input type="checkbox"
|
type="checkbox" name="SB"><br>Send Alexa notifications: <input type="checkbox"
|
||||||
name="SA"><br>Send Philips Hue change notifications: <input type="checkbox"
|
name="SA"><br>Send Philips Hue change notifications: <input type="checkbox"
|
||||||
name="SH"><br>Send Macro notifications: <input type="checkbox" name="SM"><br>
|
name="SH"><br>Send Macro notifications: <input type="checkbox" name="SM"><br>
|
||||||
Send notifications twice: <input type="checkbox" name="S2"><h3>Realtime</h3>
|
Send notifications twice: <input type="checkbox" name="S2"><h3>UDP Api</h3>
|
||||||
Receive UDP realtime: <input type="checkbox" name="RD"><br><br><i>
|
Enable UDP Api: <input type="checkbox" name="UAE"><br>Port: <input name="UAP"
|
||||||
Network DMX input</i><br>Type: <select name="DI" onchange="SP(),adj()"><option
|
type="number" min="1" max="65535" class="d5"><br><i>
|
||||||
value="5568">E1.31 (sACN)</option><option value="6454">Art-Net</option><option
|
Reboot required to apply changes.</i><h3>Realtime</h3>Receive UDP realtime:
|
||||||
value="0" selected="selected">Custom port</option></select><br><div id="xp">
|
<input type="checkbox" name="RD"><br><br><i>Network DMX input</i><br>Type:
|
||||||
Port: <input name="EP" type="number" min="1" max="65535" value="5568"
|
<select name="DI" onchange="SP(),adj()"><option value="5568">E1.31 (sACN)
|
||||||
class="d5" required><br></div>Multicast: <input type="checkbox" name="EM"><br>
|
</option><option value="6454">Art-Net</option><option value="0"
|
||||||
Start universe: <input name="EU" type="number" min="0" max="63999" required><br>
|
selected="selected">Custom port</option></select><br><div id="xp">Port: <input
|
||||||
<i>Reboot required.</i> Check out <a href="https://github.com/ahodges9/LedFx"
|
name="EP" type="number" min="1" max="65535" value="5568" class="d5" required>
|
||||||
target="_blank">LedFx</a>!<br>Skip out-of-sequence packets: <input
|
<br></div>Multicast: <input type="checkbox" name="EM"><br>Start universe: <input
|
||||||
type="checkbox" name="ES"><br>DMX start address: <input name="DA" type="number"
|
name="EU" type="number" min="0" max="63999" required><br><i>Reboot required.
|
||||||
min="0" max="510" required><br>DMX mode: <select name="DM"><option value="0">
|
</i> Check out <a href="https://github.com/ahodges9/LedFx" target="_blank">LedFx
|
||||||
Disabled</option><option value="1">Single RGB</option><option value="2">
|
</a>!<br>Skip out-of-sequence packets: <input type="checkbox" name="ES"><br>
|
||||||
Single DRGB</option><option value="3">Effect</option><option value="4">Multi RGB
|
DMX start address: <input name="DA" type="number" min="0" max="510" required>
|
||||||
</option><option value="5">Dimmer + Multi RGB</option></select><br><a
|
<br>DMX mode: <select name="DM"><option value="0">Disabled</option><option
|
||||||
|
value="1">Single RGB</option><option value="2">Single DRGB</option><option
|
||||||
|
value="3">Effect</option><option value="4">Multi RGB</option><option value="5">
|
||||||
|
Dimmer + Multi RGB</option></select><br><a
|
||||||
href="https://github.com/Aircoookie/WLED/wiki/E1.31-DMX" target="_blank">
|
href="https://github.com/Aircoookie/WLED/wiki/E1.31-DMX" target="_blank">
|
||||||
E1.31 info</a><br>Timeout: <input name="ET" type="number" min="1" max="65000"
|
E1.31 info</a><br>Timeout: <input name="ET" type="number" min="1" max="65000"
|
||||||
required> ms<br>Force max brightness: <input type="checkbox" name="FB"><br>
|
required> ms<br>Force max brightness: <input type="checkbox" name="FB"><br>
|
||||||
|
2933
wled00/html_ui.h
2933
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -55,6 +55,58 @@ void deserializeSegment(JsonObject elem, byte it)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lx parser
|
||||||
|
int lx = elem[F("lx")] | -1;
|
||||||
|
if (lx > 0) {
|
||||||
|
DEBUG_PRINT(F("LX: Lox primary = "));
|
||||||
|
DEBUG_PRINTLN(lx);
|
||||||
|
int rgbw[] = {0,0,0,0};
|
||||||
|
if (parseLx(lx, rgbw)) {
|
||||||
|
if (bri == 0) {
|
||||||
|
DEBUG_PRINTLN(F("LX: turn on"));
|
||||||
|
toggleOnOff();
|
||||||
|
}
|
||||||
|
bri = 255;
|
||||||
|
nightlightActive = false; //always disable nightlight when toggling
|
||||||
|
if (id == strip.getMainSegmentId()) {
|
||||||
|
DEBUG_PRINTLN(F("LX: main segment"));
|
||||||
|
col[0] = rgbw[0];
|
||||||
|
col[1] = rgbw[1];
|
||||||
|
col[2] = rgbw[2];
|
||||||
|
col[3] = rgbw[3];
|
||||||
|
} else {
|
||||||
|
DEBUG_PRINT(F("LX: segment "));
|
||||||
|
DEBUG_PRINTLN(id);
|
||||||
|
seg.colors[0] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int ly = elem[F("ly")] | -1;
|
||||||
|
if (ly > 0) {
|
||||||
|
DEBUG_PRINT(F("LY: Lox secondary = "));
|
||||||
|
Serial.println(ly);
|
||||||
|
int rgbw[] = {0,0,0,0};
|
||||||
|
if (parseLx(ly, rgbw)) {
|
||||||
|
if (bri == 0) {
|
||||||
|
DEBUG_PRINTLN(F("LY: turn on"));
|
||||||
|
toggleOnOff();
|
||||||
|
}
|
||||||
|
bri = 255;
|
||||||
|
nightlightActive = false; //always disable nightlight when toggling
|
||||||
|
if (id == strip.getMainSegmentId()) {
|
||||||
|
DEBUG_PRINTLN(F("LY: main segment"));
|
||||||
|
colSec[0] = rgbw[0];
|
||||||
|
colSec[1] = rgbw[1];
|
||||||
|
colSec[2] = rgbw[2];
|
||||||
|
colSec[3] = rgbw[3];
|
||||||
|
} else {
|
||||||
|
DEBUG_PRINT(F("LY: segment "));
|
||||||
|
DEBUG_PRINTLN(id);
|
||||||
|
seg.colors[1] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
//if (pal != seg.palette && pal < strip.getPaletteCount()) strip.setPalette(pal);
|
||||||
seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED));
|
seg.setOption(SEG_OPTION_SELECTED, elem[F("sel")] | seg.getOption(SEG_OPTION_SELECTED));
|
||||||
|
78
wled00/lx_parser.cpp
Normal file
78
wled00/lx_parser.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "wled.h"
|
||||||
|
|
||||||
|
bool parseLx(int lxValue, int rgbw[4])
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
float lxRed = 0;
|
||||||
|
float lxGreen = 0;
|
||||||
|
float lxBlue = 0;
|
||||||
|
|
||||||
|
if (lxValue < 200000000) {
|
||||||
|
// Loxone RGB
|
||||||
|
ok = true;
|
||||||
|
lxRed = round((lxValue % 1000) * 2.55);
|
||||||
|
lxGreen = round(((lxValue / 1000) % 1000) * 2.55);
|
||||||
|
lxBlue = round(((lxValue / 1000000) % 1000) * 2.55);
|
||||||
|
} else if ((lxValue >= 200000000) && (lxValue <= 201006500)) {
|
||||||
|
// Loxone Lumitech
|
||||||
|
ok = true;
|
||||||
|
float tmpBri = floor((lxValue - 200000000) / 10000); ;
|
||||||
|
uint16_t ct = (lxValue - 200000000) - (((uint8_t)tmpBri) * 10000);
|
||||||
|
float temp = 0;
|
||||||
|
|
||||||
|
tmpBri *= 2.55;
|
||||||
|
if (tmpBri < 0) {
|
||||||
|
tmpBri = 0;
|
||||||
|
} else if (tmpBri > 255) {
|
||||||
|
tmpBri = 255;
|
||||||
|
}
|
||||||
|
if (ct < 2700) {
|
||||||
|
ct = 2700;
|
||||||
|
} else if (ct > 6500) {
|
||||||
|
ct = 6500;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = ct / 100;
|
||||||
|
if (temp <= 66) {
|
||||||
|
lxRed = 255;
|
||||||
|
lxGreen = round(99.4708025861 * log(temp) - 161.1195681661);
|
||||||
|
if (temp <= 19) {
|
||||||
|
lxBlue = 0;
|
||||||
|
} else {
|
||||||
|
lxBlue = round(138.5177312231 * log((temp - 10)) - 305.0447927307);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lxRed = round(329.698727446 * pow((temp - 60), -0.1332047592));
|
||||||
|
lxGreen = round(288.1221695283 * pow((temp - 60), -0.0755148492));
|
||||||
|
lxBlue = 255;
|
||||||
|
}
|
||||||
|
lxRed *= (tmpBri/255);
|
||||||
|
lxGreen *= (tmpBri/255);
|
||||||
|
lxBlue *= (tmpBri/255);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
if (lxRed > 255) {
|
||||||
|
lxRed = 255;
|
||||||
|
} else if (lxRed < 0) {
|
||||||
|
lxRed = 0;
|
||||||
|
}
|
||||||
|
if (lxGreen > 255) {
|
||||||
|
lxGreen = 255;
|
||||||
|
} else if (lxGreen < 0) {
|
||||||
|
lxGreen = 0;
|
||||||
|
}
|
||||||
|
if (lxBlue > 255) {
|
||||||
|
lxBlue = 255;
|
||||||
|
} else if (lxBlue < 0) {
|
||||||
|
lxBlue = 0;
|
||||||
|
}
|
||||||
|
rgbw[0] = (uint8_t)lxRed;
|
||||||
|
rgbw[1] = (uint8_t)lxGreen;
|
||||||
|
rgbw[2] = (uint8_t)lxBlue;
|
||||||
|
rgbw[3] = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receives client input
|
* Receives client input
|
||||||
*/
|
*/
|
||||||
@ -196,6 +197,11 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
hueStoreAllowed = true;
|
hueStoreAllowed = true;
|
||||||
reconnectHue();
|
reconnectHue();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// UDP Api
|
||||||
|
udpApiEnabled = request->hasArg("UAE");
|
||||||
|
t = request->arg("UAP").toInt();
|
||||||
|
if (t > 0) udpApiPort = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TIME
|
//TIME
|
||||||
@ -416,6 +422,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
byte main = strip.getMainSegmentId();
|
byte main = strip.getMainSegmentId();
|
||||||
if (main != prevMain) setValuesFromMainSeg();
|
if (main != prevMain) setValuesFromMainSeg();
|
||||||
|
|
||||||
|
bool segGiven = false;
|
||||||
pos = req.indexOf(F("SS="));
|
pos = req.indexOf(F("SS="));
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
byte t = getNumVal(&req, pos);
|
byte t = getNumVal(&req, pos);
|
||||||
@ -507,6 +514,35 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
|
|||||||
updateVal(&req, "B2=", &colSec[2]);
|
updateVal(&req, "B2=", &colSec[2]);
|
||||||
updateVal(&req, "W2=", &colSec[3]);
|
updateVal(&req, "W2=", &colSec[3]);
|
||||||
|
|
||||||
|
//lox parser
|
||||||
|
int rgbw[4] = {0,0,0,0};
|
||||||
|
pos = req.indexOf(F("LX=")); // Lox primary color
|
||||||
|
if (pos > 0) {
|
||||||
|
int lxValue = getNumVal(&req, pos);
|
||||||
|
if (parseLx(lxValue, rgbw)) {
|
||||||
|
col[0] = rgbw[0];
|
||||||
|
col[1] = rgbw[1];
|
||||||
|
col[2] = rgbw[2];
|
||||||
|
bri = 255;
|
||||||
|
nightlightActive = false; //always disable nightlight when toggling
|
||||||
|
DEBUG_PRINT(F("LX: Lox primary = "));
|
||||||
|
DEBUG_PRINTLN(lxValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos = req.indexOf(F("LY")); // Lox secondary color
|
||||||
|
if (pos > 0) {
|
||||||
|
int lxValue = getNumVal(&req, pos);
|
||||||
|
if(parseLx(lxValue, rgbw)) {
|
||||||
|
colSec[0] = rgbw[0];
|
||||||
|
colSec[1] = rgbw[1];
|
||||||
|
colSec[2] = rgbw[2];
|
||||||
|
bri = 255;
|
||||||
|
nightlightActive = false; //always disable nightlight when toggling
|
||||||
|
DEBUG_PRINT(F("LY: Lox secondary = "));
|
||||||
|
DEBUG_PRINTLN(lxValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//set hue
|
//set hue
|
||||||
pos = req.indexOf(F("HU="));
|
pos = req.indexOf(F("HU="));
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
|
@ -105,7 +105,7 @@ void handleNotifications()
|
|||||||
if(udpConnected && notificationTwoRequired && millis()-notificationSentTime > 250){
|
if(udpConnected && notificationTwoRequired && millis()-notificationSentTime > 250){
|
||||||
notify(notificationSentCallMode,true);
|
notify(notificationSentCallMode,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e131NewData && millis() - strip.getLastShow() > 15)
|
if (e131NewData && millis() - strip.getLastShow() > 15)
|
||||||
{
|
{
|
||||||
e131NewData = false;
|
e131NewData = false;
|
||||||
@ -129,25 +129,43 @@ void handleNotifications()
|
|||||||
//hyperion / raw RGB
|
//hyperion / raw RGB
|
||||||
if (!packetSize && udpRgbConnected) {
|
if (!packetSize && udpRgbConnected) {
|
||||||
packetSize = rgbUdp.parsePacket();
|
packetSize = rgbUdp.parsePacket();
|
||||||
if (!receiveDirect) return;
|
if (packetSize) {
|
||||||
if (packetSize > UDP_IN_MAXSIZE || packetSize < 3) return;
|
if (!receiveDirect) return;
|
||||||
realtimeIP = rgbUdp.remoteIP();
|
if (packetSize > UDP_IN_MAXSIZE || packetSize < 3) return;
|
||||||
DEBUG_PRINTLN(rgbUdp.remoteIP());
|
realtimeIP = rgbUdp.remoteIP();
|
||||||
uint8_t lbuf[packetSize];
|
DEBUG_PRINTLN(rgbUdp.remoteIP());
|
||||||
rgbUdp.read(lbuf, packetSize);
|
uint8_t lbuf[packetSize];
|
||||||
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
|
rgbUdp.read(lbuf, packetSize);
|
||||||
if (realtimeOverride) return;
|
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
|
||||||
uint16_t id = 0;
|
if (realtimeOverride) return;
|
||||||
for (uint16_t i = 0; i < packetSize -2; i += 3)
|
uint16_t id = 0;
|
||||||
{
|
for (uint16_t i = 0; i < packetSize -2; i += 3)
|
||||||
setRealtimePixel(id, lbuf[i], lbuf[i+1], lbuf[i+2], 0);
|
{
|
||||||
|
setRealtimePixel(id, lbuf[i], lbuf[i+1], lbuf[i+2], 0);
|
||||||
id++; if (id >= ledCount) break;
|
|
||||||
}
|
id++; if (id >= ledCount) break;
|
||||||
strip.show();
|
}
|
||||||
return;
|
strip.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// udp api
|
||||||
|
if (udpApiEnabled && !packetSize && udpApiConnected) {
|
||||||
|
packetSize = apiUdp.parsePacket();
|
||||||
|
if (packetSize) {
|
||||||
|
if (!receiveDirect) return;
|
||||||
|
if (packetSize > UDP_IN_MAXSIZE || packetSize < 3) return;
|
||||||
|
uint8_t lbuf[packetSize];
|
||||||
|
apiUdp.read(lbuf, packetSize);
|
||||||
|
lbuf[packetSize] = '\0';
|
||||||
|
String apireq = "win&";
|
||||||
|
apireq += (char*)lbuf;
|
||||||
|
handleSet(nullptr, apireq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//notifier and UDP realtime
|
//notifier and UDP realtime
|
||||||
if (!packetSize || packetSize > UDP_IN_MAXSIZE) return;
|
if (!packetSize || packetSize > UDP_IN_MAXSIZE) return;
|
||||||
if (notifierUdp.remoteIP() == WiFi.localIP()) return; //don't process broadcasts we send ourselves
|
if (notifierUdp.remoteIP() == WiFi.localIP()) return; //don't process broadcasts we send ourselves
|
||||||
|
@ -282,7 +282,10 @@ void WLED::initAP(bool resetAP)
|
|||||||
if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) {
|
if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) {
|
||||||
udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||||
}
|
}
|
||||||
|
if (udpApiEnabled && udpApiPort > 0 && udpApiPort != ntpLocalPort && udpApiPort != udpPort && udpApiPort != udpRgbPort) {
|
||||||
|
udpApiConnected = apiUdp.begin(udpApiPort);
|
||||||
|
}
|
||||||
|
|
||||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||||
dnsServer.start(53, "*", WiFi.softAPIP());
|
dnsServer.start(53, "*", WiFi.softAPIP());
|
||||||
}
|
}
|
||||||
@ -408,6 +411,8 @@ void WLED::initInterfaces()
|
|||||||
udpConnected = notifierUdp.begin(udpPort);
|
udpConnected = notifierUdp.begin(udpPort);
|
||||||
if (udpConnected && udpRgbPort != udpPort)
|
if (udpConnected && udpRgbPort != udpPort)
|
||||||
udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
udpRgbConnected = rgbUdp.begin(udpRgbPort);
|
||||||
|
if (udpApiEnabled && udpConnected && udpApiPort != udpPort && udpApiPort != udpRgbPort)
|
||||||
|
udpApiConnected = apiUdp.begin(udpApiPort);
|
||||||
}
|
}
|
||||||
if (ntpEnabled)
|
if (ntpEnabled)
|
||||||
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||||
|
@ -215,6 +215,7 @@ WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver
|
|||||||
|
|
||||||
WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port
|
WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port
|
||||||
WLED_GLOBAL uint16_t udpRgbPort _INIT(19446); // Hyperion port
|
WLED_GLOBAL uint16_t udpRgbPort _INIT(19446); // Hyperion port
|
||||||
|
WLED_GLOBAL uint16_t udpApiPort _INIT(7000); // Udp api port
|
||||||
|
|
||||||
WLED_GLOBAL bool receiveNotificationBrightness _INIT(true); // apply brightness from incoming notifications
|
WLED_GLOBAL bool receiveNotificationBrightness _INIT(true); // apply brightness from incoming notifications
|
||||||
WLED_GLOBAL bool receiveNotificationColor _INIT(true); // apply color
|
WLED_GLOBAL bool receiveNotificationColor _INIT(true); // apply color
|
||||||
@ -259,6 +260,8 @@ WLED_GLOBAL char mqttPass[41] _INIT(""); // optional: password
|
|||||||
WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID
|
WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID
|
||||||
WLED_GLOBAL uint16_t mqttPort _INIT(1883);
|
WLED_GLOBAL uint16_t mqttPort _INIT(1883);
|
||||||
|
|
||||||
|
WLED_GLOBAL bool udpApiEnabled _INIT(true);
|
||||||
|
|
||||||
WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge for light state
|
WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge for light state
|
||||||
WLED_GLOBAL uint16_t huePollIntervalMs _INIT(2500); // low values (< 1sec) may cause lag but offer quicker response
|
WLED_GLOBAL uint16_t huePollIntervalMs _INIT(2500); // low values (< 1sec) may cause lag but offer quicker response
|
||||||
WLED_GLOBAL char hueApiKey[47] _INIT("api"); // key token will be obtained from bridge
|
WLED_GLOBAL char hueApiKey[47] _INIT("api"); // key token will be obtained from bridge
|
||||||
@ -377,7 +380,7 @@ WLED_GLOBAL byte effectIntensity _INIT(128);
|
|||||||
WLED_GLOBAL byte effectPalette _INIT(0);
|
WLED_GLOBAL byte effectPalette _INIT(0);
|
||||||
|
|
||||||
// network
|
// network
|
||||||
WLED_GLOBAL bool udpConnected _INIT(false), udpRgbConnected _INIT(false);
|
WLED_GLOBAL bool udpConnected _INIT(false), udpRgbConnected _INIT(false), udpApiConnected _INIT(false);;
|
||||||
|
|
||||||
// ui style
|
// ui style
|
||||||
WLED_GLOBAL bool showWelcomePage _INIT(false);
|
WLED_GLOBAL bool showWelcomePage _INIT(false);
|
||||||
@ -493,7 +496,7 @@ WLED_GLOBAL AsyncClient* hueClient _INIT(NULL);
|
|||||||
WLED_GLOBAL AsyncMqttClient* mqtt _INIT(NULL);
|
WLED_GLOBAL AsyncMqttClient* mqtt _INIT(NULL);
|
||||||
|
|
||||||
// udp interface objects
|
// udp interface objects
|
||||||
WLED_GLOBAL WiFiUDP notifierUdp, rgbUdp;
|
WLED_GLOBAL WiFiUDP notifierUdp, rgbUdp, apiUdp;
|
||||||
WLED_GLOBAL WiFiUDP ntpUdp;
|
WLED_GLOBAL WiFiUDP ntpUdp;
|
||||||
WLED_GLOBAL ESPAsyncE131 e131 _INIT_N(((handleE131Packet)));
|
WLED_GLOBAL ESPAsyncE131 e131 _INIT_N(((handleE131Packet)));
|
||||||
WLED_GLOBAL bool e131NewData _INIT(false);
|
WLED_GLOBAL bool e131NewData _INIT(false);
|
||||||
|
@ -284,6 +284,10 @@ void saveSettingsToEEPROM()
|
|||||||
} // last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye.
|
} // last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
EEPROM.write(2550, udpApiEnabled);
|
||||||
|
EEPROM.write(2551, udpApiPort & 0xFF);
|
||||||
|
EEPROM.write(2552, (udpApiPort >> 8) & 0xFF);
|
||||||
|
|
||||||
commit();
|
commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,6 +542,11 @@ void loadSettingsFromEEPROM(bool first)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (lastEEPROMversion > 19) {
|
||||||
|
udpApiEnabled = EEPROM.read(2550);
|
||||||
|
udpApiPort = EEPROM.read(2551) + ((EEPROM.read(2552) << 8) & 0xFF00);
|
||||||
|
}
|
||||||
|
|
||||||
receiveDirect = !EEPROM.read(2200);
|
receiveDirect = !EEPROM.read(2200);
|
||||||
notifyMacro = EEPROM.read(2201);
|
notifyMacro = EEPROM.read(2201);
|
||||||
|
|
||||||
|
@ -316,6 +316,10 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',SET_F("SA"),notifyAlexa);
|
sappend('c',SET_F("SA"),notifyAlexa);
|
||||||
sappends('s',SET_F("BK"),(char*)((blynkEnabled)?SET_F("Hidden"):""));
|
sappends('s',SET_F("BK"),(char*)((blynkEnabled)?SET_F("Hidden"):""));
|
||||||
|
|
||||||
|
// UDP Api
|
||||||
|
sappend('c',"UAE",udpApiEnabled);
|
||||||
|
sappend('v',"UAP",udpApiPort);
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_MQTT
|
#ifdef WLED_ENABLE_MQTT
|
||||||
sappend('c',SET_F("MQ"),mqttEnabled);
|
sappend('c',SET_F("MQ"),mqttEnabled);
|
||||||
sappends('s',SET_F("MS"),mqttServer);
|
sappends('s',SET_F("MS"),mqttServer);
|
||||||
|
Loading…
Reference in New Issue
Block a user