From cefe015c6880dc9e76908c59024b851cf810d231 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 22 Jun 2022 23:45:25 +0200 Subject: [PATCH] Bump version to v12.0.2.2 - Add commands to better control global temperature, humidity and pressure - Command ``GlobalTemp2 1..250`` to select Global Temperature source indexed from teleperiod occurance data (#15834) - Command ``GlobalHum2 1..250`` to select Global Humidity source indexed from teleperiod occurance data (#15834) - Command ``GlobalPress2 1..250`` to select Global Pressure source indexed from teleperiod occurance data (#15834) --- CHANGELOG.md | 14 +++- RELEASENOTES.md | 5 +- tasmota/include/i18n.h | 1 + tasmota/include/tasmota_types.h | 4 +- tasmota/include/tasmota_version.h | 2 +- tasmota/tasmota.ino | 18 ++--- tasmota/tasmota_support/settings.ino | 5 ++ tasmota/tasmota_support/support.ino | 36 +++++++--- tasmota/tasmota_support/support_command.ino | 77 +++++++++++++++------ tasmota/tasmota_support/support_tasmota.ino | 49 ++++++++++++- 10 files changed, 165 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dfab2aa4..eb048a005 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,17 +3,25 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [12.0.2.1] +## [12.0.2.2] ### Added -- Support for 5-channel light dimmer driver SM2335 used in SwitchBot Color Bulbs (#15839) +- Command ``GlobalTemp2 1..250`` to select Global Temperature source indexed from teleperiod occurance data (#15834) +- Command ``GlobalHum2 1..250`` to select Global Humidity source indexed from teleperiod occurance data (#15834) +- Command ``GlobalPress2 1..250`` to select Global Pressure source indexed from teleperiod occurance data (#15834) ### Changed ### Fixed -- ESP32 SendMail not working over ethernet (#15794) ### Removed +## [12.0.2.1] 20220622 +### Added +- Support for 5-channel light dimmer driver SM2335 used in SwitchBot Color Bulbs (#15839) + +### Fixed +- ESP32 SendMail not working over ethernet (#15794) + ## [Released] ## [12.0.2] 20220620 diff --git a/RELEASENOTES.md b/RELEASENOTES.md index a1e32ea8b..b235a6031 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -107,8 +107,11 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v12.0.2.1 +## Changelog v12.0.2.2 ### Added +- Command ``GlobalTemp2 1..250`` to select Global Temperature source indexed from teleperiod occurance data [#15834](https://github.com/arendst/Tasmota/issues/15834) +- Command ``GlobalHum2 1..250`` to select Global Humidity source indexed from teleperiod occurance data [#15834](https://github.com/arendst/Tasmota/issues/15834) +- Command ``GlobalPress2 1..250`` to select Global Pressure source indexed from teleperiod occurance data [#15834](https://github.com/arendst/Tasmota/issues/15834) - Support for 5-channel light dimmer driver SM2335 used in SwitchBot Color Bulbs [#15839](https://github.com/arendst/Tasmota/issues/15839) ### Breaking Changed diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index 87706b3b7..a4eb333da 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -364,6 +364,7 @@ #define D_CMND_HUMOFFSET "HumOffset" #define D_CMND_GLOBAL_TEMP "GlobalTemp" #define D_CMND_GLOBAL_HUM "GlobalHum" +#define D_CMND_GLOBAL_PRESS "GlobalPress" #define D_SO_WIFINOSLEEP "WifiNoSleep" diff --git a/tasmota/include/tasmota_types.h b/tasmota/include/tasmota_types.h index 2aaa9aaf6..78f92720a 100644 --- a/tasmota/include/tasmota_types.h +++ b/tasmota/include/tasmota_types.h @@ -674,9 +674,7 @@ typedef struct { uint16_t light_wakeup; // 4A6 uint8_t knx_CB_registered; // 4A8 Number of Group Address to write uint8_t switchmode[MAX_SWITCHES_SET]; // 4A9 - - uint8_t free_4c5[3]; // 4C5 - + uint8_t global_sensor_index[3]; // 4C5 uint16_t dns_timeout; // 4C8 uint8_t ds3502_state[MAX_DS3502]; // 4CA uint16_t influxdb_port; // 4CE diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 1ff29778d..4f5773c7b 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -20,6 +20,6 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x0C000201; // 12.0.2.1 +const uint32_t VERSION = 0x0C000202; // 12.0.2.2 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 00d3a21d1..fafd1d936 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -241,6 +241,15 @@ struct TasmotaGlobal_t { int16_t save_data_counter; // Counter and flag for config save to Flash RulesBitfield rules_flag; // Rule state flags (16 bits) + StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits) + uint16_t pwm_inverted; // PWM inverted flag (1 = inverted) - extended to 16 bits for ESP32 +#ifdef ESP32 + int16_t pwm_cur_value[MAX_PWMS]; // Current effective values of PWMs as applied to GPIOs + int16_t pwm_cur_phase[MAX_PWMS]; // Current phase values of PWMs as applied to GPIOs + int16_t pwm_value[MAX_PWMS]; // Wanted values of PWMs after update - -1 means no change + int16_t pwm_phase[MAX_PWMS]; // Wanted phase of PWMs after update - -1 means no change +#endif // ESP32 + bool serial_local; // Handle serial locally bool fallback_topic_flag; // Use Topic or FallbackTopic bool backlog_nodelay; // Execute all backlog commands with no delay @@ -261,14 +270,7 @@ struct TasmotaGlobal_t { bool no_autoexec; // Disable autoexec bool enable_logging; // Enable logging - StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits) - uint16_t pwm_inverted; // PWM inverted flag (1 = inverted) - extended to 16 bits for ESP32 -#ifdef ESP32 - int16_t pwm_cur_value[MAX_PWMS]; // Current effective values of PWMs as applied to GPIOs - int16_t pwm_cur_phase[MAX_PWMS]; // Current phase values of PWMs as applied to GPIOs - int16_t pwm_value[MAX_PWMS]; // Wanted values of PWMs after update - -1 means no change - int16_t pwm_phase[MAX_PWMS]; // Wanted phase of PWMs after update - -1 means no change -#endif // ESP32 + uint8_t user_globals[3]; // User set global temp/hum/press uint8_t init_state; // Tasmota init state uint8_t heartbeat_inverted; // Heartbeat pulse inverted flag uint8_t spi_enabled; // SPI configured diff --git a/tasmota/tasmota_support/settings.ino b/tasmota/tasmota_support/settings.ino index 35b9f9dbe..c25b2c75e 100644 --- a/tasmota/tasmota_support/settings.ino +++ b/tasmota/tasmota_support/settings.ino @@ -1544,6 +1544,11 @@ void SettingsDelta(void) { if (Settings->version < 0x0C000102) { // 12.0.1.2 Settings->dns_timeout = DNS_TIMEOUT; } + if (Settings->version < 0x0C000202) { // 12.0.2.2 + for (uint32_t i = 0; i < 3; i++) { + Settings->global_sensor_index[i] = 0; + } + } Settings->version = VERSION; SettingsSave(1); diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index 0cb2d6af2..0a39a346c 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -743,17 +743,17 @@ float ConvertTempToFahrenheit(float c) { float ConvertTempToCelsius(float c) { float result = c; - - if (!isnan(c) && !Settings->flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit + if (!isnan(c) && Settings->flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit result = (c - 32) / 1.8f; // Celsius } - result = result + (0.1f * Settings->temp_comp); return result; } void UpdateGlobalTemperature(float c) { - TasmotaGlobal.global_update = TasmotaGlobal.uptime; - TasmotaGlobal.temperature_celsius = c; + if (!Settings->global_sensor_index[0] && !TasmotaGlobal.user_globals[0]) { + TasmotaGlobal.global_update = TasmotaGlobal.uptime; + TasmotaGlobal.temperature_celsius = c; + } } float ConvertTemp(float c) { @@ -770,8 +770,10 @@ char TempUnit(void) { float ConvertHumidity(float h) { float result = h; - TasmotaGlobal.global_update = TasmotaGlobal.uptime; - TasmotaGlobal.humidity = h; + if (!Settings->global_sensor_index[1] && !TasmotaGlobal.user_globals[1]) { + TasmotaGlobal.global_update = TasmotaGlobal.uptime; + TasmotaGlobal.humidity = h; + } result = result + (0.1f * Settings->hum_comp); @@ -794,11 +796,27 @@ float CalcTempHumToDew(float t, float h) { return result; } +float ConvertHgToHpa(float p) { + // Convert mmHg (or inHg) to hPa + float result = p; + if (!isnan(p) && Settings->flag.pressure_conversion) { // SetOption24 - Switch between hPa or mmHg pressure unit + if (Settings->flag5.mm_vs_inch) { // SetOption139 - Switch between mmHg or inHg pressure unit + result = p * 33.86389f; // inHg (double to float saves 16 bytes!) + } else { + result = p * 1.3332239f; // mmHg (double to float saves 16 bytes!) + } + } + return result; +} + float ConvertPressure(float p) { + // Convert hPa to mmHg (or inHg) float result = p; - TasmotaGlobal.global_update = TasmotaGlobal.uptime; - TasmotaGlobal.pressure_hpa = p; + if (!Settings->global_sensor_index[2] && !TasmotaGlobal.user_globals[2]) { + TasmotaGlobal.global_update = TasmotaGlobal.uptime; + TasmotaGlobal.pressure_hpa = p; + } if (!isnan(p) && Settings->flag.pressure_conversion) { // SetOption24 - Switch between hPa or mmHg pressure unit if (Settings->flag5.mm_vs_inch) { // SetOption139 - Switch between mmHg or inHg pressure unit diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 584e35236..1ff925f03 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -33,7 +33,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" D_CMND_WIFI "|" D_CMND_DNSTIMEOUT "|" D_CMND_DEVICENAME "|" D_CMND_FN "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|" - D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM"|" D_CMND_SWITCHTEXT "|" + D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM"|" D_CMND_GLOBAL_PRESS "|" D_CMND_SWITCHTEXT "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -68,7 +68,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, &CmndWifi, &CmndDnsTimeout, &CmndDevicename, &CmndFriendlyname, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode, - &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndSwitchText, + &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndGlobalPress, &CmndSwitchText, #ifdef USE_I2C &CmndI2cScan, &CmndI2cDriver, #endif @@ -789,31 +789,68 @@ void CmndHumOffset(void) ResponseCmndFloat((float)(Settings->hum_comp) / 10, 1); } -void CmndGlobalTemp(void) -{ - if (XdrvMailbox.data_len > 0) { - float temperature = CharToFloat(XdrvMailbox.data); - if (!isnan(temperature) && Settings->flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit - temperature = (temperature - 32) / 1.8f; // Celsius +void CmndGlobalTemp(void) { + if (2 == XdrvMailbox.index) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) { + Settings->global_sensor_index[0] = XdrvMailbox.payload; + TasmotaGlobal.user_globals[0] = 0; } - if ((temperature >= -50.0f) && (temperature <= 100.0f)) { - ConvertTemp(temperature); - TasmotaGlobal.global_update = 1; // Keep global values just entered valid + ResponseCmndIdxNumber(Settings->global_sensor_index[0]); + } else { + if (XdrvMailbox.data_len > 0) { + // Set temperature based on SO8 (Celsius or Fahrenheit) + float temperature = ConvertTempToCelsius(CharToFloat(XdrvMailbox.data)); + // Temperature is now Celsius + if ((temperature >= -50.0f) && (temperature <= 100.0f)) { + TasmotaGlobal.temperature_celsius = temperature; + TasmotaGlobal.global_update = 1; // Keep global values just entered valid + TasmotaGlobal.user_globals[0] = 1; + } } + ResponseCmndFloat(TasmotaGlobal.temperature_celsius, 1); } - ResponseCmndFloat(TasmotaGlobal.temperature_celsius, 1); } -void CmndGlobalHum(void) -{ - if (XdrvMailbox.data_len > 0) { - float humidity = CharToFloat(XdrvMailbox.data); - if ((humidity >= 0.0f) && (humidity <= 100.0f)) { - ConvertHumidity(humidity); - TasmotaGlobal.global_update = 1; // Keep global values just entered valid +void CmndGlobalHum(void) { + if (2 == XdrvMailbox.index) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) { + Settings->global_sensor_index[1] = XdrvMailbox.payload; + TasmotaGlobal.user_globals[1] = 0; } + ResponseCmndIdxNumber(Settings->global_sensor_index[1]); + } else { + if (XdrvMailbox.data_len > 0) { + float humidity = CharToFloat(XdrvMailbox.data); + if ((humidity >= 0.0f) && (humidity <= 100.0f)) { + TasmotaGlobal.humidity = humidity; + TasmotaGlobal.global_update = 1; // Keep global values just entered valid + TasmotaGlobal.user_globals[1] = 1; + } + } + ResponseCmndFloat(TasmotaGlobal.humidity, 1); + } +} + +void CmndGlobalPress(void) { + if (2 == XdrvMailbox.index) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) { + Settings->global_sensor_index[2] = XdrvMailbox.payload; + TasmotaGlobal.user_globals[2] = 0; + } + ResponseCmndIdxNumber(Settings->global_sensor_index[2]); + } else { + if (XdrvMailbox.data_len > 0) { + // Set pressure based on SO24 (hPa or mmHg (or inHg based on SO139)) + float pressure = ConvertHgToHpa(CharToFloat(XdrvMailbox.data)); + // Pressure is now hPa + if ((pressure >= 0.0f) && (pressure <= 1200.0f)) { + TasmotaGlobal.pressure_hpa = pressure; + TasmotaGlobal.global_update = 1; // Keep global values just entered valid + TasmotaGlobal.user_globals[2] = 1; + } + } + ResponseCmndFloat(TasmotaGlobal.pressure_hpa, 1); } - ResponseCmndFloat(TasmotaGlobal.humidity, 1); } void CmndSleep(void) diff --git a/tasmota/tasmota_support/support_tasmota.ino b/tasmota/tasmota_support/support_tasmota.ino index 08d2f6f3d..efab5456f 100644 --- a/tasmota/tasmota_support/support_tasmota.ino +++ b/tasmota/tasmota_support/support_tasmota.ino @@ -845,6 +845,51 @@ String GetSwitchText(uint32_t i) { return switch_text; } +const char kGlobalValues[] PROGMEM = D_JSON_TEMPERATURE "|" D_JSON_HUMIDITY "|" D_JSON_PRESSURE; + +void GetGlobalValues(void) { + for (uint32_t type = 0; type < 3; type++) { + if (!Settings->global_sensor_index[type] || TasmotaGlobal.user_globals[0]) { continue; } + + char key[20]; + GetTextIndexed(key, sizeof(key), type, kGlobalValues); + + float value = -9999; + uint32_t idx = 0; + char *data = ResponseData(); + while (data) { + data = strstr(data, key); + if (data) { + idx++; + data += strlen(key) + 2; + float new_value = CharToFloat(data); + if (1 == idx) { value = new_value; } + +// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: %s value%d = %2_f"), key, idx, &new_value); + + if (idx == Settings->global_sensor_index[type]) { + value = new_value; + break; + } + } + } + if (value != -9999) { + switch (type) { + case 0: // Temperature + TasmotaGlobal.temperature_celsius = ConvertTempToCelsius(value); + break; + case 1: // Humidity + TasmotaGlobal.humidity = value; + break; + case 2: // Pressure + TasmotaGlobal.pressure_hpa = ConvertHgToHpa(value); + break; + } + TasmotaGlobal.global_update = TasmotaGlobal.uptime; + } + } +} + void MqttAppendSensorUnits(void) { if (ResponseContains_P(PSTR(D_JSON_PRESSURE))) { @@ -875,7 +920,9 @@ bool MqttShowSensor(bool call_show_sensor) XsnsCall(FUNC_JSON_APPEND); XdrvCall(FUNC_JSON_APPEND); - if (TasmotaGlobal.global_update && Settings->flag.mqtt_add_global_info) { + GetGlobalValues(); + + if (TasmotaGlobal.global_update && Settings->flag.mqtt_add_global_info) { // SetOption2 (MQTT) Add global temperature/humidity/pressure info to JSON sensor message if ((TasmotaGlobal.humidity > 0) || !isnan(TasmotaGlobal.temperature_celsius) || (TasmotaGlobal.pressure_hpa != 0)) { uint32_t add_comma = 0; ResponseAppend_P(PSTR(",\"Global\":{"));