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:
arendst 2017-01-30 17:22:17 +01:00
parent aaf75f6acb
commit f9e8cbdfc9
8 changed files with 148 additions and 23 deletions

View File

@ -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.

View File

@ -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
*

View File

@ -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};

View File

@ -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

View File

@ -164,8 +164,8 @@ const char HTTP_FORM_OTHER2[] PROGMEM =
#ifdef USE_EMULATION
const char HTTP_FORM_OTHER3[] PROGMEM =
"<br/><fieldset><legend><b>&nbsp;Emulation&nbsp;</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;
@ -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

View File

@ -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 {

View File

@ -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();