diff --git a/tasmota/_changelog.ino b/tasmota/_changelog.ino index ec19b471a..b98b89210 100644 --- a/tasmota/_changelog.ino +++ b/tasmota/_changelog.ino @@ -6,6 +6,7 @@ * Add frequency to ADE7953 energy monitor as used in Shelly 2.5 by ljakob (#6778) * Add command SetOption74 0/1 to enable DS18x20 internal pull-up and remove define DS18B20_INTERNAL_PULLUP (#6795) * Fix better control of RGB/White when SetOption37 >128, added Dimmer1 and Dimmer2 commands (#6714) + * Add hide Alexa objects with friendlyname starting with '$' (#6722, #6762) * * 6.7.1.1 20191026 * Change ArduinoSlave to TasmotaSlave (Experimental) diff --git a/tasmota/settings.h b/tasmota/settings.h index c64820103..8cd575cf1 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -98,6 +98,44 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu }; } SysBitfield3; +typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... + uint32_t data; // Allow bit manipulation using SetOption + struct { // SetOption82 .. SetOption113 + uint32_t spare00 : 1; + uint32_t spare01 : 1; + uint32_t spare02 : 1; + uint32_t spare03 : 1; + uint32_t spare04 : 1; + uint32_t spare05 : 1; + uint32_t spare06 : 1; + uint32_t spare07 : 1; + uint32_t spare08 : 1; + uint32_t spare09 : 1; + uint32_t spare10 : 1; + uint32_t spare11 : 1; + uint32_t spare12 : 1; + uint32_t spare13 : 1; + uint32_t spare14 : 1; + uint32_t spare15 : 1; + uint32_t spare16 : 1; + uint32_t spare17 : 1; + uint32_t spare18 : 1; + uint32_t spare19 : 1; + uint32_t spare20 : 1; + uint32_t spare21 : 1; + uint32_t spare22 : 1; + uint32_t spare23 : 1; + uint32_t spare24 : 1; + uint32_t spare25 : 1; + uint32_t spare26 : 1; + uint32_t spare27 : 1; + uint32_t spare28 : 1; + uint32_t spare29 : 1; + uint32_t spare30 : 1; + uint32_t spare31 : 1; + }; +} SysBitfield4; + typedef union { uint32_t data; // Allow bit manipulation struct { @@ -227,7 +265,13 @@ struct SYSCFG { uint8_t weblog_level; // 1AC uint8_t mqtt_fingerprint[2][20]; // 1AD uint8_t adc_param_type; // 1D5 - uint8_t register8[16]; // 1D6 - 16 x 8-bit registers indexed by enum SettingsRegister8 + + uint8_t free_1d6[10]; // 1D6 + + SysBitfield4 flag4; // 1E0 + + uint8_t free_1e4[2]; // 1E4 + uint8_t shutter_accuracy; // 1E6 uint8_t mqttlog_level; // 1E7 uint8_t sps30_inuse_hours; // 1E8 @@ -389,6 +433,7 @@ struct SYSCFG { uint32_t deepsleep; // E94 uint16_t energy_power_delta; // E98 uint8_t shutter_motordelay[MAX_SHUTTERS]; // E9A + uint8_t free_e9e[346]; // E9E uint32_t cfg_timestamp; // FF8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 87fb7c845..c5f4371bc 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1064,7 +1064,7 @@ void SettingsDelta(void) } } if (Settings.version < 0x0606000C) { - memset(&Settings.register8, 0x00, sizeof(Settings.register8)); + memset((char*)&Settings +0x1D6, 0x00, 16); } if (Settings.version < 0x0606000F) { Settings.shutter_accuracy = 0; diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index d17307264..e127707c6 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -372,10 +372,11 @@ void CmndStatus(void) if ((0 == payload) || (3 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d,\"" D_CMND_WEBLOG "\":%d,\"" D_CMND_MQTTLOG "\":%d,\"" D_CMND_SYSLOG "\":%d,\"" D_CMND_LOGHOST "\":\"%s\",\"" D_CMND_LOGPORT "\":%d,\"" D_CMND_SSID "\":[\"%s\",\"%s\"],\"" D_CMND_TELEPERIOD "\":%d,\"" - D_JSON_RESOLUTION "\":\"%08X\",\"" D_CMND_SETOPTION "\":[\"%08X\",\"%s\",\"%08X\"]}}"), + D_JSON_RESOLUTION "\":\"%08X\",\"" D_CMND_SETOPTION "\":[\"%08X\",\"%s\",\"%08X\",\"%08X\"]}}"), Settings.seriallog_level, Settings.weblog_level, Settings.mqttlog_level, Settings.syslog_level, Settings.syslog_host, Settings.syslog_port, Settings.sta_ssid[0], Settings.sta_ssid[1], Settings.tele_period, - Settings.flag2.data, Settings.flag.data, ToHex_P((unsigned char*)Settings.param, PARAM8_SIZE, stemp2, sizeof(stemp2)), Settings.flag3.data); + Settings.flag2.data, Settings.flag.data, ToHex_P((unsigned char*)Settings.param, PARAM8_SIZE, stemp2, sizeof(stemp2)), + Settings.flag3.data, Settings.flag4.data); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "3")); } @@ -627,7 +628,7 @@ void CmndSavedata(void) void CmndSetoption(void) { - if (XdrvMailbox.index < 82) { + if (XdrvMailbox.index < 114) { uint32_t ptype; uint32_t pindex; if (XdrvMailbox.index <= 31) { // SetOption0 .. 31 = Settings.flag @@ -638,10 +639,15 @@ void CmndSetoption(void) ptype = 2; pindex = XdrvMailbox.index -32; // 0 .. 17 (= PARAM8_SIZE -1) } - else { // SetOption50 .. 81 = Settings.flag3 + + else if (XdrvMailbox.index <= 81) { // SetOption50 .. 81 = Settings.flag3 ptype = 1; pindex = XdrvMailbox.index -50; // 0 .. 31 } + else { // SetOption82 .. 113 = Settings.flag4 + ptype = 3; + pindex = XdrvMailbox.index -82; // 0 .. 31 + } if (XdrvMailbox.payload >= 0) { if (0 == ptype) { // SetOption0 .. 31 if (XdrvMailbox.payload <= 1) { @@ -690,6 +696,11 @@ void CmndSetoption(void) } } } + else if (3 == ptype) { // SetOption82 .. 113 + if (XdrvMailbox.payload <= 1) { + bitWrite(Settings.flag4.data, pindex, XdrvMailbox.payload); + } + } else { // SetOption32 .. 49 uint32_t param_low = 0; uint32_t param_high = 255; @@ -719,9 +730,18 @@ void CmndSetoption(void) } } if (ptype < 99) { - char stemp1[TOPSZ]; - if (2 == ptype) { snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), Settings.param[pindex]); } - ResponseCmndIdxChar((2 == ptype) ? stemp1 : (1 == ptype) ? GetStateText(bitRead(Settings.flag3.data, pindex)) : GetStateText(bitRead(Settings.flag.data, pindex))); + if (2 == ptype) { + ResponseCmndIdxNumber(Settings.param[pindex]); + } else { + uint32_t flag = Settings.flag.data; + if (1 == ptype) { + flag = Settings.flag3.data; + } + else if (3 == ptype) { + flag = Settings.flag4.data; + } + ResponseCmndIdxChar(GetStateText(bitRead(flag, pindex))); + } } } } diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 73fc192a8..9520a3613 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -250,11 +250,6 @@ enum SettingsParamIndex { P_HOLD_TIME, P_MAX_POWER_RETRY, P_BACKLOG_DELAY, P_MDN P_ex_ENERGY_TARIFF1, P_ex_ENERGY_TARIFF2, // SetOption47 .. SetOption48 P_MAX_PARAM8 }; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49 -enum SettingsRegister8 { R8_SPARE00, R8_SPARE01, R8_SPARE02, R8_SPARE03, - R8_SPARE04, R8_SPARE05, R8_SPARE06, R8_SPARE07, - R8_SPARE08, R8_SPARE09, R8_SPARE10, R8_SPARE11, - R8_SPARE12, R8_SPARE13, R8_SPARE14, R8_SPARE15 }; // Max size is 16 (Settings.register8[]) - enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_P1_SMART_METER, DZ_SHUTTER, DZ_MAX_SENSORS}; diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index 9289822fc..3b439ea2f 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -361,6 +361,13 @@ void HueLightStatus1(uint8_t device, String *response) response->replace("{light_status}", light_status); } +// Check whether this device should be reported to Alexa or considered hidden. +// Any device whose friendly name start with "$" is considered hidden +bool HueActive(uint8_t device) { + if (device > MAX_FRIENDLYNAMES) { device = MAX_FRIENDLYNAMES; } + return '$' != Settings.friendlyname[device-1][0]; +} + void HueLightStatus2(uint8_t device, String *response) { *response += FPSTR(HUE_LIGHTS_STATUS_JSON2); @@ -442,20 +449,22 @@ uint32_t findEchoGeneration(void) { return gen; } -void HueGlobalConfig(String *path) -{ +void HueGlobalConfig(String *path) { String response; uint8_t maxhue = (devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : devices_present; path->remove(0,1); // cut leading / to get - response = F("{\"lights\":{\""); + response = F("{\"lights\":{"); + bool appending = false; // do we need to add a comma to append for (uint32_t i = 1; i <= maxhue; i++) { - response += EncodeLightId(i); - response += F("\":{\"state\":"); - HueLightStatus1(i, &response); - HueLightStatus2(i, &response); - if (i < maxhue) { - response += ",\""; + if (HueActive(i)) { + if (appending) { response += ","; } + response += "\""; + response += EncodeLightId(i); + response += F("\":{\"state\":"); + HueLightStatus1(i, &response); + HueLightStatus2(i, &response); + appending = true; } } response += F("},\"groups\":{},\"schedules\":{},\"config\":"); @@ -493,14 +502,17 @@ void HueLights(String *path) path->remove(0,path->indexOf("/lights")); // Remove until /lights if (path->endsWith("/lights")) { // Got /lights - response = "{\""; + response = "{"; + bool appending = false; for (uint32_t i = 1; i <= maxhue; i++) { - response += EncodeLightId(i); - response += F("\":{\"state\":"); - HueLightStatus1(i, &response); - HueLightStatus2(i, &response); - if (i < maxhue) { - response += ",\""; + if (HueActive(i)) { + if (appending) { response += ","; } + response += "\""; + response += EncodeLightId(i); + response += F("\":{\"state\":"); + HueLightStatus1(i, &response); + HueLightStatus2(i, &response); + appending = true; } } #ifdef USE_SCRIPT_HUE diff --git a/tools/decode-status.py b/tools/decode-status.py index b50d920db..2b67a3fd1 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -86,7 +86,7 @@ a_setoption = [[ ],[ "Key hold time (ms)", "Sonoff POW Max_Power_Retry", - "(not used) Tuya MCU device id", + "Backlog delay (ms)", "(not used) mDNS delayed start (Sec)", "Boot loop retry offset (0 = disable)", "RGBWW remap", @@ -99,8 +99,8 @@ a_setoption = [[ "(not used) Tuya MCU voltage Id", "(not used) Tuya MCU current Id", "(not used) Tuya MCU power Id", - "Energy Tariff1 start hour", - "Energy Tariff2 start hour", + "(not used) Energy Tariff1 start hour", + "(not used) Energy Tariff2 start hour", "", ],[ "Timers enabled", @@ -131,6 +131,15 @@ a_setoption = [[ "","", "Enable shutter support", "Invert PCF8574 ports" + ],[ + "","","","", + "","","","", + "","","","", + "","","","", + "","","","", + "","","","", + "","","","", + "","","","" ]] a_features = [[ @@ -246,7 +255,7 @@ def StartDecode(): options.append(str("{0:2d} ({1:3d}) {2}".format(i, split_register[opt_idx], option))) i += 1 - if r in (0, 2): #registers 1 and 3 hold binary values + if r in (0, 2, 3): #registers 1 and 3 hold binary values for opt_idx, option in enumerate(opt_group): i_register = int(register,16) state = (i_register >> opt_idx) & 1