mirror of https://github.com/arendst/Tasmota.git
v4.1.2
4.1.2 20170403 * Rename Unrecognised command to Unknown command * Remove all command lists * Remove command SmartConfig (superseded by WifiConfig) * Fix boot loop when selecting module Sonoff 4CH or Sonoff Touch on non ESP8285 hardware * Add optional support for Toshiba and Mitsubishi HVAC IR control (needs updated IRanother (#257) * Add all configured switches to Domoticz Configuration web page (#305) * Fix compile error when selecting WS2812 DMA (#313)
This commit is contained in:
parent
6824c8ac8a
commit
fcb380ce2c
|
@ -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 **4.1.1** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
Current version is **4.1.2** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/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.
Binary file not shown.
|
@ -1,4 +1,13 @@
|
||||||
/* 4.1.1 20170329
|
/* 4.1.2 20170403
|
||||||
|
* Rename Unrecognised command to Unknown command
|
||||||
|
* Remove all command lists
|
||||||
|
* Remove command SmartConfig (superseded by WifiConfig)
|
||||||
|
* Fix boot loop when selecting module Sonoff 4CH or Sonoff Touch on non ESP8285 hardware
|
||||||
|
* Add optional support for Toshiba and Mitsubishi HVAC IR control (needs updated IRanother (#257)
|
||||||
|
* Add all configured switches to Domoticz Configuration web page (#305)
|
||||||
|
* Fix compile error when selecting WS2812 DMA (#313)
|
||||||
|
*
|
||||||
|
* 4.1.1 20170329
|
||||||
* Fix default Telemetry for command Prefix3
|
* Fix default Telemetry for command Prefix3
|
||||||
* Fix webserver Module parameters for disabled select
|
* Fix webserver Module parameters for disabled select
|
||||||
* Fix sensor status for enabled switches
|
* Fix sensor status for enabled switches
|
||||||
|
|
|
@ -125,12 +125,15 @@ int spiffsflag = 0;
|
||||||
/*
|
/*
|
||||||
* Based on cores/esp8266/Updater.cpp
|
* Based on cores/esp8266/Updater.cpp
|
||||||
*/
|
*/
|
||||||
void setFlashChipMode(byte option, byte mode)
|
void setFlashMode(byte option, byte mode)
|
||||||
{
|
{
|
||||||
char log[LOGSZ];
|
char log[LOGSZ];
|
||||||
uint8_t *_buffer;
|
uint8_t *_buffer;
|
||||||
uint32_t address;
|
uint32_t address;
|
||||||
|
|
||||||
|
// option 0 - Use absolute address 0
|
||||||
|
// option 1 - Use OTA/Upgrade relative address
|
||||||
|
|
||||||
if (option) {
|
if (option) {
|
||||||
eboot_command ebcmd;
|
eboot_command ebcmd;
|
||||||
eboot_command_read(&ebcmd);
|
eboot_command_read(&ebcmd);
|
||||||
|
@ -147,13 +150,20 @@ void setFlashChipMode(byte option, byte mode)
|
||||||
spi_flash_write(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE);
|
spi_flash_write(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE);
|
||||||
}
|
}
|
||||||
interrupts();
|
interrupts();
|
||||||
snprintf_P(log, sizeof(log), PSTR("FLSH: Updated Flash Chip Mode to %d"), (option) ? mode : ESP.getFlashChipMode());
|
snprintf_P(log, sizeof(log), PSTR("FLSH: Set Flash Mode to %d"), (option) ? mode : ESP.getFlashChipMode());
|
||||||
addLog(LOG_LEVEL_DEBUG, log);
|
addLog(LOG_LEVEL_DEBUG, log);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete[] _buffer;
|
delete[] _buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setModuleFlashMode(byte option)
|
||||||
|
{
|
||||||
|
uint8_t mode = 0; // QIO - ESP8266
|
||||||
|
if ((sysCfg.module == SONOFF_TOUCH) || (sysCfg.module == SONOFF_4CH)) mode = 3; // DOUT - ESP8285
|
||||||
|
setFlashMode(option, mode);
|
||||||
|
}
|
||||||
|
|
||||||
boolean spiffsPresent()
|
boolean spiffsPresent()
|
||||||
{
|
{
|
||||||
return (SPIFFS_END - SPIFFS_START);
|
return (SPIFFS_END - SPIFFS_START);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* ====================================================
|
* ====================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VERSION 0x04010100 // 4.1.1
|
#define VERSION 0x04010200 // 4.1.2
|
||||||
|
|
||||||
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};
|
||||||
|
@ -541,7 +541,7 @@ void mqtt_reconnect()
|
||||||
#ifdef USE_MQTT_TLS
|
#ifdef USE_MQTT_TLS
|
||||||
addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Verify TLS fingerprint..."));
|
addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Verify TLS fingerprint..."));
|
||||||
if (!espClient.connect(sysCfg.mqtt_host, sysCfg.mqtt_port)) {
|
if (!espClient.connect(sysCfg.mqtt_host, sysCfg.mqtt_port)) {
|
||||||
snprintf_P(log, sizeof(log), PSTR("MQTT: TLS CONNECT FAILED USING WRONG MQTTHost (%s) or MQTTPort (%d). Retry in %d seconds"),
|
snprintf_P(log, sizeof(log), PSTR("MQTT: TLS Connect FAILED to %s:%d. Retry in %d seconds"),
|
||||||
sysCfg.mqtt_host, sysCfg.mqtt_port, mqttcounter);
|
sysCfg.mqtt_host, sysCfg.mqtt_port, mqttcounter);
|
||||||
addLog(LOG_LEVEL_DEBUG, log);
|
addLog(LOG_LEVEL_DEBUG, log);
|
||||||
return;
|
return;
|
||||||
|
@ -549,7 +549,7 @@ void mqtt_reconnect()
|
||||||
if (espClient.verify(sysCfg.mqtt_fingerprint, sysCfg.mqtt_host)) {
|
if (espClient.verify(sysCfg.mqtt_fingerprint, sysCfg.mqtt_host)) {
|
||||||
addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Verified"));
|
addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Verified"));
|
||||||
} else {
|
} else {
|
||||||
addLog_P(LOG_LEVEL_DEBUG, PSTR("MQTT: WARNING - Insecure connection due to invalid Fingerprint"));
|
addLog_P(LOG_LEVEL_DEBUG, PSTR("MQTT: Insecure connection due to invalid Fingerprint"));
|
||||||
}
|
}
|
||||||
#endif // USE_MQTT_TLS
|
#endif // USE_MQTT_TLS
|
||||||
mqttClient.setCallback(mqttDataCb);
|
mqttClient.setCallback(mqttDataCb);
|
||||||
|
@ -613,7 +613,8 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
|
||||||
else if (!strcmp(type,"STATETEXT") && (index > 0) && (index <= 3)) {
|
else if (!strcmp(type,"STATETEXT") && (index > 0) && (index <= 3)) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.state_text[0]))) {
|
if ((data_len > 0) && (data_len < sizeof(sysCfg.state_text[0]))) {
|
||||||
for(i = 0; i <= data_len; i++) if (dataBuf[i] == ' ') dataBuf[i] = '_';
|
for(i = 0; i <= data_len; i++) if (dataBuf[i] == ' ') dataBuf[i] = '_';
|
||||||
strlcpy(sysCfg.state_text[index -1], (payload == 1) ? (index==1)?MQTT_STATUS_OFF:(index==2)?MQTT_STATUS_ON:MQTT_CMND_TOGGLE : dataBuf, sizeof(sysCfg.state_text[0]));
|
// strlcpy(sysCfg.state_text[index -1], (payload == 1) ? (index==1)?MQTT_STATUS_OFF:(index==2)?MQTT_STATUS_ON:MQTT_CMND_TOGGLE : dataBuf, sizeof(sysCfg.state_text[0]));
|
||||||
|
strlcpy(sysCfg.state_text[index -1], dataBuf, sizeof(sysCfg.state_text[0]));
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"StateText%d\":\"%s\"}"), index, getStateText(index -1));
|
snprintf_P(svalue, ssvalue, PSTR("{\"StateText%d\":\"%s\"}"), index, getStateText(index -1));
|
||||||
}
|
}
|
||||||
|
@ -899,7 +900,10 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
payload--;
|
payload--;
|
||||||
byte new_modflg = (sysCfg.module != payload);
|
byte new_modflg = (sysCfg.module != payload);
|
||||||
sysCfg.module = payload;
|
sysCfg.module = payload;
|
||||||
if (new_modflg) for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;
|
if (new_modflg) {
|
||||||
|
for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;
|
||||||
|
setModuleFlashMode(0);
|
||||||
|
}
|
||||||
restartflag = 2;
|
restartflag = 2;
|
||||||
}
|
}
|
||||||
snprintf_P(stemp1, sizeof(stemp1), modules[sysCfg.module].name);
|
snprintf_P(stemp1, sizeof(stemp1), modules[sysCfg.module].name);
|
||||||
|
@ -997,11 +1001,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.value_units) ? " mS" : "");
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.value_units) ? " mS" : "");
|
||||||
}
|
}
|
||||||
else if (!strcmp(type,"FLASHCHIPMODE")) {
|
else if (!strcmp(type,"FLASHMODE")) { // 0 = QIO, 1 = QOUT, 2 = DIO, 3 = DOUT
|
||||||
if ((data_len > 0) && (payload >= 0) && (payload <= 3)) {
|
if ((data_len > 0) && (payload >= 0) && (payload <= 3)) {
|
||||||
if (ESP.getFlashChipMode() != payload) setFlashChipMode(0, payload &3);
|
if (ESP.getFlashChipMode() != payload) setFlashMode(0, payload &3);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"FlashChipMode\":%d}"), ESP.getFlashChipMode());
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"FlashMode\":%d}"), ESP.getFlashChipMode());
|
||||||
}
|
}
|
||||||
else if (!strcmp(type,"UPGRADE") || !strcmp(type,"UPLOAD")) {
|
else if (!strcmp(type,"UPGRADE") || !strcmp(type,"UPLOAD")) {
|
||||||
if ((data_len > 0) && (payload == 1)) {
|
if ((data_len > 0) && (payload == 1)) {
|
||||||
|
@ -1098,7 +1102,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Hostname\":\"%s\"}"), sysCfg.hostname);
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Hostname\":\"%s\"}"), sysCfg.hostname);
|
||||||
}
|
}
|
||||||
else if (!strcmp(type,"WIFICONFIG") || !strcmp(type,"SMARTCONFIG")) {
|
else if (!strcmp(type,"WIFICONFIG")) {
|
||||||
if ((data_len > 0) && (payload >= WIFI_RESTART) && (payload < MAX_WIFI_OPTION)) {
|
if ((data_len > 0) && (payload >= WIFI_RESTART) && (payload < MAX_WIFI_OPTION)) {
|
||||||
sysCfg.sta_config = payload;
|
sysCfg.sta_config = payload;
|
||||||
wificheckflag = sysCfg.sta_config;
|
wificheckflag = sysCfg.sta_config;
|
||||||
|
@ -1267,47 +1271,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
||||||
}
|
}
|
||||||
if (type == NULL) {
|
if (type == NULL) {
|
||||||
blinks = 201;
|
blinks = 201;
|
||||||
/*
|
snprintf_P(topicBuf, sizeof(topicBuf), PSTR("COMMAND"));
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands1\":\"Status, SaveData, SaveSate, Sleep, Upgrade, Otaurl, Restart, Reset, WifiConfig, Seriallog, Syslog, LogHost, LogPort, SSId, Password, AP, IPAddres, NTPServer, Hostname, Module, Modules, GPIO, GPIOs\"}"));
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Command\":\"Unknown\"}"));
|
||||||
mqtt_publish_topic_P(0, PSTR("COMMANDS1"), svalue);
|
type = (char*)topicBuf;
|
||||||
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands2\":\"Mqtt, MqttResponse, MqttHost, MqttPort, MqttUser, MqttPassword, MqttClient, Topic, GroupTopic, ButtonTopic, ButtonRetain, SwitchTopic, SwitchRetain, PowerRetain, Units, Timezone, LedState, LedPower, TelePeriod\"}"));
|
|
||||||
mqtt_publish_topic_P(0, PSTR("COMMANDS2"), svalue);
|
|
||||||
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Commands3\":\"Power%s, PulseTime, BlinkTime, BlinkCount, ButtonRestrict"), (sysCfg.module != MOTOR) ? ", PowerOnState" : "");
|
|
||||||
#ifdef USE_WEBSERVER
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver, WebPassword, Emulation"), svalue);
|
|
||||||
#endif
|
|
||||||
if (swt_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, SwitchMode"), svalue);
|
|
||||||
if (pwm_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, PWM"), svalue);
|
|
||||||
#ifdef USE_I2C
|
|
||||||
if (i2c_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, I2CScan"), svalue);
|
|
||||||
#endif // USE_I2C
|
|
||||||
if (sysCfg.module == SONOFF_LED) snprintf_P(svalue, sizeof(svalue), PSTR("%s, Color, Dimmer, Fade, Speed, Wakeup, WakeupDuration, LedTable"), svalue);
|
|
||||||
#ifdef USE_WS2812
|
|
||||||
if (pin[GPIO_WS2812] < 99) snprintf_P(svalue, sizeof(svalue), PSTR("%s, Color, Dimmer, Fade, Speed, Wakeup, LedTable, Pixels, Led, Width, Scheme"), 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);
|
|
||||||
|
|
||||||
#ifdef USE_DOMOTICZ
|
|
||||||
domoticz_commands(svalue, sizeof(svalue));
|
|
||||||
mqtt_publish_topic_P(0, PSTR("COMMANDS4"), svalue);
|
|
||||||
#endif // USE_DOMOTICZ
|
|
||||||
|
|
||||||
if (hlw_flg) {
|
|
||||||
hlw_commands(svalue, sizeof(svalue));
|
|
||||||
mqtt_publish_topic_P(0, PSTR("COMMANDS5"), svalue);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"Command\":\"Invalid command\"}"));
|
|
||||||
mqtt_publish_topic_P(0, PSTR("COMMAND"), svalue);
|
|
||||||
} else {
|
|
||||||
mqtt_publish_topic_P(4, type, svalue);
|
|
||||||
}
|
}
|
||||||
|
mqtt_publish_topic_P(4, type, svalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
@ -1465,7 +1433,7 @@ void publish_status(uint8_t payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((payload == 0) || (payload == 4)) {
|
if ((payload == 0) || (payload == 4)) {
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMEM\":{\"ProgramSize\":%d, \"Free\":%d, \"Heap\":%d, \"SpiffsStart\":%d, \"SpiffsSize\":%d, \"FlashSize\":%d, \"ProgramFlashSize\":%d, \"FlashChipMode\":%d}}"),
|
snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMEM\":{\"ProgramSize\":%d, \"Free\":%d, \"Heap\":%d, \"SpiffsStart\":%d, \"SpiffsSize\":%d, \"FlashSize\":%d, \"ProgramFlashSize\":%d, \"FlashMode\":%d}}"),
|
||||||
ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ((uint32_t)&_SPIFFS_start - 0x40200000)/1024,
|
ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ((uint32_t)&_SPIFFS_start - 0x40200000)/1024,
|
||||||
(((uint32_t)&_SPIFFS_end - 0x40200000) - ((uint32_t)&_SPIFFS_start - 0x40200000))/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipMode());
|
(((uint32_t)&_SPIFFS_end - 0x40200000) - ((uint32_t)&_SPIFFS_start - 0x40200000))/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipMode());
|
||||||
mqtt_publish_topic_P(option, PSTR("STATUS4"), svalue);
|
mqtt_publish_topic_P(option, PSTR("STATUS4"), svalue);
|
||||||
|
@ -1879,7 +1847,7 @@ void stateloop()
|
||||||
if (otaflag == 90) { // Allow MQTT to reconnect
|
if (otaflag == 90) { // Allow MQTT to reconnect
|
||||||
otaflag = 0;
|
otaflag = 0;
|
||||||
if (otaok) {
|
if (otaok) {
|
||||||
if ((sysCfg.module == SONOFF_TOUCH) || (sysCfg.module == SONOFF_4CH)) setFlashChipMode(1, 3); // DOUT - ESP8285
|
setModuleFlashMode(1); // QIO - ESP8266, DOUT - ESP8285 (Sonoff 4CH and Touch)
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("Successful. Restarting"));
|
snprintf_P(svalue, sizeof(svalue), PSTR("Successful. Restarting"));
|
||||||
} else {
|
} else {
|
||||||
snprintf_P(svalue, sizeof(svalue), PSTR("Failed %s"), ESPhttpUpdate.getLastErrorString().c_str());
|
snprintf_P(svalue, sizeof(svalue), PSTR("Failed %s"), ESPhttpUpdate.getLastErrorString().c_str());
|
||||||
|
@ -2160,7 +2128,7 @@ void setup()
|
||||||
|
|
||||||
if (Serial.baudRate() != Baudrate) {
|
if (Serial.baudRate() != Baudrate) {
|
||||||
if (seriallog_level) {
|
if (seriallog_level) {
|
||||||
snprintf_P(log, sizeof(log), PSTR("APP: Change baudrate to %d and Serial logging will be disabled in %d seconds"), Baudrate, seriallog_timer);
|
snprintf_P(log, sizeof(log), PSTR("APP: Change your baudrate to %d"), Baudrate);
|
||||||
addLog(LOG_LEVEL_INFO, log);
|
addLog(LOG_LEVEL_INFO, log);
|
||||||
}
|
}
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
|
@ -23,6 +23,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const char JSON_SNS_TEMPHUM[] PROGMEM =
|
||||||
|
"%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}";
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Watchdog extension (https://github.com/esp8266/Arduino/issues/1532)
|
* Watchdog extension (https://github.com/esp8266/Arduino/issues/1532)
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -34,7 +37,11 @@ Ticker tickerOSWatch;
|
||||||
static unsigned long osw_last_loop;
|
static unsigned long osw_last_loop;
|
||||||
byte osw_flag = 0;
|
byte osw_flag = 0;
|
||||||
|
|
||||||
void ICACHE_RAM_ATTR osw_osWatch(void)
|
#ifndef USE_WS2812_DMA // Collides with Neopixelbus but solves exception
|
||||||
|
void osw_osWatch() ICACHE_RAM_ATTR;
|
||||||
|
#endif // USE_WS2812_DMA
|
||||||
|
|
||||||
|
void osw_osWatch()
|
||||||
{
|
{
|
||||||
unsigned long t = millis();
|
unsigned long t = millis();
|
||||||
unsigned long last_run = abs(t - osw_last_loop);
|
unsigned long last_run = abs(t - osw_last_loop);
|
||||||
|
@ -599,7 +606,7 @@ void i2c_scan(char *devs, unsigned int devs_len)
|
||||||
strncat(devs, tstr, devs_len);
|
strncat(devs, tstr, devs_len);
|
||||||
any = 1;
|
any = 1;
|
||||||
}
|
}
|
||||||
else if (error == 4) snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"Unknow error at 0x%2x\"}"), address);
|
else if (error == 4) snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"Unknown error at 0x%2x\"}"), address);
|
||||||
}
|
}
|
||||||
if (any) {
|
if (any) {
|
||||||
strncat(devs, "\"}", devs_len);
|
strncat(devs, "\"}", devs_len);
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
#define WEB_PASSWORD "" // [WebPassword] Web server Admin mode Password for WEB_USERNAME (empty string = Disable)
|
#define WEB_PASSWORD "" // [WebPassword] Web server Admin mode Password for WEB_USERNAME (empty string = Disable)
|
||||||
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
|
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
|
||||||
#define USE_EMULATION // Enable Belkin WeMo and Hue Bridge emulation for Alexa (+11k code, +2k mem)
|
#define USE_EMULATION // Enable Belkin WeMo and Hue Bridge emulation for Alexa (+11k code, +2k mem)
|
||||||
#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo or Hue Bridge emulation (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
|
#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo (single relay/light) or Hue Bridge emulation (multi relay/light) (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
|
||||||
|
|
||||||
// -- mDNS ----------------------------------------
|
// -- mDNS ----------------------------------------
|
||||||
#define USE_DISCOVERY // Enable mDNS for the following services (+8k code, +0.3k mem) - Disable by //
|
#define USE_DISCOVERY // Enable mDNS for the following services (+8k code, +0.3k mem) - Disable by //
|
||||||
|
@ -138,6 +138,7 @@
|
||||||
#define USE_SHT // Add I2C emulating code for SHT1X sensor
|
#define USE_SHT // Add I2C emulating code for SHT1X sensor
|
||||||
|
|
||||||
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+3k code, 0.3k mem)
|
#define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+3k code, 0.3k mem)
|
||||||
|
// #define USE_IR_HVAC // Support for HVAC system using IR (+2k code)
|
||||||
|
|
||||||
#define USE_WS2812 // WS2812 Led string using library NeoPixelBus (+8k code, +1k mem) - Disable by //
|
#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_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB)
|
||||||
|
|
|
@ -103,7 +103,6 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM =
|
||||||
"t=document.getElementById('t1');"
|
"t=document.getElementById('t1');"
|
||||||
"if(p==1){"
|
"if(p==1){"
|
||||||
"c=document.getElementById('c1');"
|
"c=document.getElementById('c1');"
|
||||||
// "o='&c1='+c.value;"
|
|
||||||
"o='&c1='+encodeURI(c.value);"
|
"o='&c1='+encodeURI(c.value);"
|
||||||
"c.value='';"
|
"c.value='';"
|
||||||
"t.scrollTop=sn;"
|
"t.scrollTop=sn;"
|
||||||
|
@ -223,8 +222,8 @@ const char HTTP_FORM_OTHER2[] PROGMEM =
|
||||||
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/><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='1'{r3}><b>Belkin WeMo</b> single device"
|
||||||
"<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> multi devices<br/>";
|
||||||
#endif // USE_EMULATION
|
#endif // USE_EMULATION
|
||||||
const char HTTP_FORM_END[] PROGMEM =
|
const char HTTP_FORM_END[] PROGMEM =
|
||||||
"<br/><button type='submit'>Save</button></form></fieldset>";
|
"<br/><button type='submit'>Save</button></form></fieldset>";
|
||||||
|
@ -258,6 +257,8 @@ const char HTTP_FORM_CMND[] PROGMEM =
|
||||||
"<input style='width:98%' id='c1' name='c1' length='99' placeholder='Enter command' autofocus><br/>"
|
"<input style='width:98%' id='c1' name='c1' length='99' placeholder='Enter command' autofocus><br/>"
|
||||||
// "<br/><button type='submit'>Send command</button>"
|
// "<br/><button type='submit'>Send command</button>"
|
||||||
"</form>";
|
"</form>";
|
||||||
|
const char HTTP_TABLE100[] PROGMEM =
|
||||||
|
"<table style='width:100%'>";
|
||||||
const char HTTP_COUNTER[] PROGMEM =
|
const char HTTP_COUNTER[] PROGMEM =
|
||||||
"<br/><div id='t' name='t' style='text-align:center;'></div>";
|
"<br/><div id='t' name='t' style='text-align:center;'></div>";
|
||||||
const char HTTP_SNS_TEMP[] PROGMEM =
|
const char HTTP_SNS_TEMP[] PROGMEM =
|
||||||
|
@ -420,7 +421,8 @@ void handleRoot()
|
||||||
sysCfg.led_dimmer[0]);
|
sysCfg.led_dimmer[0]);
|
||||||
page += line;
|
page += line;
|
||||||
}
|
}
|
||||||
page += F("<table style='width:100%'><tr>");
|
page += FPSTR(HTTP_TABLE100);
|
||||||
|
page += F("<tr>");
|
||||||
for (byte idx = 1; idx <= Maxdevice; idx++) {
|
for (byte idx = 1; idx <= Maxdevice; idx++) {
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), idx);
|
snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), idx);
|
||||||
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>Toggle%s</button></td>"),
|
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>Toggle%s</button></td>"),
|
||||||
|
@ -477,16 +479,18 @@ void handleAjax2()
|
||||||
#endif // USE_I2C
|
#endif // USE_I2C
|
||||||
String page = "";
|
String page = "";
|
||||||
if (tpage.length() > 0) {
|
if (tpage.length() > 0) {
|
||||||
page += F("<table style='width:100%'>");
|
page += FPSTR(HTTP_TABLE100);
|
||||||
page += tpage;
|
page += tpage;
|
||||||
page += F("</table>");
|
page += F("</table>");
|
||||||
}
|
}
|
||||||
char line[120];
|
char line[120];
|
||||||
if (Maxdevice) {
|
if (Maxdevice) {
|
||||||
page += F("<table style='width:100%'><tr>");
|
page += FPSTR(HTTP_TABLE100);
|
||||||
|
page += F("<tr>");
|
||||||
for (byte idx = 1; idx <= Maxdevice; idx++) {
|
for (byte idx = 1; idx <= Maxdevice; idx++) {
|
||||||
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:bold;font-size:%dpx'>%s</div></td>"),
|
snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><div style='text-align:center;font-weight:bold;font-size:%dpx'>%s</div></td>"),
|
||||||
100 / Maxdevice, 70 - (Maxdevice * 8), (power & (0x01 << (idx -1))) ? "ON" : "OFF");
|
// 100 / Maxdevice, 70 - (Maxdevice * 8), (power & (0x01 << (idx -1))) ? "ON" : "OFF");
|
||||||
|
100 / Maxdevice, 70 - (Maxdevice * 8), getStateText(bitRead(power, idx -1)));
|
||||||
page += line;
|
page += line;
|
||||||
}
|
}
|
||||||
page += F("</tr></table>");
|
page += F("</tr></table>");
|
||||||
|
@ -528,6 +532,8 @@ void handleConfig()
|
||||||
|
|
||||||
boolean inModule(byte val, uint8_t *arr)
|
boolean inModule(byte val, uint8_t *arr)
|
||||||
{
|
{
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
if (!val) return false; // None
|
if (!val) return false; // None
|
||||||
#ifndef USE_I2C
|
#ifndef USE_I2C
|
||||||
if (val == GPIO_I2C_SCL) return true;
|
if (val == GPIO_I2C_SCL) return true;
|
||||||
|
@ -539,8 +545,11 @@ boolean inModule(byte val, uint8_t *arr)
|
||||||
#ifndef USE_IR_REMOTE
|
#ifndef USE_IR_REMOTE
|
||||||
if (val == GPIO_IRSEND) return true;
|
if (val == GPIO_IRSEND) return true;
|
||||||
#endif
|
#endif
|
||||||
|
if (((val >= GPIO_REL1) && (val <= GPIO_REL4)) || ((val >= GPIO_LED1) && (val <= GPIO_LED4))) offset = 4;
|
||||||
|
if (((val >= GPIO_REL1_INV) && (val <= GPIO_REL4_INV)) || ((val >= GPIO_LED1_INV) && (val <= GPIO_LED4_INV))) offset = -4;
|
||||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||||
if (arr[i] == val) return true;
|
if (arr[i] == val) return true;
|
||||||
|
if (arr[i] == val + offset) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -905,12 +914,14 @@ void handleSave()
|
||||||
memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
|
memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
|
||||||
String gpios = "";
|
String gpios = "";
|
||||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||||
|
if (new_modflg) sysCfg.my_module.gp.io[i] = 0;
|
||||||
if (cmodule.gp.io[i] == GPIO_USER) {
|
if (cmodule.gp.io[i] == GPIO_USER) {
|
||||||
snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
|
snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
|
||||||
sysCfg.my_module.gp.io[i] = (new_modflg) ? 0 : (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
|
sysCfg.my_module.gp.io[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
|
||||||
gpios += F(", GPIO"); gpios += String(i); gpios += F(" "); gpios += String(sysCfg.my_module.gp.io[i]);
|
gpios += F(", GPIO"); gpios += String(i); gpios += F(" "); gpios += String(sysCfg.my_module.gp.io[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setModuleFlashMode(0);
|
||||||
snprintf_P(stemp, sizeof(stemp), modules[sysCfg.module].name);
|
snprintf_P(stemp, sizeof(stemp), modules[sysCfg.module].name);
|
||||||
snprintf_P(log, sizeof(log), PSTR("HTTP: %s Module%s"), stemp, gpios.c_str());
|
snprintf_P(log, sizeof(log), PSTR("HTTP: %s Module%s"), stemp, gpios.c_str());
|
||||||
addLog(LOG_LEVEL_INFO, log);
|
addLog(LOG_LEVEL_INFO, log);
|
||||||
|
@ -1118,7 +1129,7 @@ void handleUploadLoop()
|
||||||
}
|
}
|
||||||
if ((sysCfg.module == SONOFF_TOUCH) || (sysCfg.module == SONOFF_4CH)) {
|
if ((sysCfg.module == SONOFF_TOUCH) || (sysCfg.module == SONOFF_4CH)) {
|
||||||
upload.buf[2] = 3; // DOUT - ESP8285
|
upload.buf[2] = 3; // DOUT - ESP8285
|
||||||
addLog_P(LOG_LEVEL_DEBUG, PSTR("FLSH: Updated Flash Chip Mode to 3"));
|
addLog_P(LOG_LEVEL_DEBUG, PSTR("FLSH: Set Flash Mode to 3"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,15 @@ const char HTTP_FORM_DOMOTICZ[] PROGMEM =
|
||||||
"<br/><table style='width:97%'>"
|
"<br/><table style='width:97%'>"
|
||||||
"<tr><td><b>In topic</b> (" DOMOTICZ_IN_TOPIC ")</td><td style='width:30%'><input id='it' name='it' length=32 placeholder='" DOMOTICZ_IN_TOPIC "' value='{d1}'></td></tr>"
|
"<tr><td><b>In topic</b> (" DOMOTICZ_IN_TOPIC ")</td><td style='width:30%'><input id='it' name='it' length=32 placeholder='" DOMOTICZ_IN_TOPIC "' value='{d1}'></td></tr>"
|
||||||
"<tr><td><b>Out topic</b> (" DOMOTICZ_OUT_TOPIC ")</td><td><input id='ot' name='ot' length=32 placeholder='" DOMOTICZ_OUT_TOPIC "' value='{d2}'></td></tr>";
|
"<tr><td><b>Out topic</b> (" DOMOTICZ_OUT_TOPIC ")</td><td><input id='ot' name='ot' length=32 placeholder='" DOMOTICZ_OUT_TOPIC "' value='{d2}'></td></tr>";
|
||||||
|
const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM =
|
||||||
|
"<tr><td><b>Idx {1</b></td></td><td><input id='r{1' name='r{1' length=8 placeholder='0' value='{2'></td></tr>"
|
||||||
|
"<tr><td><b>Key idx {1</b></td><td><input id='k{1' name='k{1' length=8 placeholder='0' value='{3'></td></tr>";
|
||||||
|
const char HTTP_FORM_DOMOTICZ_SWITCH[] PROGMEM =
|
||||||
|
"<tr><td><b>Switch idx {1</b></td><td><input id='s{1' name='s{1' length=8 placeholder='0' value='{4'></td></tr>";
|
||||||
|
const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM =
|
||||||
|
"<tr><td><b>Sensor idx {1</b> - {2</td><td><input id='l{1' name='l{1' length=8 placeholder='0' value='{5'></td></tr>";
|
||||||
|
const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM =
|
||||||
|
"<tr><td><b>Update timer</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td><input id='ut' name='ut' length=32 placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>";
|
||||||
|
|
||||||
const char domoticz_sensors[DOMOTICZ_MAX_SENSORS][14] PROGMEM =
|
const char domoticz_sensors[DOMOTICZ_MAX_SENSORS][14] PROGMEM =
|
||||||
{ "Temp", "Temp,Hum", "Temp,Hum,Baro", "Power,Energy", "Illuminance" };
|
{ "Temp", "Temp,Hum", "Temp,Hum,Baro", "Power,Energy", "Illuminance" };
|
||||||
|
@ -173,66 +182,62 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
|
||||||
* Commands
|
* Commands
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
boolean domoticz_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
|
boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
|
||||||
{
|
{
|
||||||
boolean serviced = true;
|
boolean serviced = true;
|
||||||
|
|
||||||
if (!strcmp(type,"DOMOTICZINTOPIC")) {
|
if (!strncmp(type,"DOMOTICZ",8)) {
|
||||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.domoticz_in_topic))) {
|
if (!strcmp(type +8,"INTOPIC")) {
|
||||||
strlcpy(sysCfg.domoticz_in_topic, (payload == 1) ? DOMOTICZ_IN_TOPIC : dataBuf, sizeof(sysCfg.domoticz_in_topic));
|
if ((data_len > 0) && (data_len < sizeof(sysCfg.domoticz_in_topic))) {
|
||||||
restartflag = 2;
|
strlcpy(sysCfg.domoticz_in_topic, (payload == 1) ? DOMOTICZ_IN_TOPIC : dataBuf, sizeof(sysCfg.domoticz_in_topic));
|
||||||
|
restartflag = 2;
|
||||||
|
}
|
||||||
|
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzInTopic\":\"%s\"}"), sysCfg.domoticz_in_topic);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzInTopic\":\"%s\"}"), sysCfg.domoticz_in_topic);
|
else if (!strcmp(type +8,"OUTTOPIC")) {
|
||||||
}
|
if ((data_len > 0) && (data_len < sizeof(sysCfg.domoticz_out_topic))) {
|
||||||
else if (!strcmp(type,"DOMOTICZOUTTOPIC")) {
|
strlcpy(sysCfg.domoticz_out_topic, (payload == 1) ? DOMOTICZ_OUT_TOPIC : dataBuf, sizeof(sysCfg.domoticz_out_topic));
|
||||||
if ((data_len > 0) && (data_len < sizeof(sysCfg.domoticz_out_topic))) {
|
restartflag = 2;
|
||||||
strlcpy(sysCfg.domoticz_out_topic, (payload == 1) ? DOMOTICZ_OUT_TOPIC : dataBuf, sizeof(sysCfg.domoticz_out_topic));
|
}
|
||||||
restartflag = 2;
|
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzOutTopic\":\"%s\"}"), sysCfg.domoticz_out_topic);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzOutTopic\":\"%s\"}"), sysCfg.domoticz_out_topic);
|
else if (!strcmp(type +8,"IDX") && (index > 0) && (index <= Maxdevice)) {
|
||||||
}
|
if ((data_len > 0) && (payload >= 0)) {
|
||||||
else if (!strcmp(type,"DOMOTICZIDX") && (index > 0) && (index <= Maxdevice)) {
|
sysCfg.domoticz_relay_idx[index -1] = payload;
|
||||||
if ((data_len > 0) && (payload >= 0)) {
|
restartflag = 2;
|
||||||
sysCfg.domoticz_relay_idx[index -1] = payload;
|
}
|
||||||
restartflag = 2;
|
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzIdx%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzIdx%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]);
|
else if (!strcmp(type +8,"KEYIDX") && (index > 0) && (index <= Maxdevice)) {
|
||||||
}
|
if ((data_len > 0) && (payload >= 0)) {
|
||||||
else if (!strcmp(type,"DOMOTICZKEYIDX") && (index > 0) && (index <= Maxdevice)) {
|
sysCfg.domoticz_key_idx[index -1] = payload;
|
||||||
if ((data_len > 0) && (payload >= 0)) {
|
}
|
||||||
sysCfg.domoticz_key_idx[index -1] = payload;
|
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzKeyIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzKeyIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
|
else if (!strcmp(type +8,"SWITCHIDX") && (index > 0) && (index <= Maxdevice)) {
|
||||||
}
|
if ((data_len > 0) && (payload >= 0)) {
|
||||||
else if (!strcmp(type,"DOMOTICZSWITCHIDX") && (index > 0) && (index <= Maxdevice)) {
|
sysCfg.domoticz_switch_idx[index -1] = payload;
|
||||||
if ((data_len > 0) && (payload >= 0)) {
|
}
|
||||||
sysCfg.domoticz_switch_idx[index -1] = payload;
|
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSwitchIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSwitchIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
|
else if (!strcmp(type +8,"SENSORIDX") && (index > 0) && (index <= DOMOTICZ_MAX_SENSORS)) {
|
||||||
}
|
if ((data_len > 0) && (payload >= 0)) {
|
||||||
else if (!strcmp(type,"DOMOTICZSENSORIDX") && (index > 0) && (index <= DOMOTICZ_MAX_SENSORS)) {
|
sysCfg.domoticz_sensor_idx[index -1] = payload;
|
||||||
if ((data_len > 0) && (payload >= 0)) {
|
}
|
||||||
sysCfg.domoticz_sensor_idx[index -1] = payload;
|
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSensorIdx%d\":%d}"), index, sysCfg.domoticz_sensor_idx[index -1]);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSensorIdx%d\":%d}"), index, sysCfg.domoticz_sensor_idx[index -1]);
|
else if (!strcmp(type +8,"UPDATETIMER")) {
|
||||||
}
|
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
|
||||||
else if (!strcmp(type,"DOMOTICZUPDATETIMER")) {
|
sysCfg.domoticz_update_timer = payload;
|
||||||
if ((data_len > 0) && (payload >= 0) && (payload < 3601)) {
|
}
|
||||||
sysCfg.domoticz_update_timer = payload;
|
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzUpdateTimer\":%d}"), sysCfg.domoticz_update_timer);
|
||||||
}
|
}
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzUpdateTimer\":%d}"), sysCfg.domoticz_update_timer);
|
else serviced = false;
|
||||||
}
|
|
||||||
else {
|
|
||||||
serviced = false;
|
|
||||||
}
|
}
|
||||||
|
else serviced = false;
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
void domoticz_commands(char *svalue, uint16_t ssvalue)
|
|
||||||
{
|
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"Commands4\":\"DomoticzInTopic, DomoticzOutTopic, DomoticzIdx, DomoticzKeyIdx, DomoticzSwitchIdx, DomoticzSensorIdx, DomoticzUpdateTimer\"}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean domoticz_button(byte key, byte device, byte state, byte svalflg)
|
boolean domoticz_button(byte key, byte device, byte state, byte svalflg)
|
||||||
{
|
{
|
||||||
if ((sysCfg.domoticz_key_idx[device -1] || sysCfg.domoticz_switch_idx[device -1]) && (svalflg)) {
|
if ((sysCfg.domoticz_key_idx[device -1] || sysCfg.domoticz_switch_idx[device -1]) && (svalflg)) {
|
||||||
|
@ -321,24 +326,27 @@ void handleDomoticz()
|
||||||
page += FPSTR(HTTP_FORM_DOMOTICZ);
|
page += FPSTR(HTTP_FORM_DOMOTICZ);
|
||||||
page.replace("{d1}", String(sysCfg.domoticz_in_topic));
|
page.replace("{d1}", String(sysCfg.domoticz_in_topic));
|
||||||
page.replace("{d2}", String(sysCfg.domoticz_out_topic));
|
page.replace("{d2}", String(sysCfg.domoticz_out_topic));
|
||||||
for (int i = 0; i < Maxdevice; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
page += F("<tr><td><b>Idx {1</b></td></td><td><input id='r{1' name='r{1' length=8 placeholder='0' value='{2'></td></tr>");
|
if (i < Maxdevice) {
|
||||||
page += F("<tr><td><b>Key idx {1</b></td><td><input id='k{1' name='k{1' length=8 placeholder='0' value='{3'></td></tr>");
|
page += FPSTR(HTTP_FORM_DOMOTICZ_RELAY);
|
||||||
page += F("<tr><td><b>Switch idx {1</b></td><td><input id='s{1' name='s{1' length=8 placeholder='0' value='{4'></td></tr>");
|
page.replace("{2", String((int)sysCfg.domoticz_relay_idx[i]));
|
||||||
|
page.replace("{3", String((int)sysCfg.domoticz_key_idx[i]));
|
||||||
|
}
|
||||||
|
if (pin[GPIO_SWT1 +i] < 99) {
|
||||||
|
page += FPSTR(HTTP_FORM_DOMOTICZ_SWITCH);
|
||||||
|
page.replace("{4", String((int)sysCfg.domoticz_switch_idx[i]));
|
||||||
|
}
|
||||||
page.replace("{1", String(i +1));
|
page.replace("{1", String(i +1));
|
||||||
page.replace("{2", String((int)sysCfg.domoticz_relay_idx[i]));
|
|
||||||
page.replace("{3", String((int)sysCfg.domoticz_key_idx[i]));
|
|
||||||
page.replace("{4", String((int)sysCfg.domoticz_switch_idx[i]));
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < DOMOTICZ_MAX_SENSORS; i++) {
|
for (int i = 0; i < DOMOTICZ_MAX_SENSORS; i++) {
|
||||||
page += F("<tr><td><b>Sensor idx {1</b> - {2</td><td><input id='l{1' name='l{1' length=8 placeholder='0' value='{4'></td></tr>");
|
page += FPSTR(HTTP_FORM_DOMOTICZ_SENSOR);
|
||||||
page.replace("{1", String(i +1));
|
page.replace("{1", String(i +1));
|
||||||
snprintf_P(stemp, sizeof(stemp), domoticz_sensors[i]);
|
snprintf_P(stemp, sizeof(stemp), domoticz_sensors[i]);
|
||||||
page.replace("{2", stemp);
|
page.replace("{2", stemp);
|
||||||
page.replace("{4", String((int)sysCfg.domoticz_sensor_idx[i]));
|
page.replace("{5", String((int)sysCfg.domoticz_sensor_idx[i]));
|
||||||
}
|
}
|
||||||
page += F("<tr><td><b>Update timer</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td><input id='ut' name='ut' length=32 placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{d7}'</td></tr>");
|
page += FPSTR(HTTP_FORM_DOMOTICZ_TIMER);
|
||||||
page.replace("{d7}", String((int)sysCfg.domoticz_update_timer));
|
page.replace("{6", String((int)sysCfg.domoticz_update_timer));
|
||||||
page += F("</table>");
|
page += F("</table>");
|
||||||
page += FPSTR(HTTP_FORM_END);
|
page += FPSTR(HTTP_FORM_END);
|
||||||
page += FPSTR(HTTP_BTN_CONF);
|
page += FPSTR(HTTP_BTN_CONF);
|
||||||
|
|
|
@ -28,13 +28,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
* IR Remote send using IRremoteESP8266 library
|
* IR Remote send using IRremoteESP8266 library
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
// * Add support for Toshiba and Mitsubishi HVAC IR control (#257)
|
|
||||||
// #define USE_IR_HVAC // Support for HVAC system using IR (+2k code)
|
|
||||||
|
|
||||||
#ifndef USE_IR_HVAC
|
#ifndef USE_IR_HVAC
|
||||||
#include <IRremoteESP8266.h>
|
#include <IRremoteESP8266.h>
|
||||||
#else
|
#else
|
||||||
#include <IRMitsubishiAC.h> // Currently firmware.elf section `.text' will not fit in region `iram1_0_seg'
|
#include <IRMitsubishiAC.h>
|
||||||
|
|
||||||
// HVAC TOSHIBA_
|
// HVAC TOSHIBA_
|
||||||
#define HVAC_TOSHIBA_HDR_MARK 4400
|
#define HVAC_TOSHIBA_HDR_MARK 4400
|
||||||
#define HVAC_TOSHIBA_HDR_SPACE 4300
|
#define HVAC_TOSHIBA_HDR_SPACE 4300
|
||||||
|
@ -44,7 +42,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define HVAC_TOSHIBA_RPT_MARK 440
|
#define HVAC_TOSHIBA_RPT_MARK 440
|
||||||
#define HVAC_TOSHIBA_RPT_SPACE 7048 // Above original iremote limit
|
#define HVAC_TOSHIBA_RPT_SPACE 7048 // Above original iremote limit
|
||||||
#define HVAC_TOSHIBA_DATALEN 9
|
#define HVAC_TOSHIBA_DATALEN 9
|
||||||
|
|
||||||
IRMitsubishiAC *mitsubir = NULL;
|
IRMitsubishiAC *mitsubir = NULL;
|
||||||
|
|
||||||
|
const char FANSPEED[] = "A12345S";
|
||||||
|
const char HVACMODE[] = "HDCA";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IRsend *irsend = NULL;
|
IRsend *irsend = NULL;
|
||||||
|
@ -143,7 +145,7 @@ boolean ir_send_command(char *type, uint16_t index, char *dataBufUc, uint16_t da
|
||||||
else error = true;
|
else error = true;
|
||||||
}
|
}
|
||||||
} else error = true;
|
} else error = true;
|
||||||
if (error) snprintf_P(svalue, ssvalue, PSTR("{\"IRHVAC\":\"Wrong parameters value for Vendor, Mode and/or FanSpeed\"}"));
|
if (error) snprintf_P(svalue, ssvalue, PSTR("{\"IRHVAC\":\"Wrong Vendor, Mode and/or FanSpeed\"}"));
|
||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC
|
#endif // USE_IR_HVAC
|
||||||
else {
|
else {
|
||||||
|
@ -157,46 +159,30 @@ boolean ir_hvac_toshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean
|
||||||
{
|
{
|
||||||
unsigned int rawdata[2 + 2*8*HVAC_TOSHIBA_DATALEN + 2];
|
unsigned int rawdata[2 + 2*8*HVAC_TOSHIBA_DATALEN + 2];
|
||||||
byte data[HVAC_TOSHIBA_DATALEN] = { 0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
byte data[HVAC_TOSHIBA_DATALEN] = { 0xF2, 0x0D, 0x03, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x00 };
|
||||||
boolean error = false;
|
|
||||||
|
|
||||||
if (HVAC_Mode == NULL || !strcmp(HVAC_Mode,"HOT")) { //default HVAC_HOT
|
char *p, *token;
|
||||||
data[6] = (byte) B00000011;
|
uint8_t mode;
|
||||||
|
|
||||||
|
if (HVAC_Mode == NULL) {
|
||||||
|
p = (char*)HVACMODE; // default HVAC_HOT
|
||||||
|
} else {
|
||||||
|
p = strchr(HVACMODE, HVAC_Mode[0]);
|
||||||
}
|
}
|
||||||
else if (HVAC_Mode && !strcmp(HVAC_Mode,"COLD")) {
|
if (!p) return true;
|
||||||
data[6] = (byte) B00000001;
|
data[6] = (p - HVACMODE) ^ 0x03; // HOT = 0x03, DRY = 0x02, COOL = 0x01, AUTO = 0x00
|
||||||
}
|
|
||||||
else if (HVAC_Mode && !strcmp(HVAC_Mode,"DRY")) {
|
|
||||||
data[6] = (byte) B00000010;
|
|
||||||
}
|
|
||||||
else if (HVAC_Mode && !strcmp(HVAC_Mode,"AUTO")) {
|
|
||||||
data[6] = (byte) B00000000;
|
|
||||||
}
|
|
||||||
else error = true;
|
|
||||||
|
|
||||||
if (!HVAC_Power) data[6] = (byte) 0x07; // Turn OFF HVAC
|
if (!HVAC_Power) data[6] = (byte) 0x07; // Turn OFF HVAC
|
||||||
|
|
||||||
if (HVAC_FanMode && !strcmp(HVAC_FanMode,"1")) {
|
if (HVAC_FanMode == NULL) {
|
||||||
data[6] = data[6] | (byte) B01000000;
|
p = (char*)FANSPEED; // default FAN_SPEED_AUTO
|
||||||
|
} else {
|
||||||
|
p = strchr(FANSPEED, HVAC_FanMode[0]);
|
||||||
}
|
}
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"2")) {
|
if (!p) return true;
|
||||||
data[6] = data[6] | (byte) B01100000;
|
mode = p - FANSPEED +1;
|
||||||
}
|
if ((mode == 1) || (mode == 7)) mode = 0;
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"3")) {
|
mode = mode << 5; // AUTO = 0x00, SPEED = 0x40, 0x60, 0x80, 0xA0, 0xC0, SILENT = 0x00
|
||||||
data[6] = data[6] | (byte) B10000000;
|
data[6] = data[6] | mode;
|
||||||
}
|
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"4")) {
|
|
||||||
data[6] = data[6] | (byte) B10100000;
|
|
||||||
}
|
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"5")) {
|
|
||||||
data[6] = data[6] | (byte) B11000000;
|
|
||||||
}
|
|
||||||
else if (HVAC_FanMode == NULL || !strcmp(HVAC_FanMode,"AUTO")) { // default FAN_SPEED_AUTO
|
|
||||||
data[6] = data[6] | (byte) B00000000;
|
|
||||||
}
|
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"SILENT")) {
|
|
||||||
data[6] = data[6] | (byte) B00000000;
|
|
||||||
}
|
|
||||||
else error = true;
|
|
||||||
|
|
||||||
byte Temp;
|
byte Temp;
|
||||||
if (HVAC_Temp > 30) {
|
if (HVAC_Temp > 30) {
|
||||||
|
@ -243,63 +229,46 @@ boolean ir_hvac_toshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean
|
||||||
irsend->sendRaw(rawdata,i,38);
|
irsend->sendRaw(rawdata,i,38);
|
||||||
interrupts();
|
interrupts();
|
||||||
|
|
||||||
return error;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean ir_hvac_mitsubishi(const char *HVAC_Mode,const char *HVAC_FanMode, boolean HVAC_Power, int HVAC_Temp)
|
boolean ir_hvac_mitsubishi(const char *HVAC_Mode,const char *HVAC_FanMode, boolean HVAC_Power, int HVAC_Temp)
|
||||||
{
|
{
|
||||||
boolean error = false;
|
char *p, *token;
|
||||||
|
uint8_t mode;
|
||||||
char log[LOGSZ];
|
char log[LOGSZ];
|
||||||
|
|
||||||
mitsubir->stateReset();
|
mitsubir->stateReset();
|
||||||
|
|
||||||
if (HVAC_Mode == NULL || !strcmp(HVAC_Mode,"HOT")) { // default HVAC_HOT
|
if (HVAC_Mode == NULL) {
|
||||||
mitsubir->setMode(MITSUBISHI_AC_HEAT);
|
p = (char*)HVACMODE; // default HVAC_HOT
|
||||||
|
} else {
|
||||||
|
p = strchr(HVACMODE, HVAC_Mode[0]);
|
||||||
}
|
}
|
||||||
else if (HVAC_Mode && !strcmp(HVAC_Mode,"COLD")) {
|
if (!p) return true;
|
||||||
mitsubir->setMode(MITSUBISHI_AC_COOL);
|
mode = (p - HVACMODE +1) << 3; // HOT = 0x08, DRY = 0x10, COOL = 0x18, AUTO = 0x20
|
||||||
}
|
mitsubir->setMode(mode);
|
||||||
else if (HVAC_Mode && !strcmp(HVAC_Mode,"DRY")) {
|
|
||||||
mitsubir->setMode(MITSUBISHI_AC_DRY);
|
|
||||||
}
|
|
||||||
else if (HVAC_Mode && !strcmp(HVAC_Mode,"AUTO")) {
|
|
||||||
mitsubir->setMode(MITSUBISHI_AC_AUTO);
|
|
||||||
} else error = true;
|
|
||||||
|
|
||||||
mitsubir->setPower(~HVAC_Power);
|
mitsubir->setPower(~HVAC_Power);
|
||||||
|
|
||||||
if (HVAC_FanMode && !strcmp(HVAC_FanMode,"1")) {
|
if (HVAC_FanMode == NULL) {
|
||||||
mitsubir->setFan(1);
|
p = (char*)FANSPEED; // default FAN_SPEED_AUTO
|
||||||
|
} else {
|
||||||
|
p = strchr(FANSPEED, HVAC_FanMode[0]);
|
||||||
}
|
}
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"2")) {
|
if (!p) return true;
|
||||||
mitsubir->setFan(2);
|
mode = p - FANSPEED; // AUTO = 0, SPEED = 1 .. 5, SILENT = 6
|
||||||
}
|
mitsubir->setFan(mode);
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"3")) {
|
|
||||||
mitsubir->setFan(3);
|
|
||||||
}
|
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"4")) {
|
|
||||||
mitsubir->setFan(4);
|
|
||||||
}
|
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"5")) {
|
|
||||||
mitsubir->setFan(5);
|
|
||||||
}
|
|
||||||
else if (HVAC_FanMode == NULL || !strcmp(HVAC_FanMode,"AUTO")) { // default FAN_SPEED_AUTO
|
|
||||||
mitsubir->setFan(MITSUBISHI_AC_FAN_AUTO);
|
|
||||||
}
|
|
||||||
else if (HVAC_FanMode && !strcmp(HVAC_FanMode,"SILENT")) {
|
|
||||||
mitsubir->setFan(MITSUBISHI_AC_FAN_SILENT);
|
|
||||||
}
|
|
||||||
else error = true;
|
|
||||||
|
|
||||||
mitsubir->setTemp(HVAC_Temp);
|
mitsubir->setTemp(HVAC_Temp);
|
||||||
mitsubir->setVane(MITSUBISHI_AC_VANE_AUTO);
|
mitsubir->setVane(MITSUBISHI_AC_VANE_AUTO);
|
||||||
|
|
||||||
mitsubir->send();
|
mitsubir->send();
|
||||||
snprintf_P(log, sizeof(log), PSTR("IRHVAC: Sent to Mitsubishi. Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
|
|
||||||
mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
|
|
||||||
addLog(LOG_LEVEL_DEBUG, log);
|
|
||||||
|
|
||||||
return error;
|
// snprintf_P(log, sizeof(log), PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
|
||||||
|
// mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
|
||||||
|
// addLog(LOG_LEVEL_DEBUG, log);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#endif // USE_IR_HVAC
|
#endif // USE_IR_HVAC
|
||||||
#endif // USE_IR_REMOTE
|
#endif // USE_IR_REMOTE
|
||||||
|
|
|
@ -198,8 +198,9 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
||||||
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature
|
if (dht_readTempHum(TEMP_CONVERSION, t, h)) { // Read temperature
|
||||||
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
|
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
|
||||||
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
|
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
|
||||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
|
// snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
|
||||||
svalue, dhtstype, stemp1, stemp2);
|
// svalue, dhtstype, stemp1, stemp2);
|
||||||
|
snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, dhtstype, stemp1, stemp2);
|
||||||
*djson = 1;
|
*djson = 1;
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
domoticz_sensor2(stemp1, stemp2);
|
domoticz_sensor2(stemp1, stemp2);
|
||||||
|
|
|
@ -511,12 +511,6 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len
|
||||||
return serviced;
|
return serviced;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hlw_commands(char *svalue, uint16_t ssvalue)
|
|
||||||
{
|
|
||||||
snprintf_P(svalue, ssvalue, PSTR("{\"Commands5\":\"PowerLow, PowerHigh, VoltageLow, VoltageHigh, CurrentLow, CurrentHigh, HlwPcal, HlwUcal, HlwIcal%s\"}"),
|
|
||||||
(FEATURE_POWER_LIMIT)?", SafePower, SafePowerHold, SafePowerWindow, MaxPower, MaxPowerHold, MaxPowerWindow, MaxEnergy, MaxEnergyStart":"");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Presentation
|
* Presentation
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
|
@ -262,8 +262,7 @@ void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
||||||
h = htu21_compensatedHumidity(h, t);
|
h = htu21_compensatedHumidity(h, t);
|
||||||
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
|
dtostrf(t, 1, TEMP_RESOLUTION &3, stemp1);
|
||||||
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
|
dtostrf(h, 1, HUMIDITY_RESOLUTION &3, stemp2);
|
||||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
|
snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, htustype, stemp1, stemp2);
|
||||||
svalue, htustype, stemp1, stemp2);
|
|
||||||
*djson = 1;
|
*djson = 1;
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
domoticz_sensor2(stemp1, stemp2);
|
domoticz_sensor2(stemp1, stemp2);
|
||||||
|
|
|
@ -183,8 +183,7 @@ void sht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
||||||
|
|
||||||
char stemp[10], shum[10];
|
char stemp[10], shum[10];
|
||||||
if (sht_readCharTempHum(stemp, shum)) {
|
if (sht_readCharTempHum(stemp, shum)) {
|
||||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"SHT1X\":{\"Temperature\":%s, \"Humidity\":%s}"),
|
snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, "SHT1X", stemp, shum);
|
||||||
svalue, stemp, shum);
|
|
||||||
*djson = 1;
|
*djson = 1;
|
||||||
#ifdef USE_DOMOTICZ
|
#ifdef USE_DOMOTICZ
|
||||||
domoticz_sensor2(stemp, shum);
|
domoticz_sensor2(stemp, shum);
|
||||||
|
|
Loading…
Reference in New Issue