Skip to content

Commit 1dbcac4

Browse files
committed
Framerate bug workaround
1 parent 8d20a13 commit 1dbcac4

File tree

11 files changed

+129
-83
lines changed

11 files changed

+129
-83
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
### Development versions after 0.11.1 release
44

5+
#### Build 2103220
6+
7+
- Version bump to 0.12.0-b2 "Hikari"
8+
- Worked around an issue causing a critical decrease in framerate (wled.cpp l.240 block)
9+
- Bump to Espalexa v2.7.0, fixing discovery
10+
511
#### Build 2103210
612

713
- Version bump to 0.12.0-b1 "Hikari"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "wled",
3-
"version": "0.12.0-b1",
3+
"version": "0.12.0-b2",
44
"description": "Tools for WLED project",
55
"main": "tools/cdata.js",
66
"directories": {

platformio.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
# ------------------------------------------------------------------------------
1010

1111
# Travis CI binaries (comment this out with a ';' when building for your own board)
12-
default_envs = travis_esp8266, travis_esp32
12+
;default_envs = travis_esp8266, travis_esp32
1313

1414
# Release binaries
15-
; default_envs = nodemcuv2, esp01_1m_full, esp32dev, esp32_eth
15+
default_envs = nodemcuv2, esp01_1m_full, esp32dev, esp32_eth
1616

1717
# Single binaries (uncomment your board)
1818
; default_envs = nodemcuv2

wled00/html_other.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ function B(){window.history.back()}function U(){document.getElementById("uf").st
4242
.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none}
4343
</style></head><body><h2>WLED Software Update</h2><form method="POST"
4444
action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()">
45-
Installed version: 0.12.0-b1<br>Download the latest binary: <a
45+
Installed version: 0.12.0-b2<br>Download the latest binary: <a
4646
href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img
4747
src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square">
4848
</a><br><input type="file" class="bt" name="update" accept=".bin" required><br>

wled00/html_settings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
375375
<h3>Software Update</h3><button type="button" onclick="U()">Manual OTA Update
376376
</button><br>Enable ArduinoOTA: <input type="checkbox" name="AO"><br><h3>About
377377
</h3><a href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
378-
version 0.12.0-b1<br><br><a
378+
version 0.12.0-b2<br><br><a
379379
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
380380
target="_blank">Contributors, dependencies and special thanks</a><br>
381381
A huge thank you to everyone who helped me create WLED!<br><br>

wled00/set.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
116116

117117
if (busConfigs[s] != nullptr) delete busConfigs[s];
118118
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder, request->hasArg(cv));
119+
doInitBusses = true;
119120
}
120121

121122
ledCount = request->arg(F("LC")).toInt();

wled00/src/dependencies/espalexa/Espalexa.h

