mirror of https://github.com/arendst/Tasmota.git
v3.9.10
3.9.10 20170130 * Add WS2812 Color Type selection (RGB or GRB) to user_config.h (#7) * Hue api changes to support HUE App(s) (#8)
This commit is contained in:
parent
aaf75f6acb
commit
f9e8cbdfc9
|
@ -1,7 +1,7 @@
|
||||||
## Sonoff-Tasmota
|
## Sonoff-Tasmota
|
||||||
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
|
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
|
||||||
|
|
||||||
Current version is **3.9.9** - See ```sonoff/_releasenotes.ino``` for change information.
|
Current version is **3.9.10** - See ```sonoff/_releasenotes.ino``` for change information.
|
||||||
|
|
||||||
- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
|
- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
|
||||||
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.
|
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.
|
||||||
|
|
Binary file not shown.
|
@ -1,4 +1,8 @@
|
||||||
/* 3.9.9 20170130
|
/* 3.9.10 20170130
|
||||||
|
* Add WS2812 Color Type selection (RGB or GRB) to user_config.h (#7)
|
||||||
|
* Hue api changes to support HUE App(s) (#8)
|
||||||
|
*
|
||||||
|
* 3.9.9 20170130
|
||||||
* Add command status 10 showing sensor data
|
* Add command status 10 showing sensor data
|
||||||
* Fix hlw status messages if hlw is disabled
|
* Fix hlw status messages if hlw is disabled
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* ====================================================
|
* ====================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VERSION 0x03090900 // 3.9.9
|
#define VERSION 0x03090A00 // 3.9.10
|
||||||
|
|
||||||
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
||||||
enum week_t {Last, First, Second, Third, Fourth};
|
enum week_t {Last, First, Second, Third, Fourth};
|
||||||
|
|
|
@ -127,6 +127,7 @@
|
||||||
#define USE_HTU // Add I2C code for HTU21 sensor
|
#define USE_HTU // Add I2C code for HTU21 sensor
|
||||||
|
|
||||||
#define USE_WS2812 // WS2812 Led string support (+8k code, +1k mem)
|
#define USE_WS2812 // WS2812 Led string support (+8k code, +1k mem)
|
||||||
|
#define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB)
|
||||||
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial TXD) (+1k mem)
|
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial TXD) (+1k mem)
|
||||||
// When USE_WS2812_DMA is enabled expect Exceptions on Pow
|
// When USE_WS2812_DMA is enabled expect Exceptions on Pow
|
||||||
|
|
||||||
|
|
|
@ -164,8 +164,8 @@ const char HTTP_FORM_OTHER2[] PROGMEM =
|
||||||
#ifdef USE_EMULATION
|
#ifdef USE_EMULATION
|
||||||
const char HTTP_FORM_OTHER3[] PROGMEM =
|
const char HTTP_FORM_OTHER3[] PROGMEM =
|
||||||
"<br/><fieldset><legend><b> Emulation </b></legend>"
|
"<br/><fieldset><legend><b> Emulation </b></legend>"
|
||||||
"<br/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='0'{r2}><b>None</b><br/>"
|
"<br/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='0'{r2}><b>None</b>"
|
||||||
"<br/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='1'{r3}><b>Belkin WeMo</b><br/>"
|
"<br/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='1'{r3}><b>Belkin WeMo</b>"
|
||||||
"<br/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='2'{r4}><b>Hue Bridge</b><br/>";
|
"<br/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='2'{r4}><b>Hue Bridge</b><br/>";
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
const char HTTP_FORM_END[] PROGMEM =
|
const char HTTP_FORM_END[] PROGMEM =
|
||||||
|
@ -288,6 +288,28 @@ const char HUE_LIGHT_STATUS_JSON[] PROGMEM =
|
||||||
"}";
|
"}";
|
||||||
const char HUE_LIGHT_RESPONSE_JSON[] PROGMEM =
|
const char HUE_LIGHT_RESPONSE_JSON[] PROGMEM =
|
||||||
"{\"success\":{\"{api}/{id}/{cmd}\":{res}}}";
|
"{\"success\":{\"{api}/{id}/{cmd}\":{res}}}";
|
||||||
|
const char HUE_CONFIG_RESPONSE_JSON[] PROGMEM =
|
||||||
|
"{\"name\":\"Philips hue\","
|
||||||
|
"\"mac\":\"{mac}\","
|
||||||
|
"\"dhcp\":true,"
|
||||||
|
"\"ipaddress\":\"{ip}\","
|
||||||
|
"\"netmask\":\"{mask}\","
|
||||||
|
"\"gateway\":\"{gw}\","
|
||||||
|
"\"proxyaddress\":\"\","
|
||||||
|
"\"proxyport\":0,"
|
||||||
|
"\"UTC\":\"{dt}\","
|
||||||
|
"\"whitelist\":{\"{id}\":{"
|
||||||
|
"\"last use date\":\"{dt}\","
|
||||||
|
"\"create date\":\"{dt}\","
|
||||||
|
"\"name\":\"Remote\"}},"
|
||||||
|
"\"swversion\":\"01036659\","
|
||||||
|
"\"apiversion\":\"1.16.0\","
|
||||||
|
"\"swupdate\":{\"updatestate\":0,\"url\":\"\",\"text\":\"\",\"notify\": false},"
|
||||||
|
"\"linkbutton\":false,"
|
||||||
|
"\"portalservices\":false"
|
||||||
|
"}";
|
||||||
|
const char HUE_NO_AUTH_JSON[] PROGMEM =
|
||||||
|
"[{\"error\":{\"type\":101,\"address\":\"/\",\"description\":\"link button not pressed\"}}]";
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
|
|
||||||
#define DNS_PORT 53
|
#define DNS_PORT 53
|
||||||
|
@ -1339,6 +1361,76 @@ void hue_todo(String *path)
|
||||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hue_config_response(String *response)
|
||||||
|
{
|
||||||
|
char buffer[21];
|
||||||
|
|
||||||
|
*response += FPSTR(HUE_CONFIG_RESPONSE_JSON);
|
||||||
|
response->replace("{mac}", WiFi.macAddress());
|
||||||
|
response->replace("{ip}", WiFi.localIP().toString());
|
||||||
|
response->replace("{mask}", WiFi.subnetMask().toString());
|
||||||
|
response->replace("{gw}", WiFi.gatewayIP().toString());
|
||||||
|
snprintf_P(buffer, sizeof(buffer), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
|
||||||
|
rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
|
||||||
|
response->replace("{dt}", String(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void hue_global_cfg(String *path)
|
||||||
|
{
|
||||||
|
String response;
|
||||||
|
|
||||||
|
path->remove(0,1); // cut leading / to get <id>
|
||||||
|
response = "{\"lights\":{\"";
|
||||||
|
for (uint8_t i = 1; i <= Maxdevice; i++)
|
||||||
|
{
|
||||||
|
response += i;
|
||||||
|
response += "\":";
|
||||||
|
response += FPSTR(HUE_LIGHT_STATUS_JSON);
|
||||||
|
if (i < Maxdevice) response += ",\"";
|
||||||
|
response.replace("{state}", (power & (0x01 << (i-1))) ? "true" : "false");
|
||||||
|
response.replace("{j1}", sysCfg.friendlyname[i-1]);
|
||||||
|
response.replace("{j2}", hue_deviceId(i));
|
||||||
|
if (pin[GPIO_WS2812] < 99) {
|
||||||
|
#ifdef USE_WS2812
|
||||||
|
ws2812_replaceHSB(&response);
|
||||||
|
#endif // USE_WS2812
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
response.replace("{h}", "0");
|
||||||
|
response.replace("{s}", "0");
|
||||||
|
response.replace("{b}", "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response += F("},\"groups\":{},\"schedules\":{},\"config\":");
|
||||||
|
|
||||||
|
hue_config_response(&response);
|
||||||
|
response.replace("{id}", *path);
|
||||||
|
response += "}";
|
||||||
|
webServer->send(200, "application/json", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hue_auth(String *path)
|
||||||
|
{
|
||||||
|
String response;
|
||||||
|
char uid[7];
|
||||||
|
|
||||||
|
snprintf_P(uid, sizeof(uid), PSTR("%03x"), ESP.getChipId());
|
||||||
|
response="[{\"success\":{\"username\":\"";
|
||||||
|
response+=String(uid);
|
||||||
|
response+="\"}}]";
|
||||||
|
webServer->send(200, "application/json", response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hue_config(String *path)
|
||||||
|
{
|
||||||
|
String response = "";
|
||||||
|
|
||||||
|
path->remove(0,1); // cut leading / to get <id>
|
||||||
|
hue_config_response(&response);
|
||||||
|
response.replace("{id}", *path);
|
||||||
|
webServer->send(200, "application/json", response);
|
||||||
|
}
|
||||||
|
|
||||||
void hue_lights(String *path)
|
void hue_lights(String *path)
|
||||||
{
|
{
|
||||||
String response;
|
String response;
|
||||||
|
@ -1388,7 +1480,8 @@ void hue_lights(String *path)
|
||||||
if (webServer->args() == 1)
|
if (webServer->args() == 1)
|
||||||
{
|
{
|
||||||
String json = webServer->arg(0);
|
String json = webServer->arg(0);
|
||||||
// Serial.print("HUE API: POST "); Serial.println(json.c_str());
|
json.replace(" ",""); // remove blanks
|
||||||
|
|
||||||
if (json.indexOf("\"on\":") >= 0) // Got "on" command
|
if (json.indexOf("\"on\":") >= 0) // Got "on" command
|
||||||
{
|
{
|
||||||
if (json.indexOf("false") >= 0) // false -> turn device off
|
if (json.indexOf("false") >= 0) // false -> turn device off
|
||||||
|
@ -1456,22 +1549,34 @@ void handle_hue_api(String *path)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char log[LOGSZ];
|
char log[LOGSZ];
|
||||||
|
uint8_t args = 0;
|
||||||
|
|
||||||
path->remove(0, 4); // remove /api
|
path->remove(0, 4); // remove /api
|
||||||
|
snprintf_P(log, sizeof(log), PSTR("HTTP: Handle Hue API (%s)"), path->c_str());
|
||||||
|
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||||
|
for (args = 0; args < webServer->args(); args++) {
|
||||||
|
String json = webServer->arg(args);
|
||||||
|
snprintf_P(log, sizeof(log), PSTR("HTTP: Hue POST args (%s)"), json.c_str());
|
||||||
|
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||||
|
}
|
||||||
|
|
||||||
if (path->endsWith("/invalid/")) {} // Just ignore
|
if (path->endsWith("/invalid/")) {} // Just ignore
|
||||||
else if (path->endsWith("/config")) hue_todo(path);
|
else if (path->endsWith("/")) hue_auth(path); // New HUE App setup
|
||||||
|
else if (path->endsWith("/config")) hue_config(path);
|
||||||
else if (path->indexOf("/lights") >= 0) hue_lights(path);
|
else if (path->indexOf("/lights") >= 0) hue_lights(path);
|
||||||
else if (path->endsWith("/groups")) hue_todo(path);
|
else if (path->endsWith("/groups")) hue_todo(path);
|
||||||
else if (path->endsWith("/schedules")) hue_todo(path);
|
else if (path->endsWith("/schedules")) hue_todo(path);
|
||||||
else if (path->endsWith("/sensors")) hue_todo(path);
|
else if (path->endsWith("/sensors")) hue_todo(path);
|
||||||
else if (path->endsWith("/scenes")) hue_todo(path);
|
else if (path->endsWith("/scenes")) hue_todo(path);
|
||||||
else if (path->endsWith("/rules")) hue_todo(path);
|
else if (path->endsWith("/rules")) hue_todo(path);
|
||||||
else
|
else hue_global_cfg(path);
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
snprintf_P(log, sizeof(log), PSTR("HTTP: Handle Hue API (%s)"),path->c_str());
|
snprintf_P(log, sizeof(log), PSTR("HTTP: Handle Hue API (%s)"),path->c_str());
|
||||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||||
webServer->send(406, "application/json", "{}");
|
webServer->send(406, "application/json", "{}");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,6 @@ void hue_respondToMSearch()
|
||||||
response.replace("{r3}", hue_UUID());
|
response.replace("{r3}", hue_UUID());
|
||||||
portUDP.write(response.c_str());
|
portUDP.write(response.c_str());
|
||||||
portUDP.endPacket();
|
portUDP.endPacket();
|
||||||
snprintf_P(message, sizeof(message), PSTR("Response1 sent"));
|
|
||||||
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
||||||
|
|
||||||
response = FPSTR(HUE_RESPONSE);
|
response = FPSTR(HUE_RESPONSE);
|
||||||
|
@ -150,7 +149,6 @@ void hue_respondToMSearch()
|
||||||
response.replace("{r3}", hue_UUID());
|
response.replace("{r3}", hue_UUID());
|
||||||
portUDP.write(response.c_str());
|
portUDP.write(response.c_str());
|
||||||
portUDP.endPacket();
|
portUDP.endPacket();
|
||||||
snprintf_P(message, sizeof(message), PSTR("Response2 sent"));
|
|
||||||
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
||||||
|
|
||||||
response = FPSTR(HUE_RESPONSE);
|
response = FPSTR(HUE_RESPONSE);
|
||||||
|
@ -161,7 +159,8 @@ void hue_respondToMSearch()
|
||||||
response.replace("{r3}", hue_UUID());
|
response.replace("{r3}", hue_UUID());
|
||||||
portUDP.write(response.c_str());
|
portUDP.write(response.c_str());
|
||||||
portUDP.endPacket();
|
portUDP.endPacket();
|
||||||
snprintf_P(message, sizeof(message), PSTR("Response3 sent"));
|
|
||||||
|
snprintf_P(message, sizeof(message), PSTR("3 response packets sent"));
|
||||||
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,9 +31,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <NeoPixelBus.h>
|
#include <NeoPixelBus.h>
|
||||||
|
|
||||||
#ifdef USE_WS2812_DMA
|
#ifdef USE_WS2812_DMA
|
||||||
|
#if (USE_WS2812_CTYPE == 1)
|
||||||
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> *strip = NULL;
|
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> *strip = NULL;
|
||||||
#else
|
#else // USE_WS2812_CTYPE
|
||||||
|
NeoPixelBus<NeoRgbFeature, Neo800KbpsMethod> *strip = NULL;
|
||||||
|
#endif // USE_WS2812_CTYPE
|
||||||
|
#else // USE_WS2812_DMA
|
||||||
|
#if (USE_WS2812_CTYPE == 1)
|
||||||
NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> *strip = NULL;
|
NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> *strip = NULL;
|
||||||
|
#else // USE_WS2812_CTYPE
|
||||||
|
NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang800KbpsMethod> *strip = NULL;
|
||||||
|
#endif // USE_WS2812_CTYPE
|
||||||
#endif // USE_WS2812_DMA
|
#endif // USE_WS2812_DMA
|
||||||
|
|
||||||
#define COLOR_SATURATION 254.0f
|
#define COLOR_SATURATION 254.0f
|
||||||
|
@ -457,9 +465,17 @@ void ws2812_pixels()
|
||||||
void ws2812_init()
|
void ws2812_init()
|
||||||
{
|
{
|
||||||
#ifdef USE_WS2812_DMA
|
#ifdef USE_WS2812_DMA
|
||||||
|
#if (USE_WS2812_CTYPE == 1)
|
||||||
strip = new NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod>(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use.
|
strip = new NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod>(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use.
|
||||||
#else
|
#else // USE_WS2812_CTYPE
|
||||||
|
strip = new NeoPixelBus<NeoRgbFeature, Neo800KbpsMethod>(WS2812_MAX_LEDS); // For Esp8266, the Pin is omitted and it uses GPIO3 due to DMA hardware use.
|
||||||
|
#endif // USE_WS2812_CTYPE
|
||||||
|
#else // USE_WS2812_DMA
|
||||||
|
#if (USE_WS2812_CTYPE == 1)
|
||||||
strip = new NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod>(WS2812_MAX_LEDS, pin[GPIO_WS2812]);
|
strip = new NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod>(WS2812_MAX_LEDS, pin[GPIO_WS2812]);
|
||||||
|
#else // USE_WS2812_CTYPE
|
||||||
|
strip = new NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang800KbpsMethod>(WS2812_MAX_LEDS, pin[GPIO_WS2812]);
|
||||||
|
#endif // USE_WS2812_CTYPE
|
||||||
#endif // USE_WS2812_DMA
|
#endif // USE_WS2812_DMA
|
||||||
strip->Begin();
|
strip->Begin();
|
||||||
ws2812_pixels();
|
ws2812_pixels();
|
||||||
|
|
Loading…
Reference in New Issue