diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 8c65c845b..27b47a02f 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,9 @@ -/* 6.4.1.8 20190107 +/* 6.4.1.9 20190115 + * Add support for Mi LED Desk Lamp with rotary switch (#4887) + * Fix mDNS addService (#4938) + * Fix allowable MAX_RULE_VARS to 16 (#4933) + * + * 6.4.1.8 20190107 * Change sonoff_template.h layout regarding optional module flags like ADC0 * Add command SetOption62 1 to force no Button/Switch pullup on dedicated modules. Currently only supported on Shelly2 (#4841) * Fix Display exception 28 when JSON value is NULL received @@ -8,6 +13,9 @@ * Change web authentication (#4865) * Add support for Digoo DG-SP202 Smart Socket with Energy monitoring (#4891) * Add support for Smanergy KA10 Smart Wall Socket with Energy monitoring + * Add support for Luminea ZX2820 Smart Socket with Energy monitoring (#4921) + * Add define MDNS_ENABLE to control initial mDNS state (#4923) + * Add split interlock part 1 (#4910) * * 6.4.1.7 20190106 * Fix HLW8012, HJL01 and BL0937 based energy sensors low Power (below 10W) measurement regression from 6.4.1.6 diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 537aafaef..2c02809f8 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -134,6 +134,9 @@ #define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa #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 ---------------------------------------- +#define MDNS_ENABLED 0 // [SetOption55] Use mDNS (0 = Disable, 1 = Enable) + // -- Time - Up to three NTP servers in your region #define NTP_SERVER1 "pool.ntp.org" // [NtpServer1] Select first NTP server by name or IP address (129.250.35.250) #define NTP_SERVER2 "nl.pool.ntp.org" // [NtpServer2] Select second NTP server by name or IP address (5.39.184.5) @@ -322,8 +325,9 @@ // #define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code) // #define USE_RTC_ADDR 0x68 // Default I2C address 0x68 // #define USE_MGC3130 // Enable MGC3130 Electric Field Effect Sensor (I2C address 0x42) (+2k7 code, 0k3 mem) -// #define USE_PN532_I2C // Enable PN532 - Near Field Communication (NFC) controller (+3k3 code, 508 bytes of mem) -// #define USE_PN532_CAUSE_EVENTS // Enable PN532 driver to cause event's on card read in addition to immediate telemetry +// #define USE_PN532_I2C // Enable PN532 - Near Field Communication (NFC) controller (+1k7 code, 164 bytes of mem) +// #define USE_PN532_DATA_FUNCTION // Enable PN532 DATA Usage using Sensor15 command (+1k6 code, 316 bytes of mem) +// #define USE_PN532_CAUSE_EVENTS // Enable PN532 driver to cause event's on card read in addition to immediate telemetry (+64 bytes code, 48 bytes mem) // #define USE_DISPLAY // Add I2C Display Support (+2k code) #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 diff --git a/sonoff/settings.h b/sonoff/settings.h index 618cc03f2..714dee800 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -76,7 +76,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep uint32_t button_switch_force_local : 1;// bit 11 (v6.3.0.16) - SetOption61 - Force local operation when button/switch topic is set uint32_t no_pullup : 1; // bit 12 (v6.4.1.7) - SetOption62 - Force no pull-up (0 = (no)pull-up, 1 = no pull-up) - uint32_t spare13 : 1; + uint32_t split_interlock : 1; // bit 13 (v6.4.1.8) - SetOption63 - Split interlock on CH4 uint32_t spare14 : 1; uint32_t spare15 : 1; uint32_t spare16 : 1; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 055b35566..65f42e979 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -621,6 +621,7 @@ void SettingsDefaultSet2(void) Settings.webserver = WEB_SERVER; Settings.weblog_level = WEB_LOG_LEVEL; strlcpy(Settings.web_password, WEB_PASSWORD, sizeof(Settings.web_password)); + Settings.flag3.mdns_enabled = MDNS_ENABLED; // Button // Settings.flag.button_restrict = 0; @@ -1018,7 +1019,7 @@ void SettingsDelta(void) } } if (Settings.version < 0x06040105) { - Settings.flag3.mdns_enabled = 0; + Settings.flag3.mdns_enabled = MDNS_ENABLED; Settings.param[P_MDNS_DELAYED_START] = 0; } diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 59b7a96f2..c520d3981 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -260,5 +260,7 @@ const uint8_t kIFan02Speed[MAX_FAN_SPEED][3] = {{6,6,6}, {7,6,6}, {7,7,6}, {7,6, \*********************************************************************************************/ extern uint8_t light_device; // Light device number +extern uint8_t light_power; // Light power +extern uint8_t rotary_changed; // Rotary switch changed #endif // _SONOFF_H_ diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 404403d5a..f16a3ba10 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -167,7 +167,6 @@ byte syslog_level; // Current copy of Settings.syslog_l //byte mdns_delayed_start = 0; // mDNS delayed start boolean latest_uptime_flag = true; // Signal latest uptime boolean pwm_present = false; // Any PWM channel configured with SetOption15 0 -boolean mdns_begun = false; // mDNS active myio my_module; // Active copy of Module GPIOs (17 x 8 bits) gpio_flag my_module_flag; // Active copy of Module GPIO flags StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits) @@ -319,6 +318,23 @@ void SetDevicePower(power_t rpower, int source) power = (1 << devices_present) -1; rpower = power; } + if (Settings.flag3.split_interlock) { + Settings.flag.interlock = 1; // prevent the situation where interlock is off and split-interlock is on + uint8_t mask = 0x01; + uint8_t count = 0; + byte result1 = 0; + byte result2 = 0; + for (byte i = 0; i < devices_present; i++) { + if (rpower & mask) { + if (i <2) { result1++;}//increment if low part is ON + if (i >1) { result2++;}//increment if high part is ON + } + mask <<= 1; // shift the bitmask one left (1,2,4,8) to find out what is on + } + if ((result1) >1 && (result2 >1)) {power = 0; rpower = 0;} // all 4 switch are on, something is wrong, so we turn all off + if ((result1) >1 && (result2 <2)) {power = power & 0x0C; rpower = power;} // 1/2 are both on and 3/4 max one is on + if ((result1) <2 && (result2 >1)) {power = power & 0x03; rpower = power;} // 1/2 max one is on and 3/4 both are on + } else { if (Settings.flag.interlock) { // Allow only one or no relay set power_t mask = 1; uint8_t count = 0; @@ -331,6 +347,7 @@ void SetDevicePower(power_t rpower, int source) rpower = 0; } } + } XdrvMailbox.index = rpower; XdrvCall(FUNC_SET_POWER); // Signal power state @@ -1389,7 +1406,28 @@ void ExecuteCommandPower(byte device, byte state, int source) blink_mask &= (POWER_MASK ^ mask); // Clear device mask MqttPublishPowerBlinkState(device); } - if (Settings.flag.interlock && !interlock_mutex) { // Clear all but masked relay + if (Settings.flag3.split_interlock && !Settings.flag.interlock ) Settings.flag.interlock=1; // ensure interlock is on, in case split_interlock is on + // check if channel 1/2 or 3/4 are to be changed + if (device <= 2 && Settings.flag3.split_interlock ) { // channel 1/2 are changed + if (Settings.flag3.split_interlock && !interlock_mutex) { // Clear all but masked relay, but only if we are not already doing something + interlock_mutex = 1; + for (byte i = 0; i < 2; i++) { + byte imask = 0x01 << i; + if ((power & imask) && (mask != imask)) { ExecuteCommandPower(i +1, POWER_OFF, SRC_IGNORE); delay(50); }// example, first power is ON but the pushed button is not the first, then powerOFF the first one + } + interlock_mutex = 0; // avoid infinite loop due to recursive requests + } + } else { // channel 3/4 are changed + if (Settings.flag3.split_interlock && !interlock_mutex) { // only start if we are on interlock split and have no re-call + interlock_mutex = 1; + for (byte i = 2; i < devices_present; i++) { + byte imask = 0x01 << i; + if ((power & imask) && (mask != imask)) ExecuteCommandPower(i +1, POWER_OFF, SRC_IGNORE); + } + interlock_mutex = 0; + } + } + if ( Settings.flag.interlock && !interlock_mutex && !Settings.flag3.split_interlock) { //execute regular interlock-mode as interlock-split is off interlock_mutex = 1; for (byte i = 0; i < devices_present; i++) { power_t imask = 1 << i; @@ -2323,6 +2361,7 @@ void GpioInit(void) ButtonInit(); SwitchInit(); + RotaryInit(); #ifdef USE_WS2812 if (!light_type && (pin[GPIO_WS2812] < 99)) { // RGB led @@ -2509,6 +2548,7 @@ void loop(void) ButtonLoop(); SwitchLoop(); + RotaryLoop(); if (TimeReached(state_50msecond)) { SetNextTimeInterval(state_50msecond, 50); diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index e15fb9a99..39eb8737d 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -163,6 +163,8 @@ enum ProgramSelectablePins { GPIO_DI, // my92x1 PWM input GPIO_DCKI, // my92x1 CLK input GPIO_ARIRFRCV, // AliLux RF Receive input + GPIO_ROT_A, // Rotary switch A Pin + GPIO_ROT_B, // Rotary switch B Pin GPIO_USER, // User configurable GPIO_MAX }; @@ -277,6 +279,8 @@ enum SupportedModules { YTF_IR_BRIDGE, DIGOO, KA10, + ZX2820, + MI_DESK_LAMP, MAXMODULE }; /********************************************************************************************/ @@ -545,6 +549,7 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { TECKIN_US, APLIC_WDP303075, GOSUND, + ZX2820, SK03_TUYA, DIGOO, KA10, @@ -563,6 +568,7 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { ARILUX_LC11, ZENGGE_ZF_WF017, HUAFAN_SS, + MI_DESK_LAMP, KMC_70011, AILIGHT, // Light Bulbs PHILIPS, @@ -1736,6 +1742,38 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_LED2, // GPIO13 Red LED - Power status GPIO_REL1, // GPIO14 Relay 1 0, 0, 0 + }, + { "Luminea ZX2820", + GPIO_KEY1, // GPIO00 Button + 0, 0, 0, + GPIO_HLW_CF, // GPIO04 HLW8012 CF power + GPIO_NRG_CF1, // GPIO05 HLW8012 CF1 voltage / current + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + 0, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + 0, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPIO_NRG_SEL_INV, // GPIO12 HLW8012 SEL (0 = Voltage) + GPIO_LED1_INV, // GPIO13 Green Led - Link and Power status + GPIO_REL1, // GPIO14 Relay + 0, 0, 0 + }, + { "Mi Desk Lamp", // Mi LED Desk Lamp - https://www.mi.com/global/smartlamp/ + 0, 0, + GPIO_KEY1, // GPIO02 Button + 0, + GPIO_PWM1, // GPIO04 Cold White + GPIO_PWM2, // GPIO05 Warm White + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + 0, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + 0, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPIO_ROT_A, // GPIO12 Rotary switch A pin + GPIO_ROT_B, // GPIO13 Rotary switch B pin + 0, 0, 0, 0 } }; diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index f371936aa..534276418 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06040108 +#define VERSION 0x06040109 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support_button.ino b/sonoff/support_button.ino index ed5cecce6..b058b685a 100644 --- a/sonoff/support_button.ino +++ b/sonoff/support_button.ino @@ -203,19 +203,23 @@ void ButtonHandler(void) multipress[button_index] = 1; } } - if (single_press && SendKey(0, button_index + multipress[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set - // Success + if ((MI_DESK_LAMP == Settings.module) && (button_index == 0) && (rotary_changed) && (light_power)) { + rotary_changed = 0; // Color temp changed, no need to turn of the light } else { - if (multipress[button_index] < 3) { // Single or Double press - if (WifiState() > WIFI_RESTART) { // WPSconfig, Smartconfig or Wifimanager active - restart_flag = 1; - } else { - ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally - } - } else { // 3 - 7 press - if (!Settings.flag.button_restrict) { - snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]); - ExecuteCommand(scmnd, SRC_BUTTON); + if (single_press && SendKey(0, button_index + multipress[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + // Success + } else { + if (multipress[button_index] < 3) { // Single or Double press + if (WifiState() > WIFI_RESTART) { // WPSconfig, Smartconfig or Wifimanager active + restart_flag = 1; + } else { + ExecuteCommandPower(button_index + multipress[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally + } + } else { // 3 - 7 press + if (!Settings.flag.button_restrict) { + snprintf_P(scmnd, sizeof(scmnd), kCommands[multipress[button_index] -3]); + ExecuteCommand(scmnd, SRC_BUTTON); + } } } } diff --git a/sonoff/support_rotary.ino b/sonoff/support_rotary.ino new file mode 100644 index 000000000..726f45379 --- /dev/null +++ b/sonoff/support_rotary.ino @@ -0,0 +1,153 @@ +/* + support_rotary.ino - rotary switch support for Sonoff-Tasmota + + Copyright (C) 2019 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#define ROTARY_V1 +#ifdef ROTARY_V1 +/*********************************************************************************************\ + * Rotary support +\*********************************************************************************************/ + +unsigned long rotary_debounce = 0; // Rotary debounce timer +uint8_t rotaries_found = 0; +uint8_t rotary_state = 0; +uint8_t rotary_position = 128; +uint8_t rotary_last_position = 128; +uint8_t interrupts_in_use = 0; +uint8_t rotary_changed = 0; + +/********************************************************************************************/ + +void update_position(void) +{ + uint8_t s; + + /* + * https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h + */ + + s = rotary_state & 3; + if (digitalRead(pin[GPIO_ROT_A])) s |= 4; + if (digitalRead(pin[GPIO_ROT_B])) s |= 8; + switch (s) { + case 0: case 5: case 10: case 15: + break; + case 1: case 7: case 8: case 14: + rotary_position++; break; + case 2: case 4: case 11: case 13: + rotary_position--; break; + case 3: case 12: + rotary_position = rotary_position + 2; break; + default: + rotary_position = rotary_position - 2; break; + } + rotary_state = (s >> 2); +} + +void update_rotary(void) +{ + if (MI_DESK_LAMP == Settings.module){ + if (light_power) { + update_position(); + } + } +} + +void RotaryInit(void) +{ + rotaries_found = 0; + if ((pin[GPIO_ROT_A] < 99) && (pin[GPIO_ROT_B] < 99)) { + rotaries_found++; + pinMode(pin[GPIO_ROT_A], INPUT_PULLUP); + pinMode(pin[GPIO_ROT_B], INPUT_PULLUP); + + // GPIO6-GPIO11 are typically used to interface with the flash memory IC on + // most esp8266 modules, so we should avoid adding interrupts to these pins. + + if ((pin[GPIO_ROT_A] < 6) || (pin[GPIO_ROT_A] > 11)) { + attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT_A]), update_rotary, CHANGE); + interrupts_in_use++; + } + if ((pin[GPIO_ROT_B] < 6) || (pin[GPIO_ROT_B] > 11)) { + attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT_B]), update_rotary, CHANGE); + interrupts_in_use++; + } + } +} + +/*********************************************************************************************\ + * Rotary handler +\*********************************************************************************************/ + +void RotaryHandler(void) +{ + if (interrupts_in_use < 2) { + noInterrupts(); + update_rotary(); + } else { + noInterrupts(); + } + if (rotary_last_position != rotary_position) { + if (MI_DESK_LAMP == Settings.module) { // Mi Desk lamp + if (holdbutton[0]) { + rotary_changed = 1; + // button1 is pressed: set color temperature + int16_t t = LightGetColorTemp(); + t = t + (rotary_position - rotary_last_position); + if (t < 153) { + t = 153; + } + if (t > 500) { + t = 500; + } + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_CMND_COLORTEMPERATURE " %d"), rotary_position - rotary_last_position); + AddLog(LOG_LEVEL_DEBUG); + LightSetColorTemp((uint16_t)t); + } else { + int8_t d = Settings.light_dimmer; + d = d + (rotary_position - rotary_last_position); + if (d < 1) { + d = 1; + } + if (d > 100) { + d = 100; + } + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_CMND_DIMMER " %d"), rotary_position - rotary_last_position); + AddLog(LOG_LEVEL_DEBUG); + + LightSetDimmer((uint8_t)d); + Settings.light_dimmer = d; + } + } + rotary_last_position = 128; + rotary_position = 128; + } + interrupts(); +} + +void RotaryLoop(void) +{ + if (rotaries_found) { + if (TimeReached(rotary_debounce)) { + SetNextTimeInterval(rotary_debounce, Settings.button_debounce); // Using button_debounce setting for this as well + RotaryHandler(); + } + } +} + +#endif // ROTARY_V1 diff --git a/sonoff/support_wifi.ino b/sonoff/support_wifi.ino index 817577900..0971d104a 100644 --- a/sonoff/support_wifi.ino +++ b/sonoff/support_wifi.ino @@ -41,6 +41,7 @@ uint8_t wifi_status; uint8_t wps_result; uint8_t wifi_config_type = 0; uint8_t wifi_config_counter = 0; +uint8_t mdns_begun = 0; // mDNS active uint8_t wifi_scan_state; uint8_t wifi_bssid[6]; @@ -492,7 +493,7 @@ void WifiCheck(uint8_t param) // mdns_delayed_start--; // } else { // mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; - mdns_begun = MDNS.begin(my_hostname); + mdns_begun = (uint8_t)MDNS.begin(my_hostname); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS "%s"), (mdns_begun) ? D_INITIALIZED : D_FAILED); AddLog(LOG_LEVEL_INFO); // } @@ -505,7 +506,8 @@ void WifiCheck(uint8_t param) StartWebserver(Settings.webserver, WiFi.localIP()); #ifdef USE_DISCOVERY #ifdef WEBSERVER_ADVERTISE - if (mdns_begun) { + if (1 == mdns_begun) { + mdns_begun = 2; MDNS.addService("http", "tcp", WEB_PORT); } #endif // WEBSERVER_ADVERTISE @@ -530,7 +532,7 @@ void WifiCheck(uint8_t param) #if defined(USE_WEBSERVER) && defined(USE_EMULATION) UdpDisconnect(); #endif // USE_EMULATION - mdns_begun = false; + mdns_begun = 0; #ifdef USE_KNX knx_started = false; #endif // USE_KNX diff --git a/sonoff/xdrv_02_mqtt.ino b/sonoff/xdrv_02_mqtt.ino index 1d3c3a4b8..4321cb7b0 100644 --- a/sonoff/xdrv_02_mqtt.ino +++ b/sonoff/xdrv_02_mqtt.ino @@ -220,9 +220,19 @@ boolean MqttDiscoverServer(void) AddLog(LOG_LEVEL_INFO); if (n > 0) { - // Note: current strategy is to get the first MQTT service (even when many are found) + #ifdef MDNS_HOSTNAME + for (int i = 0; i < n; i++) { + if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) { + snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(i).toString().c_str()); + Settings.mqtt_port = MDNS.port(i); + break; // stop at the first matching record + } + } + #else + // If the hostname isn't set, use the first record found. snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(0).toString().c_str()); Settings.mqtt_port = MDNS.port(0); + #endif // MDNS_HOSTNAME snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(0).c_str(), Settings.mqtt_host, Settings.mqtt_port); @@ -513,13 +523,11 @@ void MqttReconnect(void) mqtt_retry_counter = Settings.mqtt_retry; global_state.mqtt_down = 1; -#ifndef USE_MQTT_TLS #ifdef USE_DISCOVERY #ifdef MQTT_HOST_DISCOVERY - if (!strlen(Settings.mqtt_host) && !MqttDiscoverServer()) { return; } + if (!MqttDiscoverServer() && !strlen(Settings.mqtt_host)) { return; } #endif // MQTT_HOST_DISCOVERY #endif // USE_DISCOVERY -#endif // USE_MQTT_TLS char *mqtt_user = NULL; char *mqtt_pwd = NULL; @@ -585,13 +593,11 @@ void MqttCheck(void) if (!MqttIsConnected()) { global_state.mqtt_down = 1; if (!mqtt_retry_counter) { -#ifndef USE_MQTT_TLS #ifdef USE_DISCOVERY #ifdef MQTT_HOST_DISCOVERY if (!strlen(Settings.mqtt_host) && !mdns_begun) { return; } #endif // MQTT_HOST_DISCOVERY #endif // USE_DISCOVERY -#endif // USE_MQTT_TLS MqttReconnect(); } else { mqtt_retry_counter--; diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 9265e4f67..ef4540401 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -111,6 +111,7 @@ uint8_t light_wheel = 0; uint8_t light_subtype = 0; uint8_t light_device = 0; uint8_t light_power = 0; +uint8_t light_old_power = 1; uint8_t light_update = 1; uint8_t light_wakeup_active = 0; uint8_t light_wakeup_dimmer = 0; @@ -715,11 +716,12 @@ void LightRandomColor(void) void LightSetPower(void) { // light_power = XdrvMailbox.index; + light_old_power = light_power; light_power = bitRead(XdrvMailbox.index, light_device -1); if (light_wakeup_active) { light_wakeup_active--; } - if (light_power) { + if (light_power && !light_old_power) { light_update = 1; } LightAnimate(); @@ -828,7 +830,10 @@ void LightAnimate(void) } } } - XdrvMailbox.index = light_device; + + char *tmp_data = XdrvMailbox.data; + uint16_t tmp_data_len = XdrvMailbox.data_len; + XdrvMailbox.data = (char*)cur_col; XdrvMailbox.data_len = sizeof(cur_col); if (XdrvCall(FUNC_SET_CHANNELS)) { @@ -842,6 +847,8 @@ void LightAnimate(void) else if (light_type > LT_WS2812) { LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); } + XdrvMailbox.data = tmp_data; + XdrvMailbox.data_len = tmp_data_len; } } } diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index df2db9748..5c43db43c 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -95,13 +95,13 @@ uint8_t rules_teleperiod = 0; char event_data[100]; char vars[MAX_RULE_VARS][33] = { 0 }; -#if (MAX_RULE_VARS>8) -#error MAX_RULE_VARS is bigger than 8 +#if (MAX_RULE_VARS>16) +#error MAX_RULE_VARS is bigger than 16 #endif -#if (MAX_RULE_MEMS>8) -#error MAX_RULE_MEMS is bigger than 8 +#if (MAX_RULE_MEMS>5) +#error MAX_RULE_MEMS is bigger than 5 #endif -uint8_t vars_event = 0; +uint16_t vars_event = 0; uint8_t mems_event = 0; /*******************************************************************************************/ diff --git a/sonoff/xsns_40_pn532_i2c.ino b/sonoff/xsns_40_pn532_i2c.ino index 567b19a77..c2fdf65e7 100644 --- a/sonoff/xsns_40_pn532_i2c.ino +++ b/sonoff/xsns_40_pn532_i2c.ino @@ -61,9 +61,13 @@ uint8_t pn532_i2c_detected = 0; uint8_t pn532_i2c_packetbuffer[64]; uint8_t pn532_i2c_scan_defer_report = 0; // If a valid card was found we will not scan for one again in the same two seconds so we set this to 19 if a card was found uint8_t pn532_i2c_command = 0; + uint8_t pn532_i2c_disable = 0; + +#ifdef USE_PN532_DATA_FUNCTION uint8_t pn532_i2c_function = 0; uint8_t pn532_i2c_newdata[16]; +#endif // USE_PN532_DATA_FUNCTION const uint8_t PROGMEM pn532_global_timeout = 10; @@ -285,6 +289,8 @@ boolean PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *u return true; } +#ifdef USE_PN532_DATA_FUNCTION + uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) { uint8_t i; @@ -370,6 +376,7 @@ uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data) return (0 < PN532_readResponse(pn532_i2c_packetbuffer, sizeof(pn532_i2c_packetbuffer))); } +#endif // USE_PN532_DATA_FUNCTION void PN532_ScanForTag(void) { @@ -384,11 +391,17 @@ void PN532_ScanForTag(void) pn532_i2c_scan_defer_report--; } else { char uids[15]; + +#ifdef USE_PN532_DATA_FUNCTION char card_datas[34]; +#endif // USE_PN532_DATA_FUNCTION + sprintf(uids,""); for (uint8_t i = 0;i < uid_len;i++) { sprintf(uids,"%s%02X",uids,uid[i]); } + +#ifdef USE_PN532_DATA_FUNCTION if (uid_len == 4) { // Lets try to read block 0 of the mifare classic card for more information uint8_t keyuniversal[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; if (mifareclassic_AuthenticateBlock (uid, uid_len, 1, 1, keyuniversal)) { @@ -435,17 +448,28 @@ void PN532_ScanForTag(void) break; } pn532_i2c_function = 0; +#endif // USE_PN532_DATA_FUNCTION + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); + +#ifdef USE_PN532_DATA_FUNCTION snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\", \"DATA\":\"%s\"}}"), mqtt_data, uids, card_datas); +#else + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"PN532\":{\"UID\":\"%s\"}}"), mqtt_data, uids); +#endif // USE_PN532_DATA_FUNCTION + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); -#ifdef USE_PN532_CAUSE_EVENTS +#ifdef USE_PN532_CAUSE_EVENTS char command[71]; +#ifdef USE_PN532_DATA_FUNCTION sprintf(command,"backlog event PN532_UID=%s;event PN532_DATA=%s",uids,card_datas); +#else + sprintf(command,"event PN532_UID=%s",uids); +#endif // USE_PN532_DATA_FUNCTION ExecuteCommand(command, SRC_RULE); - -#endif +#endif // USE_PN532_CAUSE_EVENTS pn532_i2c_scan_defer_report = 7; // Ignore tags found for two seconds } @@ -454,6 +478,8 @@ void PN532_ScanForTag(void) } } +#ifdef USE_PN532_DATA_FUNCTION + boolean PN532_Command(void) { boolean serviced = true; @@ -500,6 +526,8 @@ boolean PN532_Command(void) } } +#endif // USE_PN532_DATA_FUNCTION + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -518,11 +546,15 @@ boolean Xsns40(byte function) case FUNC_EVERY_SECOND: PN532_Detect(); break; + +#ifdef USE_PN532_DATA_FUNCTION case FUNC_COMMAND: if (XSNS_40 == XdrvMailbox.index) { result = PN532_Command(); } break; +#endif // USE_PN532_DATA_FUNCTION + case FUNC_SAVE_BEFORE_RESTART: if (!pn532_i2c_disable) { pn532_i2c_disable = 1; diff --git a/tools/decode-config.py b/tools/decode-config.py index 53481b791..739314710 100755 --- a/tools/decode-config.py +++ b/tools/decode-config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -VER = '2.1.0017' +VER = '2.1.0018' """ decode-config.py - Backup/Restore Sonoff-Tasmota configuration data @@ -824,7 +824,13 @@ Setting_6_4_1_7['flag3'][0].update ({ 'no_pullup': ('