diff --git a/CHANGELOG.md b/CHANGELOG.md index 87cfc3f1d..c17016372 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,11 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [9.3.1.3] +## [9.3.1.4] +### Added +- Command ``TuyaTempSetRes 0..3`` to control Tuya Temperature Set Resolution (#11781) + +## [9.3.1.3] 20210419 ### Added - Optional GUI file editor enabled with define ``GUI_EDIT_FILE`` by barbudor (#11668) - Initial support for universal display driver UDisplay by Gerhard Mutz. Enable by selecting any GPIO as ``Option A3`` (#11665) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 2036bb721..a8e111583 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -78,12 +78,13 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v9.3.1.3 +## Changelog v9.3.1.4 ### Added - Command ``Sensor80 1 <0..7>`` to control MFRC522 RFID antenna gain from 18dB (0) to 48dB (7) [#11073](https://github.com/arendst/Tasmota/issues/11073) - Command ``SerialBuffer 256..520`` to change hardware serial receive buffer size from default (256) to max local buffer size (520) [#11448](https://github.com/arendst/Tasmota/issues/11448) - Command ``SetOption126 1`` to enable DS18x20 arithmetic mean over teleperiod for JSON temperature based on [#11472](https://github.com/arendst/Tasmota/issues/11472) - Command ``Backlog0`` to allow execution of following commands without delay +- Command ``TuyaTempSetRes 0..3`` to control Tuya Temperature Set Resolution [#11781](https://github.com/arendst/Tasmota/issues/11781) - Commands ``MqttKeepAlive 1..100`` to set Mqtt Keep Alive timer (default 30) and ``MqttTimeout 1..100`` to set Mqtt Socket Timeout (default 4) [#5341](https://github.com/arendst/Tasmota/issues/5341) - Commands ``DisplayType`` to select sub-modules where implemented and ``DisplayInvert`` to select inverted display where implemented - Support for SML VBUS [#11125](https://github.com/arendst/Tasmota/issues/11125) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index f30354df0..a27c728d1 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -329,6 +329,7 @@ #define RF_DATA_RADIX false // [SetOption28] RF receive data format (false = hexadecimal, true = decimal) #define IR_DATA_RADIX false // [SetOption29] IR receive data format (false = hexadecimal, true = decimal) #define TUYA_SETOPTION_20 false // [SetOption54] Apply SetOption20 settings to Tuya device +#define TUYA_TEMP_SET_RES 1 // [TuyaTempSetRes] Maximum number of decimals (0 - 3) showing sensor TemperatureSet #define IR_ADD_RAW_DATA false // [SetOption58] Add IR Raw data to JSON message #define BUZZER_ENABLE false // [SetOption67] Enable buzzer when available #define DS18X20_PULL_UP false // [SetOption74] Enable internal pullup for single DS18x20 sensor diff --git a/tasmota/settings.h b/tasmota/settings.h index 9e8b31d26..8388bb81d 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -193,7 +193,44 @@ typedef union { uint32_t humidity_resolution : 2; uint32_t temperature_resolution : 2; }; -} SysBitfield2; +} SysMBitfield1; + +typedef union { + uint32_t data; // Allow bit manipulation + struct { + uint32_t spare00 : 1; // bit 0 + uint32_t spare01 : 1; // bit 1 + uint32_t spare02 : 1; // bit 2 + uint32_t spare03 : 1; // bit 3 + uint32_t spare04 : 1; // bit 4 + uint32_t spare05 : 1; // bit 5 + uint32_t spare06 : 1; // bit 6 + uint32_t spare07 : 1; // bit 7 + uint32_t spare08 : 1; // bit 8 + uint32_t spare09 : 1; // bit 9 + uint32_t spare10 : 1; // bit 10 + uint32_t spare11 : 1; // bit 11 + uint32_t spare12 : 1; // bit 12 + uint32_t spare13 : 1; // bit 13 + uint32_t spare14 : 1; // bit 14 + uint32_t spare15 : 1; // bit 15 + uint32_t spare16 : 1; // bit 16 + uint32_t spare17 : 1; // bit 17 + uint32_t spare18 : 1; // bit 18 + uint32_t spare19 : 1; // bit 19 + uint32_t spare20 : 1; // bit 20 + uint32_t spare21 : 1; // bit 21 + uint32_t spare22 : 1; // bit 22 + uint32_t spare23 : 1; // bit 23 + uint32_t spare24 : 1; // bit 24 + uint32_t spare25 : 1; // bit 25 + uint32_t spare26 : 1; // bit 26 + uint32_t spare27 : 1; // bit 27 + uint32_t spare28 : 1; // bit 28 + uint32_t spare29 : 1; // bit 29 + uint32_t temperature_set_res : 2; // bits 30/31 (v9.3.1.4) - (Tuya) + }; +} SysMBitfield2; typedef union { uint16_t data; @@ -517,7 +554,7 @@ struct { uint8_t free_558[100]; // 558 - SysBitfield2 flag2; // 5BC + SysMBitfield1 flag2; // 5BC unsigned long pulse_counter[MAX_COUNTERS]; // 5C0 uint16_t pulse_counter_type; // 5D0 uint16_t pulse_counter_debounce; // 5D2 @@ -674,9 +711,7 @@ struct { uint32_t device_group_share_in; // FCC Bitmask of device group items imported uint32_t device_group_share_out; // FD0 Bitmask of device group items exported uint32_t bootcount_reset_time; // FD4 - - int ex_adc_param4; // FD8 Free since 9.0.0.1 - + SysMBitfield2 mbflag2; // FD8 uint32_t shutter_button[MAX_SHUTTER_KEYS]; // FDC uint32_t i2c_drivers[3]; // FEC I2cDriver uint32_t cfg_timestamp; // FF8 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 9b52b867e..3eb10d608 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -707,10 +707,11 @@ void SettingsDefaultSet2(void) { // this little trick allows GCC to optimize the assignment by grouping values and doing only ORs SysBitfield flag = { 0 }; - SysBitfield2 flag2 = { 0 }; SysBitfield3 flag3 = { 0 }; SysBitfield4 flag4 = { 0 }; SysBitfield5 flag5 = { 0 }; + SysMBitfield1 flag2 = { 0 }; + SysMBitfield2 mbflag2 = { 0 }; #ifdef ESP8266 Settings.gpio16_converted = 0xF5A0; @@ -1064,6 +1065,7 @@ void SettingsDefaultSet2(void) { // Tuya flag3.tuya_apply_o20 |= TUYA_SETOPTION_20; flag3.tuya_serial_mqtt_publish |= MQTT_TUYA_RECEIVED; + mbflag2.temperature_set_res |= TUYA_TEMP_SET_RES; flag3.buzzer_enable |= BUZZER_ENABLE; flag3.shutter_mode |= SHUTTER_SUPPORT; @@ -1229,7 +1231,7 @@ void SettingsDelta(void) { if (Settings.version < 0x09000002) { char parameters[32]; snprintf_P(parameters, sizeof(parameters), PSTR("%d,%d,%d,%d,%d"), - Settings.ex_adc_param_type, Settings.ex_adc_param1, Settings.ex_adc_param2, Settings.ex_adc_param3, Settings.ex_adc_param4); + Settings.ex_adc_param_type, Settings.ex_adc_param1, Settings.ex_adc_param2, Settings.ex_adc_param3, Settings.mbflag2.data); SettingsUpdateText(SET_ADC_PARAM1, parameters); } #endif // ESP8266 @@ -1254,6 +1256,9 @@ void SettingsDelta(void) { Settings.mqtt_keepalive = MQTT_KEEPALIVE; Settings.mqtt_socket_timeout = MQTT_SOCKET_TIMEOUT; } + if (Settings.version < 0x09030104) { + Settings.mbflag2.data = 0; + } Settings.version = VERSION; SettingsSave(1); diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index d643f4943..2e298a623 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,6 +20,6 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x09030103; +const uint32_t VERSION = 0x09030104; #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 68fd8ecc3..a7dfb1353 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -100,10 +100,10 @@ const char kTuyaSensors[] PROGMEM = // List of available sensors (can be expande "|" D_JSON_TVOC "|" D_JSON_ECO2 "|" D_JSON_CO2 "|" D_JSON_GAS "||Timer1|Timer2|Timer3|TImer4"; const char kTuyaCommand[] PROGMEM = D_PRFX_TUYA "|" // Prefix - D_CMND_TUYA_MCU "|" D_CMND_TUYA_MCU_SEND_STATE "|" D_CMND_TUYARGB "|" D_CMND_TUYA_ENUM "|" D_CMND_TUYA_ENUM_LIST; + D_CMND_TUYA_MCU "|" D_CMND_TUYA_MCU_SEND_STATE "|" D_CMND_TUYARGB "|" D_CMND_TUYA_ENUM "|" D_CMND_TUYA_ENUM_LIST "|TempSetRes"; void (* const TuyaCommand[])(void) PROGMEM = { - &CmndTuyaMcu, &CmndTuyaSend, &CmndTuyaRgb, &CmndTuyaEnum, &CmndTuyaEnumList + &CmndTuyaMcu, &CmndTuyaSend, &CmndTuyaRgb, &CmndTuyaEnum, &CmndTuyaEnumList, &CmndTuyaTempSetRes }; /*********************************************************************************************\ @@ -242,6 +242,14 @@ void CmndTuyaRgb(void) { // Command to control the RGB format ResponseCmndNumber(Settings.tuya_fnid_map[230].dpid); } +void CmndTuyaTempSetRes(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) { + Settings.mbflag2.temperature_set_res = XdrvMailbox.payload; + } + ResponseCmndNumber(Settings.mbflag2.temperature_set_res); +} + void CmndTuyaEnum(void) { // Command to control up to four type 4 Enum uint16_t EnumIdx = XdrvMailbox.index; int32_t payload = XdrvMailbox.payload; @@ -336,6 +344,7 @@ float TuyaAdjustedTemperature(int16_t packetValue, uint8_t res) break; } } + /*********************************************************************************************\ * Internal Functions \*********************************************************************************************/ @@ -704,7 +713,7 @@ void TuyaProcessStatePacket(void) { fnId = TuyaGetFuncId(Tuya.buffer[dpidStart]); AddLog(LOG_LEVEL_DEBUG, PSTR("TYA: fnId=%d is set for dpId=%d"), fnId, Tuya.buffer[dpidStart]); - if (Tuya.buffer[dpidStart + 1] == 0) { + if (Tuya.buffer[dpidStart + 1] == 0) { #ifdef USE_ENERGY_SENSOR if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER_COMBINED) { if (dpDataLen == 8) { @@ -778,7 +787,11 @@ void TuyaProcessStatePacket(void) { } else { if (fnId > 74) { res = 0; - } else { res = Settings.flag2.temperature_resolution; } + } else if (fnId == 72) { + res = Settings.mbflag2.temperature_set_res; + } else { + res = Settings.flag2.temperature_resolution; + } GetTextIndexed(sname, sizeof(sname), (fnId-71), kTuyaSensors); ResponseClear(); // Clear retained message Response_P(PSTR("{\"TuyaSNS\":{\"%s\":%s}}"), sname, dtostrfd(TuyaAdjustedTemperature(packetValue, res), res, tempval)); // sensor update is just on change @@ -892,7 +905,7 @@ void TuyaProcessStatePacket(void) { ExecuteCommand(scmnd, SRC_SWITCH); } } - + } else if (Tuya.buffer[dpidStart + 1] == 4) { // Data Type 4 const unsigned char *dpData = (unsigned char*)&Tuya.buffer[dpidStart + 4]; @@ -1344,7 +1357,11 @@ void TuyaSensorsShow(bool json) } if (sensor > 74) { res = 0; - } else { res = Settings.flag2.temperature_resolution; } + } else if (sensor == 72) { + res = Settings.mbflag2.temperature_set_res; + } else { + res = Settings.flag2.temperature_resolution; + } GetTextIndexed(sname, sizeof(sname), (sensor-71), kTuyaSensors); ResponseAppend_P(PSTR("\"%s\":%s"), sname, @@ -1360,7 +1377,7 @@ void TuyaSensorsShow(bool json) break; case 72: WSContentSend_PD(PSTR("{s}" D_TEMPERATURE " Set{m}%s " D_UNIT_DEGREE "%c{e}"), - dtostrfd(TuyaAdjustedTemperature(Tuya.Sensors[1], Settings.flag2.temperature_resolution), Settings.flag2.temperature_resolution, tempval), TempUnit()); + dtostrfd(TuyaAdjustedTemperature(Tuya.Sensors[1], Settings.mbflag2.temperature_set_res), Settings.mbflag2.temperature_set_res, tempval), TempUnit()); break; case 73: WSContentSend_PD(HTTP_SNS_HUM, "", dtostrfd(TuyaAdjustedTemperature(Tuya.Sensors[2], Settings.flag2.temperature_resolution), Settings.flag2.temperature_resolution, tempval));