Lines changed: 91 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*/
1111
/*
1212
* @title Espalexa library
13-
* @version 2.5.0
13+
* @version 2.7.0
1414
* @author Christian Schwinne
1515
* @license MIT
1616
* @contributors d-999
@@ -25,7 +25,7 @@
2525
//#define ESPALEXA_NO_SUBPAGE
2626

2727
#ifndef ESPALEXA_MAXDEVICES
28-
#define ESPALEXA_MAXDEVICES 10 //this limit only has memory reasons, set it higher should you need to
28+
#define ESPALEXA_MAXDEVICES 10 //this limit only has memory reasons, set it higher should you need to, max 128
2929
#endif
3030

3131
//#define ESPALEXA_DEBUG
@@ -50,7 +50,7 @@
5050
#include "../network/Network.h"
5151

5252
#ifdef ESPALEXA_DEBUG
53-
#pragma message "Espalexa 2.5.0 debug mode"
53+
#pragma message "Espalexa 2.7.0 debug mode"
5454
#define EA_DEBUG(x) Serial.print (x)
5555
#define EA_DEBUGLN(x) Serial.println (x)
5656
#else
@@ -76,13 +76,14 @@ class Espalexa {
7676
#endif
7777
uint8_t currentDeviceCount = 0;
7878
bool discoverable = true;
79+
bool udpConnected = false;
7980

8081
EspalexaDevice* devices[ESPALEXA_MAXDEVICES] = {};
8182
//Keep in mind that Device IDs go from 1 to DEVICES, cpp arrays from 0 to DEVICES-1!!
8283

8384
WiFiUDP espalexaUdp;
8485
IPAddress ipMulti;
85-
bool udpConnected = false;
86+
uint32_t mac24; //bottom 24 bits of mac
8687
String escapedMac=""; //lowercase mac address
8788

8889
//private member functions
@@ -119,33 +120,32 @@ class Espalexa {
119120

120121
void encodeLightId(uint8_t idx, char* out)
121122
{
122-
//Unique id must be 12 character len
123-
//use the last 10 characters of the MAC followed by the device id in hex value
124-
//uniqueId: aabbccddeeii
125-
126123
uint8_t mac[6];
127124
WiFi.macAddress(mac);
128125

129-
//shift the mac address to the left (discard first byte)
130-
for (uint8_t i = 0; i < 5; i++) {
131-
mac[i] = mac[i+1];
132-
}
133-
mac[5] = idx;
126+
sprintf_P(out, PSTR("%02X:%02X:%02X:%02X:%02X:%02X:00:11-%02X"), mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], idx);
127+
}
134128

135-
for (uint8_t i = 0; i < 6; i++) {
136-
sprintf(out + i*2, "%.2x", mac[i]);
137-
}
129+
// construct 'globally unique' Json dict key fitting into signed int
130+
inline int encodeLightKey(uint8_t idx)
131+
{
132+
//return idx +1;
133+
static_assert(ESPALEXA_MAXDEVICES <= 128, "");
134+
return (mac24<<7) | idx;
138135
}
139-
136+
137+
// get device index from Json key
138+
uint8_t decodeLightKey(int key)
139+
{
140+
//return key -1;
141+
return (((uint32_t)key>>7) == mac24) ? (key & 127U) : 255U;
142+
}
143+
140144
//device JSON string: color+temperature device emulates LCT015, dimmable device LWB010, (TODO: on/off Plug 01, color temperature device LWT010, color device LST001)
141-
void deviceJsonString(uint8_t deviceId, char* buf)
145+
void deviceJsonString(EspalexaDevice* dev, char* buf)
142146
{
143-
deviceId--;
144-
if (deviceId >= currentDeviceCount) {strcpy(buf,"{}"); return;} //error
145-
EspalexaDevice* dev = devices[deviceId];
146-
147-
char buf_lightid[13];
148-
encodeLightId(deviceId + 1, buf_lightid);
147+
char buf_lightid[27];
148+
encodeLightId(dev->getId() + 1, buf_lightid);
149149

150150
char buf_col[80] = "";
151151
//color support
@@ -167,7 +167,7 @@ class Espalexa {
167167

168168
sprintf_P(buf, PSTR("{\"state\":{\"on\":%s,\"bri\":%u%s%s,\"alert\":\"none%s\",\"mode\":\"homeautomation\",\"reachable\":true},"
169169
"\"type\":\"%s\",\"name\":\"%s\",\"modelid\":\"%s\",\"manufacturername\":\"Philips\",\"productname\":\"E%u"
170-
"\",\"uniqueid\":\"%s\",\"swversion\":\"espalexa-2.5.0\"}")
170+
"\",\"uniqueid\":\"%s\",\"swversion\":\"espalexa-2.7.0\"}")
171171

172172
, (dev->getValue())?"true":"false", dev->getLastValue()-1, buf_col, buf_ct, buf_cm, typeString(dev->getType()),
173173
dev->getName().c_str(), modelidString(dev->getType()), static_cast<uint8_t>(dev->getType()), buf_lightid);
@@ -192,7 +192,7 @@ class Espalexa {
192192
}
193193
res += "\r\nFree Heap: " + (String)ESP.getFreeHeap();
194194
res += "\r\nUptime: " + (String)millis();
195-
res += "\r\n\r\nEspalexa library v2.5.0 by Christian Schwinne 2020";
195+
res += "\r\n\r\nEspalexa library v2.7.0 by Christian Schwinne 2021";
196196
server->send(200, "text/plain", res);
197197
}
198198
#endif
@@ -335,6 +335,9 @@ class Espalexa {
335335
escapedMac.replace(":", "");
336336
escapedMac.toLowerCase();
337337

338+
String macSubStr = escapedMac.substring(6, 12);
339+
mac24 = strtol(macSubStr.c_str(), 0, 16);
340+
338341
#ifdef ESPALEXA_ASYNC
339342
serverAsync = externalServer;
340343
#else
@@ -390,48 +393,55 @@ class Espalexa {
390393
}
391394
}
392395

393-
bool addDevice(EspalexaDevice* d)
396+
// returns device index or 0 on failure
397+
uint8_t addDevice(EspalexaDevice* d)
394398
{
395399
EA_DEBUG("Adding device ");
396400
EA_DEBUGLN((currentDeviceCount+1));
397-
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
398-
if (d == nullptr) return false;
401+
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
402+
if (d == nullptr) return 0;
399403
d->setId(currentDeviceCount);
400404
devices[currentDeviceCount] = d;
401-
currentDeviceCount++;
402-
return true;
405+
return ++currentDeviceCount;
403406
}
404407

405408
//brightness-only callback
406-
bool addDevice(String deviceName, BrightnessCallbackFunction callback, uint8_t initialValue = 0)
409+
uint8_t addDevice(String deviceName, BrightnessCallbackFunction callback, uint8_t initialValue = 0)
407410
{
408411
EA_DEBUG("Constructing device ");
409412
EA_DEBUGLN((currentDeviceCount+1));
410-
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
413+
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
411414
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
412415
return addDevice(d);
413416
}
414417

415418
//brightness-only callback
416-
bool addDevice(String deviceName, ColorCallbackFunction callback, uint8_t initialValue = 0)
419+
uint8_t addDevice(String deviceName, ColorCallbackFunction callback, uint8_t initialValue = 0)
417420
{
418421
EA_DEBUG("Constructing device ");
419422
EA_DEBUGLN((currentDeviceCount+1));
420-
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
423+
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
421424
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, initialValue);
422425
return addDevice(d);
423426
}
424427

425428

426-
bool addDevice(String deviceName, DeviceCallbackFunction callback, EspalexaDeviceType t = EspalexaDeviceType::dimmable, uint8_t initialValue = 0)
429+
uint8_t addDevice(String deviceName, DeviceCallbackFunction callback, EspalexaDeviceType t = EspalexaDeviceType::dimmable, uint8_t initialValue = 0)
427430
{
428431
EA_DEBUG("Constructing device ");
429432
EA_DEBUGLN((currentDeviceCount+1));
430-
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return false;
433+
if (currentDeviceCount >= ESPALEXA_MAXDEVICES) return 0;
431434
EspalexaDevice* d = new EspalexaDevice(deviceName, callback, t, initialValue);
432435
return addDevice(d);
433436
}
434-
437+
438+
void renameDevice(uint8_t id, const String& deviceName)
439+
{
440+
unsigned int index = id - 1;
441+
if (index < currentDeviceCount)
442+
devices[index]->setName(deviceName);
443+
}
444+
435445
//basic implementation of Philips hue api functions needed for basic Alexa control
436446
#ifdef ESPALEXA_ASYNC
437447
bool handleAlexaApiCall(AsyncWebServerRequest* request)
@@ -450,6 +460,8 @@ class Espalexa {
450460
bool handleAlexaApiCall(String req, String body)
451461
{
452462
#endif
463+
EA_DEBUG("URL: ");
464+
EA_DEBUGLN(req);
453465
EA_DEBUGLN("AlexaApiCall");
454466
if (req.indexOf("api") <0) return false; //return if not an API call
455467
EA_DEBUGLN("ok");
@@ -458,70 +470,72 @@ class Espalexa {
458470
{
459471
EA_DEBUGLN("devType");
460472
body = "";
461-
server->send(200, "application/json", F("[{\"success\":{\"username\":\"2WLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBQr\"}}]"));
473+
server->send(200, "application/json", F("[{\"success\":{\"username\":\"2BLEDHardQrI3WHYTHoMcXHgEspsM8ZZRpSKtBGr\"}}]"));
462474
return true;
463475
}
464476

465477
if ((req.indexOf("state") > 0) && (body.length() > 0)) //client wants to control light
466478
{
467-
server->send(200, "application/json", F("[{\"success\":{\"/lights/1/state/\": true}}]"));
468-
469479
uint32_t devId = req.substring(req.indexOf("lights")+7).toInt();
470480
EA_DEBUG("ls"); EA_DEBUGLN(devId);
471-
EA_DEBUGLN(devId);
472-
devId--; //zero-based for devices array
473-
if (devId >= currentDeviceCount) return true; //return if invalid ID
481+
unsigned idx = decodeLightKey(devId);
482+
EA_DEBUGLN(idx);
483+
char buf[50];
484+
sprintf_P(buf,PSTR("[{\"success\":{\"/lights/%u/state/\": true}}]"),devId);
485+
server->send(200, "application/json", buf);
486+
if (idx >= currentDeviceCount) return true; //return if invalid ID
487+
EspalexaDevice* dev = devices[idx];
474488

475-
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::none);
489+
dev->setPropertyChanged(EspalexaDeviceProperty::none);
476490

477491
if (body.indexOf("false")>0) //OFF command
478492
{
479-
devices[devId]->setValue(0);
480-
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::off);
481-
devices[devId]->doCallback();
493+
dev->setValue(0);
494+
dev->setPropertyChanged(EspalexaDeviceProperty::off);
495+
dev->doCallback();
482496
return true;
483497
}
484498

485499
if (body.indexOf("true") >0) //ON command
486500
{
487-
devices[devId]->setValue(devices[devId]->getLastValue());
488-
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::on);
501+
dev->setValue(dev->getLastValue());
502+
dev->setPropertyChanged(EspalexaDeviceProperty::on);
489503
}
490504

491505
if (body.indexOf("bri") >0) //BRIGHTNESS command
492506
{
493507
uint8_t briL = body.substring(body.indexOf("bri") +5).toInt();
494508
if (briL == 255)
495509
{
496-
devices[devId]->setValue(255);
510+
dev->setValue(255);
497511
} else {
498-
devices[devId]->setValue(briL+1);
512+
dev->setValue(briL+1);
499513
}
500-
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::bri);
514+
dev->setPropertyChanged(EspalexaDeviceProperty::bri);
501515
}
502516

503517
if (body.indexOf("xy") >0) //COLOR command (XY mode)
504518
{
505-
devices[devId]->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
506-
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::xy);
519+
dev->setColorXY(body.substring(body.indexOf("[") +1).toFloat(), body.substring(body.indexOf(",0") +1).toFloat());
520+
dev->setPropertyChanged(EspalexaDeviceProperty::xy);
507521
}
508522

509523
if (body.indexOf("hue") >0) //COLOR command (HS mode)
510524
{
511-
devices[devId]->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
512-
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::hs);
525+
dev->setColor(body.substring(body.indexOf("hue") +5).toInt(), body.substring(body.indexOf("sat") +5).toInt());
526+
dev->setPropertyChanged(EspalexaDeviceProperty::hs);
513527
}
514528

515529
if (body.indexOf("ct") >0) //COLOR TEMP command (white spectrum)
516530
{
517-
devices[devId]->setColor(body.substring(body.indexOf("ct") +4).toInt());
518-
devices[devId]->setPropertyChanged(EspalexaDeviceProperty::ct);
531+
dev->setColor(body.substring(body.indexOf("ct") +4).toInt());
532+
dev->setPropertyChanged(EspalexaDeviceProperty::ct);
519533
}
520534

521-
devices[devId]->doCallback();
535+
dev->doCallback();
522536

523537
#ifdef ESPALEXA_DEBUG
524-
if (devices[devId]->getLastChangedProperty() == EspalexaDeviceProperty::none)
538+
if (dev->getLastChangedProperty() == EspalexaDeviceProperty::none)
525539
EA_DEBUGLN("STATE REQ WITHOUT BODY (likely Content-Type issue #6)");
526540
#endif
527541
return true;
@@ -539,25 +553,31 @@ class Espalexa {
539553
String jsonTemp = "{";
540554
for (int i = 0; i<currentDeviceCount; i++)
541555
{
542-
jsonTemp += "\"" + String(i+1) + "\":";
556+
jsonTemp += '"';
557+
jsonTemp += encodeLightKey(i);
558+
jsonTemp += '"';
559+
jsonTemp += ':';
560+
543561
char buf[512];
544-
deviceJsonString(i+1, buf);
562+
deviceJsonString(devices[i], buf);
545563
jsonTemp += buf;
546-
if (i < currentDeviceCount-1) jsonTemp += ",";
564+
if (i < currentDeviceCount-1) jsonTemp += ',';
547565
}
548-
jsonTemp += "}";
566+
jsonTemp += '}';
549567
server->send(200, "application/json", jsonTemp);
550568
} else //client wants one light (devId)
551569
{
552570
EA_DEBUGLN(devId);
553-
if (devId > currentDeviceCount)
554-
{
571+
unsigned int idx = decodeLightKey(devId);
572+
573+
if (idx >= currentDeviceCount) idx = 0; //send first device if invalid
574+
if (currentDeviceCount == 0) {
555575
server->send(200, "application/json", "{}");
556-
} else {
557-
char buf[512];
558-
deviceJsonString(devId, buf);
559-
server->send(200, "application/json", buf);
576+
return true;
560577
}
578+
char buf[512];
579+
deviceJsonString(devices[idx], buf);
580+
server->send(200, "application/json", buf);
561581
}
562582

563583
return true;

0 commit comments

Comments
 (0)