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
|
||||
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.
|
||||
- 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
|
||||
* 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 week_t {Last, First, Second, Third, Fourth};
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
#define USE_HTU // Add I2C code for HTU21 sensor
|
||||
|
||||
#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)
|
||||
// When USE_WS2812_DMA is enabled expect Exceptions on Pow
|
||||
|
||||
|
|
|
@ -164,8 +164,8 @@ const char HTTP_FORM_OTHER2[] PROGMEM =
|
|||
#ifdef USE_EMULATION
|
||||
const char HTTP_FORM_OTHER3[] PROGMEM =
|
||||
"<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='1'{r3}><b>Belkin WeMo</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/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='2'{r4}><b>Hue Bridge</b><br/>";
|
||||
#endif // USE_EMULATION
|
||||
const char HTTP_FORM_END[] PROGMEM =
|
||||
|
@ -288,6 +288,28 @@ const char HUE_LIGHT_STATUS_JSON[] PROGMEM =
|
|||
"}";
|
||||
const char HUE_LIGHT_RESPONSE_JSON[] PROGMEM =
|
||||
"{\"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
|
||||
|
||||
#define DNS_PORT 53
|
||||
|
@ -1286,8 +1308,8 @@ void handleUPnPevent()
|
|||
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle WeMo basic event"));
|
||||
|
||||
String request = webServer->arg(0);
|
||||
if(request.indexOf("State>1</Binary") > 0) do_cmnd_power(1, 1);
|
||||
if(request.indexOf("State>0</Binary") > 0) do_cmnd_power(1, 0);
|
||||
if (request.indexOf("State>1</Binary") > 0) do_cmnd_power(1, 1);
|
||||
if (request.indexOf("State>0</Binary") > 0) do_cmnd_power(1, 0);
|
||||
webServer->send(200, "text/plain", "");
|
||||
}
|
||||
|
||||
|
@ -1339,6 +1361,76 @@ void hue_todo(String *path)
|
|||
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)
|
||||
{
|
||||
String response;
|
||||
|
@ -1347,7 +1439,7 @@ void hue_lights(String *path)
|
|||
uint8_t bri = 0;
|
||||
char id[4];
|
||||
|
||||
path->remove(0,path->indexOf("/lights")); // Remove until /lights
|
||||
path->remove(0,path->indexOf("/lights")); // Remove until /lights
|
||||
if (path->endsWith("/lights")) // Got /lights
|
||||
{
|
||||
response = "{\"";
|
||||
|
@ -1388,7 +1480,8 @@ void hue_lights(String *path)
|
|||
if (webServer->args() == 1)
|
||||
{
|
||||
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("false") >= 0) // false -> turn device off
|
||||
|
@ -1408,7 +1501,7 @@ void hue_lights(String *path)
|
|||
}
|
||||
#ifdef USE_WS2812
|
||||
if ((pin[GPIO_WS2812] < 99) && ((pos=json.indexOf("\"bri\":")) >= 0)) {
|
||||
bri=atoi(json.substring(pos+6).c_str());
|
||||
bri = atoi(json.substring(pos+6).c_str());
|
||||
ws2812_changeBrightness(bri);
|
||||
response += ",";
|
||||
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
|
||||
|
@ -1456,22 +1549,34 @@ void handle_hue_api(String *path)
|
|||
*/
|
||||
|
||||
char log[LOGSZ];
|
||||
uint8_t args = 0;
|
||||
|
||||
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
|
||||
else if (path->endsWith("/config")) hue_todo(path);
|
||||
else if(path->indexOf("/lights") >= 0) hue_lights(path);
|
||||
else if(path->endsWith("/groups")) hue_todo(path);
|
||||
else if(path->endsWith("/schedules")) hue_todo(path);
|
||||
else if(path->endsWith("/sensors")) hue_todo(path);
|
||||
else if(path->endsWith("/scenes")) hue_todo(path);
|
||||
else if(path->endsWith("/rules")) hue_todo(path);
|
||||
else
|
||||
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->endsWith("/groups")) hue_todo(path);
|
||||
else if (path->endsWith("/schedules")) hue_todo(path);
|
||||
else if (path->endsWith("/sensors")) hue_todo(path);
|
||||
else if (path->endsWith("/scenes")) hue_todo(path);
|
||||
else if (path->endsWith("/rules")) hue_todo(path);
|
||||
else hue_global_cfg(path);
|
||||
/*
|
||||
{
|
||||
snprintf_P(log, sizeof(log), PSTR("HTTP: Handle Hue API (%s)"),path->c_str());
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
webServer->send(406, "application/json", "{}");
|
||||
}
|
||||
*/
|
||||
}
|
||||
#endif // USE_EMULATION
|
||||
|
||||
|
|
|
@ -138,7 +138,6 @@ void hue_respondToMSearch()
|
|||
response.replace("{r3}", hue_UUID());
|
||||
portUDP.write(response.c_str());
|
||||
portUDP.endPacket();
|
||||
snprintf_P(message, sizeof(message), PSTR("Response1 sent"));
|
||||
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
||||
|
||||
response = FPSTR(HUE_RESPONSE);
|
||||
|
@ -150,7 +149,6 @@ void hue_respondToMSearch()
|
|||
response.replace("{r3}", hue_UUID());
|
||||
portUDP.write(response.c_str());
|
||||
portUDP.endPacket();
|
||||
snprintf_P(message, sizeof(message), PSTR("Response2 sent"));
|
||||
// addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
|
||||
|
||||
response = FPSTR(HUE_RESPONSE);
|
||||
|
@ -161,7 +159,8 @@ void hue_respondToMSearch()
|
|||
response.replace("{r3}", hue_UUID());
|
||||
portUDP.write(response.c_str());
|
||||
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());
|
||||
|
||||
} else {
|
||||
|
|
|
@ -31,9 +31,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <NeoPixelBus.h>
|
||||
|
||||
#ifdef USE_WS2812_DMA
|
||||
#if (USE_WS2812_CTYPE == 1)
|
||||
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;
|
||||
#else // USE_WS2812_CTYPE
|
||||
NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang800KbpsMethod> *strip = NULL;
|
||||
#endif // USE_WS2812_CTYPE
|
||||
#endif // USE_WS2812_DMA
|
||||
|
||||
#define COLOR_SATURATION 254.0f
|
||||
|
@ -457,9 +465,17 @@ void ws2812_pixels()
|
|||
void ws2812_init()
|
||||
{
|
||||
#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.
|
||||
#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]);
|
||||
#else // USE_WS2812_CTYPE
|
||||
strip = new NeoPixelBus<NeoRgbFeature, NeoEsp8266BitBang800KbpsMethod>(WS2812_MAX_LEDS, pin[GPIO_WS2812]);
|
||||
#endif // USE_WS2812_CTYPE
|
||||
#endif // USE_WS2812_DMA
|
||||
strip->Begin();
|
||||
ws2812_pixels();
|
||||
|
|
Loading…
Reference in New Issue