mirror of https://github.com/arendst/Tasmota.git
v3.9.16
3.9.16 20170214 * Update latching relay handler * Add support for IR led using IRremoteESP8266 library (#59) * Add Hue argument passing using ArduinoJSON library (#59)
This commit is contained in:
parent
533855c210
commit
381bb4b50c
|
@ -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.15** - See ```sonoff/_releasenotes.ino``` for change information.
|
||||
Current version is **3.9.16** - 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.
|
@ -19,4 +19,4 @@ board = esp01_1m
|
|||
; board = esp8285
|
||||
build_flags = -Wl,-Tesp8266.flash.1m64.ld -DMQTT_MAX_PACKET_SIZE=400
|
||||
|
||||
lib_deps = PubSubClient, NeoPixelBus
|
||||
lib_deps = PubSubClient, NeoPixelBus, IRremoteESP8266, ArduinoJSON
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
/* 3.9.15 20170213
|
||||
/* 3.9.16 20170214
|
||||
* Update latching relay handler
|
||||
* Add support for IR led using IRremoteESP8266 library (#59)
|
||||
* Add Hue argument passing using ArduinoJSON library (#59)
|
||||
*
|
||||
* 3.9.15 20170213
|
||||
* Change JSON float values from string to number according to http://json.org (#56)
|
||||
* Add support for exs latched relay module https://ex-store.de/ESP8266-WiFi-Relay-V31 (#58)
|
||||
* Add support for inverted relays
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* ====================================================
|
||||
*/
|
||||
|
||||
#define VERSION 0x03090F00 // 3.9.15
|
||||
#define VERSION 0x03091000 // 3.9.16
|
||||
|
||||
//#define BE_MINIMAL // Compile a minimal version if upgrade memory gets tight (still 404k)
|
||||
// To be used as step 1. Next step is compile and use desired version
|
||||
|
@ -56,6 +56,9 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#ifdef USE_DOMOTICZ
|
||||
#undef USE_DOMOTICZ // Disable Domoticz
|
||||
#endif
|
||||
//#ifdef USE_WEBSERVER
|
||||
//#undef USE_WEBSERVER // Disable Webserver
|
||||
//#endif
|
||||
#ifdef USE_EMULATION
|
||||
#undef USE_EMULATION // Disable Wemo or Hue emulation
|
||||
#endif
|
||||
|
@ -74,6 +77,9 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#ifdef USE_DHT
|
||||
#undef USE_DHT // Disable internal DHT sensor
|
||||
#endif
|
||||
#ifdef USE_IR_REMOTE
|
||||
#undef USE_IR_REMOTE // Disable IR driver
|
||||
#endif
|
||||
#endif // BE_MINIMAL
|
||||
|
||||
#ifndef SWITCH_MODE
|
||||
|
@ -148,6 +154,12 @@ enum butt_t {PRESSED, NOT_PRESSED};
|
|||
#ifdef USE_I2C
|
||||
#include <Wire.h> // I2C support library
|
||||
#endif // USE_I2C
|
||||
#if defined USE_EMULATION || defined USE_IR_REMOTE
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
const size_t bufferSize = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(10) + 130; // Required size for complete HUE light JSON object or other JSON objects
|
||||
DynamicJsonBuffer jsonBuffer(bufferSize);
|
||||
#endif // USE_EMULATION || USE_IR_REMOTE
|
||||
|
||||
typedef void (*rtcCallback)();
|
||||
|
||||
|
@ -789,17 +801,16 @@ void getClient(char* output, const char* input, byte size)
|
|||
void setLatchingRelay(uint8_t power, uint8_t state)
|
||||
{
|
||||
power &= 1;
|
||||
if (state == 2) { // Init relay
|
||||
if (state == 2) { // Reset relay
|
||||
state = 0;
|
||||
latching_power = power;
|
||||
latching_relay_pulse = 0;
|
||||
}
|
||||
else if (state == 1) { // Set port power to On
|
||||
else if (state && !latching_relay_pulse) { // Set port power to On
|
||||
latching_power = power;
|
||||
latching_relay_pulse = 2; // max 200mS (initiated by stateloop())
|
||||
}
|
||||
else { // Set saved port to Off
|
||||
power = latching_power;
|
||||
}
|
||||
if (pin[GPIO_REL1 +power] < 99) digitalWrite(pin[GPIO_REL1 +power], rel_inverted[power] ? !state : state);
|
||||
if (pin[GPIO_REL1 +latching_power] < 99) digitalWrite(pin[GPIO_REL1 +latching_power], rel_inverted[latching_power] ? !state : state);
|
||||
}
|
||||
|
||||
void setRelay(uint8_t power)
|
||||
|
@ -1743,6 +1754,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
// Serviced
|
||||
}
|
||||
#endif // USE_WS2812
|
||||
#ifdef USE_IR_REMOTE
|
||||
else if ((pin[GPIO_IRSEND] < 99) && ir_send_command(type, index, dataBufUc, data_len, payload, svalue, sizeof(svalue))) {
|
||||
// Serviced
|
||||
}
|
||||
#endif // USE_IR_REMOTE
|
||||
else {
|
||||
type = NULL;
|
||||
}
|
||||
|
@ -1769,6 +1785,9 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
#endif // USE_I2C
|
||||
#ifdef USE_WS2812
|
||||
if (pin[GPIO_WS2812] < 99) snprintf_P(svalue, sizeof(svalue), PSTR("%s, Pixels, Led, Color, Dimmer, Scheme, Fade, Speed, Width, Wakeup, LedTable"), svalue);
|
||||
#endif
|
||||
#ifdef USE_IR_REMOTE
|
||||
if (pin[GPIO_IRSEND] < 99) snprintf_P(svalue, sizeof(svalue), PSTR("%s, IRSend"), svalue);
|
||||
#endif
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
|
||||
mqtt_publish_topic_P(0, PSTR("COMMANDS3"), svalue);
|
||||
|
@ -2540,6 +2559,10 @@ void GPIO_init()
|
|||
#ifdef USE_WS2812
|
||||
if (pin[GPIO_WS2812] < 99) ws2812_init();
|
||||
#endif // USE_WS2812
|
||||
|
||||
#ifdef USE_IR_REMOTE
|
||||
if (pin[GPIO_IRSEND] < 99) ir_send_init();
|
||||
#endif // USE_IR_REMOTE
|
||||
}
|
||||
|
||||
void setup()
|
||||
|
|
|
@ -12,11 +12,12 @@ enum upins_t {
|
|||
GPIO_I2C_SCL, // I2C SCL
|
||||
GPIO_I2C_SDA, // I2C SDA
|
||||
GPIO_WS2812, // WS2812 Led string
|
||||
GPIO_IRSEND, // IR remote
|
||||
GPIO_SWT1, // User connected external switches
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
// Text in webpage Module Parameters and commands GPIOS and GPIO
|
||||
const char sensors[GPIO_SENSOR_END][8] PROGMEM = {
|
||||
const char sensors[GPIO_SENSOR_END][9] PROGMEM = {
|
||||
"None",
|
||||
"DHT11",
|
||||
"AM2301",
|
||||
|
@ -25,6 +26,7 @@ const char sensors[GPIO_SENSOR_END][8] PROGMEM = {
|
|||
"I2C SCL",
|
||||
"I2C SDA",
|
||||
"WS2812",
|
||||
"IRremote",
|
||||
"Switch" };
|
||||
|
||||
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
||||
|
@ -257,7 +259,7 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
|
|||
{ "EXS Relay", // Latching relay https://ex-store.de/ESP8266-WiFi-Relay-V31
|
||||
// Module Pin 1 VCC 3V3, Module Pin 6 GND
|
||||
GPIO_KEY1, // GPIO00 Module Pin 8 - Button (firmware flash)
|
||||
GPIO_USER, // GPIO01 Module Pin 2 = UART0_TXD
|
||||
0, // GPIO01 Module Pin 2 = UART0_TXD
|
||||
GPIO_USER, // GPIO02 Module Pin 7
|
||||
GPIO_USER, // GPIO03 Module Pin 3 = UART0_RXD
|
||||
GPIO_USER, // GPIO04 Module Pin 10
|
||||
|
|
|
@ -994,7 +994,7 @@ void addLog(byte loglevel, const char *line)
|
|||
#endif // DEBUG_ESP_PORT
|
||||
if (loglevel <= seriallog_level) Serial.printf("%s %s\n", mxtime, line);
|
||||
#ifdef USE_WEBSERVER
|
||||
if (loglevel <= sysCfg.weblog_level) {
|
||||
if (sysCfg.webserver && (loglevel <= sysCfg.weblog_level)) {
|
||||
Log[logidx] = String(mxtime) + " " + String(line);
|
||||
logidx++;
|
||||
if (logidx > MAX_LOG_LINES -1) logidx = 0;
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional)
|
||||
|
||||
// -- HTTP ----------------------------------------
|
||||
#define USE_WEBSERVER // Enable web server and wifi manager (+60k code, +4k mem) - Disable by //
|
||||
#define USE_WEBSERVER // Enable web server and wifi manager (+62k code, +4k mem) - Disable by //
|
||||
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
|
||||
#define WEB_SERVER 2 // [WebServer] Web server (0 = Off, 1 = Start as User, 2 = Start as Admin)
|
||||
#define USE_EMULATION // Enable Belkin WeMo and Hue Bridge emulation for Alexa (+11k code, +2k mem)
|
||||
|
@ -124,6 +124,8 @@
|
|||
#define USE_BMP // Add I2C code for BMP/BME280 sensor
|
||||
#define USE_HTU // Add I2C code for HTU21 sensor
|
||||
|
||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0.3k mem)
|
||||
|
||||
#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+8k code, +1k mem) - Disable by //
|
||||
#define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB)
|
||||
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial TXD) (+1k mem)
|
||||
|
|
|
@ -1497,6 +1497,7 @@ void hue_lights(String *path)
|
|||
uint8_t device = 1;
|
||||
int16_t pos = 0;
|
||||
uint8_t bri = 0;
|
||||
bool on = false;
|
||||
char id[4];
|
||||
|
||||
path->remove(0,path->indexOf("/lights")); // Remove until /lights
|
||||
|
@ -1539,29 +1540,22 @@ void hue_lights(String *path)
|
|||
response.replace("{cmd}", "state/on");
|
||||
if (webServer->args() == 1)
|
||||
{
|
||||
String json = webServer->arg(0);
|
||||
json.replace(" ",""); // remove blanks
|
||||
|
||||
if (json.indexOf("\"on\":") >= 0) // Got "on" command
|
||||
JsonObject &hue_json = jsonBuffer.parseObject(webServer->arg(0));
|
||||
on = hue_json["on"];
|
||||
switch(on)
|
||||
{
|
||||
if (json.indexOf("false") >= 0) // false -> turn device off
|
||||
{
|
||||
do_cmnd_power(device, 0);
|
||||
response.replace("{res}", "false");
|
||||
}
|
||||
else if(json.indexOf("true") >= 0) // true -> Turn device on
|
||||
{
|
||||
do_cmnd_power(device, 1);
|
||||
response.replace("{res}", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
response.replace("{res}", (power & (0x01 << (device-1))) ? "true" : "false");
|
||||
}
|
||||
case false : do_cmnd_power(device, 0);
|
||||
response.replace("{res}", "false");
|
||||
break;
|
||||
case true : do_cmnd_power(device, 1);
|
||||
response.replace("{res}", "true");
|
||||
break;
|
||||
default : response.replace("{res}", (power & (0x01 << (device-1))) ? "true" : "false");
|
||||
break;
|
||||
}
|
||||
#ifdef USE_WS2812
|
||||
if ((pin[GPIO_WS2812] < 99) && ((pos=json.indexOf("\"bri\":")) >= 0)) {
|
||||
bri = atoi(json.substring(pos+6).c_str());
|
||||
bri = hue_json["bri"];
|
||||
if (pin[GPIO_WS2812] < 99) {
|
||||
ws2812_changeBrightness(bri);
|
||||
response += ",";
|
||||
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
|
||||
|
@ -1620,7 +1614,7 @@ void handle_hue_api(String *path)
|
|||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
|
||||
if (path->endsWith("/invalid/")) {} // Just ignore
|
||||
if (path->endsWith("/invalid/")) {} // Just ignore
|
||||
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);
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Copyright (c) 2017 Heiko Krupp and Theo Arends. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef USE_IR_REMOTE
|
||||
/*********************************************************************************************\
|
||||
* IR Remote send using IRremoteESP8266 library
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include <IRremoteESP8266.h>
|
||||
|
||||
IRsend *irsend = NULL;
|
||||
|
||||
void ir_send_init(void)
|
||||
{
|
||||
irsend = new IRsend(pin[GPIO_IRSEND]); // an IR led is at GPIO_IRSEND
|
||||
irsend->begin();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Commands
|
||||
\*********************************************************************************************/
|
||||
|
||||
boolean ir_send_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
|
||||
{
|
||||
boolean serviced = true;
|
||||
boolean error = false;
|
||||
const char *protocol;
|
||||
uint8_t bits = 0;
|
||||
uint32_t data = 0;
|
||||
|
||||
if (!strcmp(type,"IRSEND")) {
|
||||
if (data_len) {
|
||||
JsonObject &ir_json = jsonBuffer.parseObject(dataBuf);
|
||||
if (!ir_json.success()) {
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"Invalid JSON\"}")); // JSON decode failed
|
||||
} else {
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"Done\"}"));
|
||||
protocol = ir_json["PROTOCOL"];
|
||||
bits = ir_json["BITS"];
|
||||
data = ir_json["DATA"];
|
||||
if (protocol && bits && data) {
|
||||
if (!strcmp(protocol,"NEC")) irsend->sendNEC(data, bits);
|
||||
else if (!strcmp(protocol,"SONY")) irsend->sendSony(data, bits);
|
||||
else if (!strcmp(protocol,"RC5")) irsend->sendRC5(data, bits);
|
||||
else if (!strcmp(protocol,"RC6")) irsend->sendRC6(data, bits);
|
||||
else if (!strcmp(protocol,"DISH")) irsend->sendDISH(data, bits);
|
||||
else if (!strcmp(protocol,"JVC")) irsend->sendJVC(data, bits, 1);
|
||||
else if (!strcmp(protocol,"SAMSUNG")) irsend->sendSAMSUNG(data, bits);
|
||||
else {
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"Protocol not supported\"}"));
|
||||
}
|
||||
} else error = true;
|
||||
}
|
||||
} else error = true;
|
||||
if (error) snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"No protocol, bits or data\"}"));
|
||||
}
|
||||
else {
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
return serviced;
|
||||
}
|
||||
#endif // USE_IR_REMOTE
|
|
@ -579,7 +579,7 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_
|
|||
snprintf_P(svalue, ssvalue, PSTR("{\"Scheme\":%d}"), sysCfg.ws_scheme);
|
||||
}
|
||||
else {
|
||||
serviced = false;
|
||||
serviced = false; // Unknown command
|
||||
}
|
||||
return serviced;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue