From 3d1887abb5c4891c523fe6dedd92e76be1621d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 00:59:36 +0300 Subject: [PATCH 01/44] Handle value changes and prevent old values from being displayed --- components/samsung_ac/samsung_ac.cpp | 35 +++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index d0215fd8..89c19b29 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -15,7 +15,9 @@ namespace esphome ESP_LOGW(TAG, "setup"); } } - + std::map last_values; + std::map last_update_time; + const unsigned long TIMEOUT_PERIOD = 10000; void Samsung_AC::update() { if (debug_log_messages) @@ -23,6 +25,37 @@ namespace esphome ESP_LOGW(TAG, "update"); } + for (const auto &pair : devices_) + { + std::string current_value = pair.second->get_current_value(); + std::string address = pair.second->address; + unsigned long now = millis(); + + if (last_values[address] != current_value) + { + // Değer değiştiyse, yeni değeri kaydedin ve işlemi başlatın + last_values[address] = current_value; + last_update_time[address] = now; + + // Burada yeni değeri UI'ya yansıtma işlemi yapılabilir + ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); + } + else + { + // Değer aynıysa bu adımı atlayın + ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); + + // Zaman aşımını kontrol edin + if (now - last_update_time[address] > TIMEOUT_PERIOD) + { + ESP_LOGW(TAG, "Timeout for device: %s", address.c_str()); + last_values[address] = "default_value"; // Örnek varsayılan değer + last_update_time[address] = now; + } + continue; + } + } + debug_mqtt_connect(debug_mqtt_host, debug_mqtt_port, debug_mqtt_username, debug_mqtt_password); // Waiting for first update before beginning processing data From 79b5e0f2817d113e78c7e0e14fa20764babb4cce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 01:04:02 +0300 Subject: [PATCH 02/44] Handle value changes and prevent old values from being displayed --- components/samsung_ac/samsung_ac.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 89c19b29..28fbf784 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -27,14 +27,14 @@ namespace esphome for (const auto &pair : devices_) { - std::string current_value = pair.second->get_current_value(); + optional current_value = pair.second->_cur_mode; std::string address = pair.second->address; unsigned long now = millis(); - if (last_values[address] != current_value) + if (current_value.has_value() && last_values[address] != std::to_string(current_value.value())) { // Değer değiştiyse, yeni değeri kaydedin ve işlemi başlatın - last_values[address] = current_value; + last_values[address] = std::to_string(current_value.value()); last_update_time[address] = now; // Burada yeni değeri UI'ya yansıtma işlemi yapılabilir @@ -55,7 +55,7 @@ namespace esphome continue; } } - + debug_mqtt_connect(debug_mqtt_host, debug_mqtt_port, debug_mqtt_username, debug_mqtt_password); // Waiting for first update before beginning processing data From dcf5c7c456da8ba1d5d6f0d7cc559d9606b6c8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 01:06:39 +0300 Subject: [PATCH 03/44] Handle value changes and prevent old values from being displayed --- components/samsung_ac/samsung_ac.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 28fbf784..151a2a7d 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -18,6 +18,28 @@ namespace esphome std::map last_values; std::map last_update_time; const unsigned long TIMEOUT_PERIOD = 10000; + std::string mode_to_string(Mode mode) + { + switch (mode) + { + case Mode::OFF: + return "OFF"; + case Mode::AUTO: + return "AUTO"; + case Mode::COOL: + return "COOL"; + case Mode::HEAT: + return "HEAT"; + case Mode::FAN_ONLY: + return "FAN_ONLY"; + case Mode::DRY: + return "DRY"; + // Diğer modlar için aynı şekilde ekleyebilirsiniz + default: + return "UNKNOWN"; + } + } + void Samsung_AC::update() { if (debug_log_messages) @@ -31,10 +53,10 @@ namespace esphome std::string address = pair.second->address; unsigned long now = millis(); - if (current_value.has_value() && last_values[address] != std::to_string(current_value.value())) + if (current_value.has_value() && last_values[address] != mode_to_string(current_value.value())) { // Değer değiştiyse, yeni değeri kaydedin ve işlemi başlatın - last_values[address] = std::to_string(current_value.value()); + last_values[address] = mode_to_string(current_value.value()); last_update_time[address] = now; // Burada yeni değeri UI'ya yansıtma işlemi yapılabilir From 4abee34d73a9fcc2de8a975b7c9bcd2a01cb92a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 01:09:50 +0300 Subject: [PATCH 04/44] Handle value changes and prevent old values from being displayed --- components/samsung_ac/samsung_ac.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 151a2a7d..0d7754d1 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -22,21 +22,19 @@ namespace esphome { switch (mode) { - case Mode::OFF: - return "OFF"; - case Mode::AUTO: - return "AUTO"; - case Mode::COOL: - return "COOL"; - case Mode::HEAT: - return "HEAT"; - case Mode::FAN_ONLY: - return "FAN_ONLY"; - case Mode::DRY: - return "DRY"; - // Diğer modlar için aynı şekilde ekleyebilirsiniz + case Mode::Auto: + return "Auto"; + case Mode::Cool: + return "Cool"; + case Mode::Dry: + return "Dry"; + case Mode::Fan: + return "Fan"; + case Mode::Heat: + return "Heat"; + case Mode::Unknown: default: - return "UNKNOWN"; + return "Unknown"; } } From 489d582c200b298ef1dc9f978fe3454174c3c32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 01:15:32 +0300 Subject: [PATCH 05/44] Handle value changes and prevent old values from being displayed --- components/samsung_ac/samsung_ac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 0d7754d1..59a45214 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -17,7 +17,7 @@ namespace esphome } std::map last_values; std::map last_update_time; - const unsigned long TIMEOUT_PERIOD = 10000; + const unsigned long TIMEOUT_PERIOD = 1500; std::string mode_to_string(Mode mode) { switch (mode) From 19df6d5efd0e08d21cec1bb7607c7d5fc8ac6fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 10:14:15 +0300 Subject: [PATCH 06/44] Handle value changes and prevent old values from being displayed --- components/samsung_ac/samsung_ac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 59a45214..2d3bef26 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -17,7 +17,7 @@ namespace esphome } std::map last_values; std::map last_update_time; - const unsigned long TIMEOUT_PERIOD = 1500; + const unsigned long TIMEOUT_PERIOD = 1000; std::string mode_to_string(Mode mode) { switch (mode) From 0027cb308ddd6cf888be2c78f35d9edf6c788f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 18:33:28 +0300 Subject: [PATCH 07/44] Fix build on ESP-IDF: Change logging message type interpolation #166 --- components/samsung_ac/protocol_nasa.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/samsung_ac/protocol_nasa.cpp b/components/samsung_ac/protocol_nasa.cpp index 25aa82de..be6c9b3e 100644 --- a/components/samsung_ac/protocol_nasa.cpp +++ b/components/samsung_ac/protocol_nasa.cpp @@ -21,9 +21,9 @@ namespace esphome return value - (int)65535 /*uint16 max*/ - 1.0; } -#define LOG_MESSAGE(message_name, temp, source, dest) \ - if (debug_log_messages) \ - { \ +#define LOG_MESSAGE(message_name, temp, source, dest) \ + if (debug_log_messages) \ + { \ ESP_LOGW(TAG, "s:%s d:%s " #message_name " %g", source.c_str(), dest.c_str(), static_cast(temp)); \ } From 9623be72a923502bf208034cf55d53f89f02af28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 18:52:27 +0300 Subject: [PATCH 08/44] Fix 1 --- components/samsung_ac/samsung_ac.cpp | 58 ++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 2d3bef26..cde51296 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -44,38 +44,80 @@ namespace esphome { ESP_LOGW(TAG, "update"); } - for (const auto &pair : devices_) { optional current_value = pair.second->_cur_mode; std::string address = pair.second->address; unsigned long now = millis(); + if (pending_changes.find(address) != pending_changes.end()) + { + if (current_value.has_value() && current_value.value() == pending_changes[address]) + { + pending_changes.erase(address); + } + else + { + ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); + continue; + } + } + if (current_value.has_value() && last_values[address] != mode_to_string(current_value.value())) { - // Değer değiştiyse, yeni değeri kaydedin ve işlemi başlatın + pending_changes[address] = current_value.value(); last_values[address] = mode_to_string(current_value.value()); last_update_time[address] = now; - // Burada yeni değeri UI'ya yansıtma işlemi yapılabilir ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); } else { - // Değer aynıysa bu adımı atlayın ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); - // Zaman aşımını kontrol edin if (now - last_update_time[address] > TIMEOUT_PERIOD) { - ESP_LOGW(TAG, "Timeout for device: %s", address.c_str()); - last_values[address] = "default_value"; // Örnek varsayılan değer - last_update_time[address] = now; + if (pending_changes.find(address) != pending_changes.end()) + { + ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); + pending_changes.erase(address); + } } continue; } } + // for (const auto &pair : devices_) + //{ + // optional current_value = pair.second->_cur_mode; + // std::string address = pair.second->address; + // unsigned long now = millis(); + // + // if (current_value.has_value() && last_values[address] != mode_to_string(current_value.value())) + // { + // // Değer değiştiyse, yeni değeri kaydedin ve işlemi başlatın + // last_values[address] = mode_to_string(current_value.value()); + // last_update_time[address] = now; + // + // // Burada yeni değeri UI'ya yansıtma işlemi yapılabilir + // ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); + // } + // else + // { + // // Değer aynıysa bu adımı atlayın + // ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); + // + // // Zaman aşımını kontrol edin + // if (now - last_update_time[address] > TIMEOUT_PERIOD) + // { + // ESP_LOGW(TAG, "Timeout for device: %s", address.c_str()); + // last_values[address] = "default_value"; // Örnek varsayılan değer + // last_update_time[address] = now; + // } + // continue; + // } + //} + debug_mqtt_connect(debug_mqtt_host, debug_mqtt_port, debug_mqtt_username, debug_mqtt_password); // Waiting for first update before beginning processing data From d06023fdf81b2ed4eefbb0d4ce643528fb5b619f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 18:56:32 +0300 Subject: [PATCH 09/44] Fix 2 --- components/samsung_ac/samsung_ac.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index cde51296..6942c166 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -17,6 +17,7 @@ namespace esphome } std::map last_values; std::map last_update_time; + std::map pending_changes; const unsigned long TIMEOUT_PERIOD = 1000; std::string mode_to_string(Mode mode) { @@ -44,6 +45,7 @@ namespace esphome { ESP_LOGW(TAG, "update"); } + for (const auto &pair : devices_) { optional current_value = pair.second->_cur_mode; From c1e7343053fb58fa99b1c41626626bbe2094e7d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 22:46:49 +0300 Subject: [PATCH 10/44] outdoor_operation_mode add --- components/samsung_ac/__init__.py | 12 ++ components/samsung_ac/protocol.h | 127 ++++++++++++++++++++++ components/samsung_ac/protocol_nasa.cpp | 14 ++- components/samsung_ac/protocol_nasa.h | 1 + components/samsung_ac/samsung_ac.cpp | 31 ------ components/samsung_ac/samsung_ac_device.h | 12 ++ 6 files changed, 163 insertions(+), 34 deletions(-) diff --git a/components/samsung_ac/__init__.py b/components/samsung_ac/__init__.py index fde12c11..e118af0d 100644 --- a/components/samsung_ac/__init__.py +++ b/components/samsung_ac/__init__.py @@ -73,6 +73,8 @@ CONF_DEVICE_CUSTOM_MESSAGE = "message" CONF_DEVICE_CUSTOM_RAW_FILTERS = "raw_filters" CONF_DEVICE_ERROR_CODE = "error_code" +CONF_DEVICE_OUTDOOR_OPERATION_MODE = "outdoor_operation_mode" + CONF_CAPABILITIES = "capabilities" @@ -206,6 +208,11 @@ def error_code_sensor_schema(message: int): accuracy_decimals=1, device_class=DEVICE_CLASS_TEMPERATURE, state_class=STATE_CLASS_MEASUREMENT, + ), + cv.Optional(CONF_DEVICE_OUTDOOR_OPERATION_MODE): sensor.sensor_schema( + unit_of_measurement="", + accuracy_decimals=0, + icon="mdi:factory", ), cv.Optional(CONF_DEVICE_ERROR_CODE): error_code_sensor_schema(0x8235), cv.Optional(CONF_DEVICE_TARGET_TEMPERATURE): NUMBER_SCHEMA, @@ -423,6 +430,11 @@ async def to_code(config): cg.add(var_dev.add_custom_sensor( cust_sens[CONF_DEVICE_CUSTOM_MESSAGE], sens)) + if CONF_DEVICE_OUTDOOR_OPERATION_MODE in device: + conf = device[CONF_DEVICE_OUTDOOR_OPERATION_MODE] + sens = await sensor.new_sensor(conf) + cg.add(var_dev.set_outdoor_operation_mode_sensor(sens)) + for key in CUSTOM_SENSOR_KEYS: if key in device: conf = device[key] diff --git a/components/samsung_ac/protocol.h b/components/samsung_ac/protocol.h index b7e0bfc4..21feab7e 100644 --- a/components/samsung_ac/protocol.h +++ b/components/samsung_ac/protocol.h @@ -70,6 +70,48 @@ namespace esphome All = 3 }; + enum class OutdoorOperationMode + { + OP_STOP = 0, + OP_SAFETY = 1, + OP_NORMAL = 2, + OP_BALANCE = 3, + OP_RECOVERY = 4, + OP_DEICE = 5, + OP_COMPDOWN = 6, + OP_PROHIBIT = 7, + OP_LINEJIG = 8, + OP_PCBJIG = 9, + OP_TEST = 10, + OP_CHARGE = 11, + OP_PUMPDOWN = 12, + OP_PUMPOUT = 13, + OP_VACCUM = 14, + OP_CALORYJIG = 15, + OP_PUMPDOWNSTOP = 16, + OP_SUBSTOP = 17, + OP_CHECKPIPE = 18, + OP_CHECKREF = 19, + OP_FPTJIG = 20, + OP_NONSTOP_HEAT_COOL_CHANGE = 21, + OP_AUTO_INSPECT = 22, + OP_ELECTRIC_DISCHARGE = 23, + OP_SPLIT_DEICE = 24, + OP_INVETER_CHECK = 25, + OP_NONSTOP_DEICE = 26, + OP_REM_TEST = 27, + OP_RATING = 28, + OP_PC_TEST = 29, + OP_PUMPDOWN_THERMOOFF = 30, + OP_3PHASE_TEST = 31, + OP_SMARTINSTALL_TEST = 32, + OP_DEICE_PERFORMANCE_TEST = 33, + OP_INVERTER_FAN_PBA_CHECK = 34, + OP_AUTO_PIPE_PAIRING = 35, + OP_AUTO_CHARGE = 36, + OP_UNKNOWN = -1 + }; + class MessageTarget { public: @@ -95,6 +137,8 @@ namespace esphome virtual optional> get_custom_sensors(const std::string address) = 0; virtual void set_custom_sensor(const std::string address, uint16_t message_number, float value) = 0; virtual void set_error_code(const std::string address, int error_code) = 0; + virtual void set_outdoor_operation_mode(const std::string &address, OutdoorOperationMode outdooroperationmode) = 0; + }; struct ProtocolRequest @@ -152,3 +196,86 @@ namespace esphome } // namespace samsung_ac } // namespace esphome + +inline std::string outdoor_operation_mode_to_string(OutdoorOperationMode mode) +{ + switch (mode) + { + case OutdoorOperationMode::OP_STOP: + return "OP_STOP: Outdoor unit is stopped."; + case OutdoorOperationMode::OP_SAFETY: + return "OP_SAFETY: Operating in safety mode."; + case OutdoorOperationMode::OP_NORMAL: + return "OP_NORMAL: Normal operation mode."; + case OutdoorOperationMode::OP_BALANCE: + return "OP_BALANCE: Balancing mode."; + case OutdoorOperationMode::OP_RECOVERY: + return "OP_RECOVERY: Recovery mode."; + case OutdoorOperationMode::OP_DEICE: + return "OP_DEICE: Defrost mode."; + case OutdoorOperationMode::OP_COMPDOWN: + return "OP_COMPDOWN: Compressor down mode."; + case OutdoorOperationMode::OP_PROHIBIT: + return "OP_PROHIBIT: Prohibited state."; + case OutdoorOperationMode::OP_LINEJIG: + return "OP_LINEJIG: Line jig mode."; + case OutdoorOperationMode::OP_PCBJIG: + return "OP_PCBJIG: PCB jig mode."; + case OutdoorOperationMode::OP_TEST: + return "OP_TEST: Test mode."; + case OutdoorOperationMode::OP_CHARGE: + return "OP_CHARGE: Charge mode."; + case OutdoorOperationMode::OP_PUMPDOWN: + return "OP_PUMPDOWN: Pump down mode."; + case OutdoorOperationMode::OP_PUMPOUT: + return "OP_PUMPOUT: Pump out mode."; + case OutdoorOperationMode::OP_VACCUM: + return "OP_VACCUM: Vacuum mode."; + case OutdoorOperationMode::OP_CALORYJIG: + return "OP_CALORYJIG: Calory jig mode."; + case OutdoorOperationMode::OP_PUMPDOWNSTOP: + return "OP_PUMPDOWNSTOP: Pump down stop mode."; + case OutdoorOperationMode::OP_SUBSTOP: + return "OP_SUBSTOP: Sub stop mode."; + case OutdoorOperationMode::OP_CHECKPIPE: + return "OP_CHECKPIPE: Pipe check mode."; + case OutdoorOperationMode::OP_CHECKREF: + return "OP_CHECKREF: Refrigerant check mode."; + case OutdoorOperationMode::OP_FPTJIG: + return "OP_FPTJIG: FPT jig mode."; + case OutdoorOperationMode::OP_NONSTOP_HEAT_COOL_CHANGE: + return "OP_NONSTOP_HEAT_COOL_CHANGE: Non-stop heat/cool change mode."; + case OutdoorOperationMode::OP_AUTO_INSPECT: + return "OP_AUTO_INSPECT: Auto inspection mode."; + case OutdoorOperationMode::OP_ELECTRIC_DISCHARGE: + return "OP_ELECTRIC_DISCHARGE: Electric discharge mode."; + case OutdoorOperationMode::OP_SPLIT_DEICE: + return "OP_SPLIT_DEICE: Split defrost mode."; + case OutdoorOperationMode::OP_INVETER_CHECK: + return "OP_INVETER_CHECK: Inverter check mode."; + case OutdoorOperationMode::OP_NONSTOP_DEICE: + return "OP_NONSTOP_DEICE: Non-stop defrost mode."; + case OutdoorOperationMode::OP_REM_TEST: + return "OP_REM_TEST: Remote test mode."; + case OutdoorOperationMode::OP_RATING: + return "OP_RATING: Rating mode."; + case OutdoorOperationMode::OP_PC_TEST: + return "OP_PC_TEST: PC test mode."; + case OutdoorOperationMode::OP_PUMPDOWN_THERMOOFF: + return "OP_PUMPDOWN_THERMOOFF: Thermo-off pump down mode."; + case OutdoorOperationMode::OP_3PHASE_TEST: + return "OP_3PHASE_TEST: Three-phase test mode."; + case OutdoorOperationMode::OP_SMARTINSTALL_TEST: + return "OP_SMARTINSTALL_TEST: Smart install test mode."; + case OutdoorOperationMode::OP_DEICE_PERFORMANCE_TEST: + return "OP_DEICE_PERFORMANCE_TEST: Defrost performance test mode."; + case OutdoorOperationMode::OP_INVERTER_FAN_PBA_CHECK: + return "OP_INVERTER_FAN_PBA_CHECK: Inverter fan PBA check mode."; + case OutdoorOperationMode::OP_AUTO_PIPE_PAIRING: + return "OP_AUTO_PIPE_PAIRING: Auto pipe pairing mode."; + case OutdoorOperationMode::OP_AUTO_CHARGE: + return "OP_AUTO_CHARGE: Automatic charge mode."; + default: + return "OP_UNKNOWN: Unknown operation mode."; + } +} diff --git a/components/samsung_ac/protocol_nasa.cpp b/components/samsung_ac/protocol_nasa.cpp index be6c9b3e..6b644716 100644 --- a/components/samsung_ac/protocol_nasa.cpp +++ b/components/samsung_ac/protocol_nasa.cpp @@ -722,6 +722,16 @@ namespace esphome target->set_error_code(source, code); break; } + case MessageNumber::ENUM_outdoor_operation_mode: + { + int code = static_cast(message.value); + if (debug_log_messages) + { + ESP_LOGW(TAG, "s:%s d:%s ENUM_outdoor_operation_mode %d", source.c_str(), dest.c_str(), code); + } + target->set_outdoor_operation_mode(source, code); + break; + } default: { @@ -861,11 +871,9 @@ namespace esphome void process_messageset_debug(std::string source, std::string dest, MessageSet &message, MessageTarget *target) { - if (source == "20.00.00" || source == "20.00.01" || source == "20.00.03") + if (source == "20.00.00" || source == "20.00.01" || source == "20.00.02" || source == "20.00.03") return; - // return; // :) - switch ((uint16_t)message.messageNumber) { case 0x4003: diff --git a/components/samsung_ac/protocol_nasa.h b/components/samsung_ac/protocol_nasa.h index b987e24b..af811d9c 100644 --- a/components/samsung_ac/protocol_nasa.h +++ b/components/samsung_ac/protocol_nasa.h @@ -81,6 +81,7 @@ namespace esphome ENUM_in_louver_hl_swing = 0x4011, ENUM_in_louver_lr_swing = 0x407e, ENUM_in_state_humidity_percent = 0x4038, + ENUM_outdoor_operation_mode = 0x8001, VAR_in_temp_room_f = 0x4203, VAR_in_temp_target_f = 0x4201, VAR_in_temp_water_outlet_target_f = 0x4247, diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 6942c166..764b91b0 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -89,37 +89,6 @@ namespace esphome } } - // for (const auto &pair : devices_) - //{ - // optional current_value = pair.second->_cur_mode; - // std::string address = pair.second->address; - // unsigned long now = millis(); - // - // if (current_value.has_value() && last_values[address] != mode_to_string(current_value.value())) - // { - // // Değer değiştiyse, yeni değeri kaydedin ve işlemi başlatın - // last_values[address] = mode_to_string(current_value.value()); - // last_update_time[address] = now; - // - // // Burada yeni değeri UI'ya yansıtma işlemi yapılabilir - // ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); - // } - // else - // { - // // Değer aynıysa bu adımı atlayın - // ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); - // - // // Zaman aşımını kontrol edin - // if (now - last_update_time[address] > TIMEOUT_PERIOD) - // { - // ESP_LOGW(TAG, "Timeout for device: %s", address.c_str()); - // last_values[address] = "default_value"; // Örnek varsayılan değer - // last_update_time[address] = now; - // } - // continue; - // } - //} - debug_mqtt_connect(debug_mqtt_host, debug_mqtt_port, debug_mqtt_username, debug_mqtt_password); // Waiting for first update before beginning processing data diff --git a/components/samsung_ac/samsung_ac_device.h b/components/samsung_ac/samsung_ac_device.h index e80c8e93..18ec32dd 100644 --- a/components/samsung_ac/samsung_ac_device.h +++ b/components/samsung_ac/samsung_ac_device.h @@ -108,6 +108,7 @@ namespace esphome sensor::Sensor *indoor_eva_in_temperature{nullptr}; sensor::Sensor *indoor_eva_out_temperature{nullptr}; sensor::Sensor *error_code{nullptr}; + sensor::Sensor *outdoor_operation_mode{nullptr}; Samsung_AC_Number *target_temperature{nullptr}; Samsung_AC_Number *water_outlet_target{nullptr}; Samsung_AC_Number *target_water_temperature{nullptr}; @@ -145,6 +146,11 @@ namespace esphome error_code = sensor; } + void set_outdoor_operation_mode_sensor(sensor::Sensor *sensor) + { + outdoor_operation_mode = sensor; + } + void add_custom_sensor(int message_number, sensor::Sensor *sensor) { Samsung_AC_Sensor cust_sensor; @@ -427,6 +433,12 @@ namespace esphome error_code->publish_state(value); } + void update_outdoor_operation_mode(int value) + { + if (outdoor_operation_mode != nullptr) + outdoor_operation_mode->publish_state(value); + } + void update_custom_sensor(uint16_t message_number, float value) { for (auto &sensor : custom_sensors) From be2d23361c17ad14c76119557ee56bada21aab43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 22:47:06 +0300 Subject: [PATCH 11/44] outdoor_operation_mode add. --- components/samsung_ac/samsung_ac.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/samsung_ac/samsung_ac.h b/components/samsung_ac/samsung_ac.h index 968e6908..7af186ca 100644 --- a/components/samsung_ac/samsung_ac.h +++ b/components/samsung_ac/samsung_ac.h @@ -193,6 +193,7 @@ namespace esphome if (dev != nullptr) dev->update_custom_sensor(message_number, value); } + void /*MessageTarget::*/ set_error_code(const std::string address, int value) override { Samsung_AC_Device *dev = find_device(address); @@ -200,6 +201,13 @@ namespace esphome dev->update_error_code(value); } + void /*MessageTarget::*/ set_outdoor_operation_mode(const std::string address, int value) override + { + Samsung_AC_Device *dev = find_device(address); + if (dev != nullptr) + dev->update_outdoor_operation_mode(value); + } + protected: Samsung_AC_Device *find_device(const std::string address) { From 8a9d0456347b4e0aa8ba1ddced4ab652b2b05b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 22:55:18 +0300 Subject: [PATCH 12/44] outdoor_operation_mode delete :). --- components/samsung_ac/__init__.py | 11 -- components/samsung_ac/protocol.h | 129 +--------------------- components/samsung_ac/protocol_nasa.cpp | 22 ---- components/samsung_ac/protocol_nasa.h | 1 - components/samsung_ac/samsung_ac_device.h | 12 -- 5 files changed, 1 insertion(+), 174 deletions(-) diff --git a/components/samsung_ac/__init__.py b/components/samsung_ac/__init__.py index e118af0d..b035f83d 100644 --- a/components/samsung_ac/__init__.py +++ b/components/samsung_ac/__init__.py @@ -73,7 +73,6 @@ CONF_DEVICE_CUSTOM_MESSAGE = "message" CONF_DEVICE_CUSTOM_RAW_FILTERS = "raw_filters" CONF_DEVICE_ERROR_CODE = "error_code" -CONF_DEVICE_OUTDOOR_OPERATION_MODE = "outdoor_operation_mode" @@ -208,11 +207,6 @@ def error_code_sensor_schema(message: int): accuracy_decimals=1, device_class=DEVICE_CLASS_TEMPERATURE, state_class=STATE_CLASS_MEASUREMENT, - ), - cv.Optional(CONF_DEVICE_OUTDOOR_OPERATION_MODE): sensor.sensor_schema( - unit_of_measurement="", - accuracy_decimals=0, - icon="mdi:factory", ), cv.Optional(CONF_DEVICE_ERROR_CODE): error_code_sensor_schema(0x8235), cv.Optional(CONF_DEVICE_TARGET_TEMPERATURE): NUMBER_SCHEMA, @@ -430,11 +424,6 @@ async def to_code(config): cg.add(var_dev.add_custom_sensor( cust_sens[CONF_DEVICE_CUSTOM_MESSAGE], sens)) - if CONF_DEVICE_OUTDOOR_OPERATION_MODE in device: - conf = device[CONF_DEVICE_OUTDOOR_OPERATION_MODE] - sens = await sensor.new_sensor(conf) - cg.add(var_dev.set_outdoor_operation_mode_sensor(sens)) - for key in CUSTOM_SENSOR_KEYS: if key in device: conf = device[key] diff --git a/components/samsung_ac/protocol.h b/components/samsung_ac/protocol.h index 21feab7e..2fc515c6 100644 --- a/components/samsung_ac/protocol.h +++ b/components/samsung_ac/protocol.h @@ -70,49 +70,7 @@ namespace esphome All = 3 }; - enum class OutdoorOperationMode - { - OP_STOP = 0, - OP_SAFETY = 1, - OP_NORMAL = 2, - OP_BALANCE = 3, - OP_RECOVERY = 4, - OP_DEICE = 5, - OP_COMPDOWN = 6, - OP_PROHIBIT = 7, - OP_LINEJIG = 8, - OP_PCBJIG = 9, - OP_TEST = 10, - OP_CHARGE = 11, - OP_PUMPDOWN = 12, - OP_PUMPOUT = 13, - OP_VACCUM = 14, - OP_CALORYJIG = 15, - OP_PUMPDOWNSTOP = 16, - OP_SUBSTOP = 17, - OP_CHECKPIPE = 18, - OP_CHECKREF = 19, - OP_FPTJIG = 20, - OP_NONSTOP_HEAT_COOL_CHANGE = 21, - OP_AUTO_INSPECT = 22, - OP_ELECTRIC_DISCHARGE = 23, - OP_SPLIT_DEICE = 24, - OP_INVETER_CHECK = 25, - OP_NONSTOP_DEICE = 26, - OP_REM_TEST = 27, - OP_RATING = 28, - OP_PC_TEST = 29, - OP_PUMPDOWN_THERMOOFF = 30, - OP_3PHASE_TEST = 31, - OP_SMARTINSTALL_TEST = 32, - OP_DEICE_PERFORMANCE_TEST = 33, - OP_INVERTER_FAN_PBA_CHECK = 34, - OP_AUTO_PIPE_PAIRING = 35, - OP_AUTO_CHARGE = 36, - OP_UNKNOWN = -1 - }; - - class MessageTarget + class MessageTarget { public: virtual uint32_t get_miliseconds() = 0; @@ -137,8 +95,6 @@ namespace esphome virtual optional> get_custom_sensors(const std::string address) = 0; virtual void set_custom_sensor(const std::string address, uint16_t message_number, float value) = 0; virtual void set_error_code(const std::string address, int error_code) = 0; - virtual void set_outdoor_operation_mode(const std::string &address, OutdoorOperationMode outdooroperationmode) = 0; - }; struct ProtocolRequest @@ -196,86 +152,3 @@ namespace esphome } // namespace samsung_ac } // namespace esphome - -inline std::string outdoor_operation_mode_to_string(OutdoorOperationMode mode) -{ - switch (mode) - { - case OutdoorOperationMode::OP_STOP: - return "OP_STOP: Outdoor unit is stopped."; - case OutdoorOperationMode::OP_SAFETY: - return "OP_SAFETY: Operating in safety mode."; - case OutdoorOperationMode::OP_NORMAL: - return "OP_NORMAL: Normal operation mode."; - case OutdoorOperationMode::OP_BALANCE: - return "OP_BALANCE: Balancing mode."; - case OutdoorOperationMode::OP_RECOVERY: - return "OP_RECOVERY: Recovery mode."; - case OutdoorOperationMode::OP_DEICE: - return "OP_DEICE: Defrost mode."; - case OutdoorOperationMode::OP_COMPDOWN: - return "OP_COMPDOWN: Compressor down mode."; - case OutdoorOperationMode::OP_PROHIBIT: - return "OP_PROHIBIT: Prohibited state."; - case OutdoorOperationMode::OP_LINEJIG: - return "OP_LINEJIG: Line jig mode."; - case OutdoorOperationMode::OP_PCBJIG: - return "OP_PCBJIG: PCB jig mode."; - case OutdoorOperationMode::OP_TEST: - return "OP_TEST: Test mode."; - case OutdoorOperationMode::OP_CHARGE: - return "OP_CHARGE: Charge mode."; - case OutdoorOperationMode::OP_PUMPDOWN: - return "OP_PUMPDOWN: Pump down mode."; - case OutdoorOperationMode::OP_PUMPOUT: - return "OP_PUMPOUT: Pump out mode."; - case OutdoorOperationMode::OP_VACCUM: - return "OP_VACCUM: Vacuum mode."; - case OutdoorOperationMode::OP_CALORYJIG: - return "OP_CALORYJIG: Calory jig mode."; - case OutdoorOperationMode::OP_PUMPDOWNSTOP: - return "OP_PUMPDOWNSTOP: Pump down stop mode."; - case OutdoorOperationMode::OP_SUBSTOP: - return "OP_SUBSTOP: Sub stop mode."; - case OutdoorOperationMode::OP_CHECKPIPE: - return "OP_CHECKPIPE: Pipe check mode."; - case OutdoorOperationMode::OP_CHECKREF: - return "OP_CHECKREF: Refrigerant check mode."; - case OutdoorOperationMode::OP_FPTJIG: - return "OP_FPTJIG: FPT jig mode."; - case OutdoorOperationMode::OP_NONSTOP_HEAT_COOL_CHANGE: - return "OP_NONSTOP_HEAT_COOL_CHANGE: Non-stop heat/cool change mode."; - case OutdoorOperationMode::OP_AUTO_INSPECT: - return "OP_AUTO_INSPECT: Auto inspection mode."; - case OutdoorOperationMode::OP_ELECTRIC_DISCHARGE: - return "OP_ELECTRIC_DISCHARGE: Electric discharge mode."; - case OutdoorOperationMode::OP_SPLIT_DEICE: - return "OP_SPLIT_DEICE: Split defrost mode."; - case OutdoorOperationMode::OP_INVETER_CHECK: - return "OP_INVETER_CHECK: Inverter check mode."; - case OutdoorOperationMode::OP_NONSTOP_DEICE: - return "OP_NONSTOP_DEICE: Non-stop defrost mode."; - case OutdoorOperationMode::OP_REM_TEST: - return "OP_REM_TEST: Remote test mode."; - case OutdoorOperationMode::OP_RATING: - return "OP_RATING: Rating mode."; - case OutdoorOperationMode::OP_PC_TEST: - return "OP_PC_TEST: PC test mode."; - case OutdoorOperationMode::OP_PUMPDOWN_THERMOOFF: - return "OP_PUMPDOWN_THERMOOFF: Thermo-off pump down mode."; - case OutdoorOperationMode::OP_3PHASE_TEST: - return "OP_3PHASE_TEST: Three-phase test mode."; - case OutdoorOperationMode::OP_SMARTINSTALL_TEST: - return "OP_SMARTINSTALL_TEST: Smart install test mode."; - case OutdoorOperationMode::OP_DEICE_PERFORMANCE_TEST: - return "OP_DEICE_PERFORMANCE_TEST: Defrost performance test mode."; - case OutdoorOperationMode::OP_INVERTER_FAN_PBA_CHECK: - return "OP_INVERTER_FAN_PBA_CHECK: Inverter fan PBA check mode."; - case OutdoorOperationMode::OP_AUTO_PIPE_PAIRING: - return "OP_AUTO_PIPE_PAIRING: Auto pipe pairing mode."; - case OutdoorOperationMode::OP_AUTO_CHARGE: - return "OP_AUTO_CHARGE: Automatic charge mode."; - default: - return "OP_UNKNOWN: Unknown operation mode."; - } -} diff --git a/components/samsung_ac/protocol_nasa.cpp b/components/samsung_ac/protocol_nasa.cpp index 6b644716..332a9bfd 100644 --- a/components/samsung_ac/protocol_nasa.cpp +++ b/components/samsung_ac/protocol_nasa.cpp @@ -722,16 +722,6 @@ namespace esphome target->set_error_code(source, code); break; } - case MessageNumber::ENUM_outdoor_operation_mode: - { - int code = static_cast(message.value); - if (debug_log_messages) - { - ESP_LOGW(TAG, "s:%s d:%s ENUM_outdoor_operation_mode %d", source.c_str(), dest.c_str(), code); - } - target->set_outdoor_operation_mode(source, code); - break; - } default: { @@ -908,18 +898,6 @@ namespace esphome LOG_MESSAGE(ENUM_in_fan_vent_mode, message.value, source, dest); // fan_vent_mode_to_fanmode(); break; - case 0x4205: // VAR_in_temp_eva_in_f unit = 'Celsius' - { - double temp = (double)message.value / (double)10; - LOG_MESSAGE(VAR_in_temp_eva_in_f, temp, source, dest); - break; - } - case 0x4206: // VAR_in_temp_eva_out_f unit = 'Celsius' - { - double temp = (double)message.value / (double)10; - LOG_MESSAGE(VAR_in_temp_eva_out_f, temp, source, dest); - break; - } case 0x4211: // VAR_in_capacity_request unit = 'kW' { double temp = (double)message.value / (double)8.6; diff --git a/components/samsung_ac/protocol_nasa.h b/components/samsung_ac/protocol_nasa.h index af811d9c..b987e24b 100644 --- a/components/samsung_ac/protocol_nasa.h +++ b/components/samsung_ac/protocol_nasa.h @@ -81,7 +81,6 @@ namespace esphome ENUM_in_louver_hl_swing = 0x4011, ENUM_in_louver_lr_swing = 0x407e, ENUM_in_state_humidity_percent = 0x4038, - ENUM_outdoor_operation_mode = 0x8001, VAR_in_temp_room_f = 0x4203, VAR_in_temp_target_f = 0x4201, VAR_in_temp_water_outlet_target_f = 0x4247, diff --git a/components/samsung_ac/samsung_ac_device.h b/components/samsung_ac/samsung_ac_device.h index 18ec32dd..e80c8e93 100644 --- a/components/samsung_ac/samsung_ac_device.h +++ b/components/samsung_ac/samsung_ac_device.h @@ -108,7 +108,6 @@ namespace esphome sensor::Sensor *indoor_eva_in_temperature{nullptr}; sensor::Sensor *indoor_eva_out_temperature{nullptr}; sensor::Sensor *error_code{nullptr}; - sensor::Sensor *outdoor_operation_mode{nullptr}; Samsung_AC_Number *target_temperature{nullptr}; Samsung_AC_Number *water_outlet_target{nullptr}; Samsung_AC_Number *target_water_temperature{nullptr}; @@ -146,11 +145,6 @@ namespace esphome error_code = sensor; } - void set_outdoor_operation_mode_sensor(sensor::Sensor *sensor) - { - outdoor_operation_mode = sensor; - } - void add_custom_sensor(int message_number, sensor::Sensor *sensor) { Samsung_AC_Sensor cust_sensor; @@ -433,12 +427,6 @@ namespace esphome error_code->publish_state(value); } - void update_outdoor_operation_mode(int value) - { - if (outdoor_operation_mode != nullptr) - outdoor_operation_mode->publish_state(value); - } - void update_custom_sensor(uint16_t message_number, float value) { for (auto &sensor : custom_sensors) From d33db7b429f548d17b8845b99fe9be5e23f6dd34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Mon, 26 Aug 2024 22:57:17 +0300 Subject: [PATCH 13/44] outdoor_operation_mode delete :). --- components/samsung_ac/samsung_ac.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/components/samsung_ac/samsung_ac.h b/components/samsung_ac/samsung_ac.h index 7af186ca..4bbaff76 100644 --- a/components/samsung_ac/samsung_ac.h +++ b/components/samsung_ac/samsung_ac.h @@ -201,13 +201,6 @@ namespace esphome dev->update_error_code(value); } - void /*MessageTarget::*/ set_outdoor_operation_mode(const std::string address, int value) override - { - Samsung_AC_Device *dev = find_device(address); - if (dev != nullptr) - dev->update_outdoor_operation_mode(value); - } - protected: Samsung_AC_Device *find_device(const std::string address) { From 73a2ea8f446e37a7f08d9b102dcb93239c497da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 00:00:46 +0300 Subject: [PATCH 14/44] Optimize to_code function and remove unnecessary code --- components/samsung_ac/__init__.py | 111 ++++++++++++------------------ 1 file changed, 45 insertions(+), 66 deletions(-) diff --git a/components/samsung_ac/__init__.py b/components/samsung_ac/__init__.py index b035f83d..fef77d9e 100644 --- a/components/samsung_ac/__init__.py +++ b/components/samsung_ac/__init__.py @@ -280,41 +280,28 @@ async def to_code(config): device[CONF_DEVICE_ID], device[CONF_DEVICE_ADDRESS], var) # setup capabilities - if CONF_CAPABILITIES in device and CONF_CAPABILITIES_VERTICAL_SWING in device[CONF_CAPABILITIES]: - cg.add(var_dev.set_supports_vertical_swing( - device[CONF_CAPABILITIES][CONF_CAPABILITIES_VERTICAL_SWING])) - elif CONF_CAPABILITIES in config and CONF_CAPABILITIES_VERTICAL_SWING in config[CONF_CAPABILITIES]: - cg.add(var_dev.set_supports_vertical_swing( - config[CONF_CAPABILITIES][CONF_CAPABILITIES_VERTICAL_SWING])) - - if CONF_CAPABILITIES in device and CONF_CAPABILITIES_HORIZONTAL_SWING in device[CONF_CAPABILITIES]: - cg.add(var_dev.set_supports_horizontal_swing( - device[CONF_CAPABILITIES][CONF_CAPABILITIES_HORIZONTAL_SWING])) - elif CONF_CAPABILITIES in config and CONF_CAPABILITIES_HORIZONTAL_SWING in config[CONF_CAPABILITIES]: - cg.add(var_dev.set_supports_horizontal_swing( - config[CONF_CAPABILITIES][CONF_CAPABILITIES_HORIZONTAL_SWING])) + capabilities = device.get(CONF_CAPABILITIES, config.get(CONF_CAPABILITIES, {})) + + if capabilities.get(CONF_CAPABILITIES_VERTICAL_SWING): + cg.add(var_dev.set_supports_vertical_swing(True)) + + if capabilities.get(CONF_CAPABILITIES_HORIZONTAL_SWING): + cg.add(var_dev.set_supports_horizontal_swing(True)) none_added = False - for preset in PRESETS: - device_preset_conf = device[CONF_CAPABILITIES][CONF_PRESETS][preset] if ( - CONF_CAPABILITIES in device - and CONF_PRESETS in device[CONF_CAPABILITIES] - and preset in device[CONF_CAPABILITIES][CONF_PRESETS]) else None - global_preset_conf = config[CONF_CAPABILITIES][CONF_PRESETS][preset] if ( - CONF_CAPABILITIES in config - and CONF_PRESETS in config[CONF_CAPABILITIES] - and preset in config[CONF_CAPABILITIES][CONF_PRESETS]) else None - - preset_conf = global_preset_conf if device_preset_conf is None else device_preset_conf + presets = capabilities.get(CONF_PRESETS, {}) + + for preset, preset_info in PRESETS.items(): + preset_conf = presets.get(preset, None) preset_dict = isinstance(preset_conf, dict) - if preset_conf == True or (preset_dict and preset_conf[CONF_PRESET_ENABLED] == True): + if preset_conf == True or (preset_dict and preset_conf.get(CONF_PRESET_ENABLED, False)): if not none_added: none_added = True cg.add(var_dev.add_alt_mode("None", 0)) cg.add(var_dev.add_alt_mode( - preset_conf[CONF_PRESET_NAME] if preset_dict and CONF_PRESET_NAME in preset_conf else PRESETS[preset]["displayName"], - preset_conf[CONF_PRESET_VALUE] if preset_dict and CONF_PRESET_VALUE in preset_conf else PRESETS[preset]["value"] + preset_conf.get(CONF_PRESET_NAME, preset_info["displayName"]), + preset_conf.get(CONF_PRESET_VALUE, preset_info["value"]) )) # if CONF_CAPABILITIES in device and CONF_ALT_MODES in device[CONF_CAPABILITIES]: @@ -326,49 +313,28 @@ async def to_code(config): # for alt in config[CONF_CAPABILITIES][CONF_ALT_MODES]: # cg.add(var_dev.add_alt_mode(alt[CONF_ALT_MODE_NAME], alt[CONF_ALT_MODE_VALUE])) - if CONF_DEVICE_POWER in device: - conf = device[CONF_DEVICE_POWER] - sens = await switch.new_switch(conf) - cg.add(var_dev.set_power_switch(sens)) - - if CONF_DEVICE_AUTOMATIC_CLEANING in device: - conf = device[CONF_DEVICE_AUTOMATIC_CLEANING] - sens = await switch.new_switch(conf) - cg.add(var_dev.set_automatic_cleaning_switch(sens)) - - if CONF_DEVICE_WATER_HEATER_POWER in device: - conf = device[CONF_DEVICE_WATER_HEATER_POWER] - sens = await switch.new_switch(conf) - cg.add(var_dev.set_water_heater_power_switch(sens)) + # Mapping of config keys to their corresponding methods and types + device_actions = { + CONF_DEVICE_POWER: (switch.new_switch, var_dev.set_power_switch), + CONF_DEVICE_AUTOMATIC_CLEANING: (switch.new_switch, var_dev.set_automatic_cleaning_switch), + CONF_DEVICE_WATER_HEATER_POWER: (switch.new_switch, var_dev.set_water_heater_power_switch), + CONF_DEVICE_ROOM_TEMPERATURE: (sensor.new_sensor, var_dev.set_room_temperature_sensor), + CONF_DEVICE_OUTDOOR_TEMPERATURE: (sensor.new_sensor, var_dev.set_outdoor_temperature_sensor), + CONF_DEVICE_INDOOR_EVA_IN_TEMPERATURE: (sensor.new_sensor, var_dev.set_indoor_eva_in_temperature_sensor), + CONF_DEVICE_INDOOR_EVA_OUT_TEMPERATURE: (sensor.new_sensor, var_dev.set_indoor_eva_out_temperature_sensor), + CONF_DEVICE_ERROR_CODE: (sensor.new_sensor, var_dev.set_error_code_sensor), + } - if CONF_DEVICE_ROOM_TEMPERATURE in device: - conf = device[CONF_DEVICE_ROOM_TEMPERATURE] - sens = await sensor.new_sensor(conf) - cg.add(var_dev.set_room_temperature_sensor(sens)) + # Iterate over the actions + for key, (action, method) in device_actions.items(): + if key in device: + conf = device[key] + sens = await action(conf) + cg.add(method(sens)) if CONF_DEVICE_ROOM_TEMPERATURE_OFFSET in device: cg.add(var_dev.set_room_temperature_offset( device[CONF_DEVICE_ROOM_TEMPERATURE_OFFSET])) - - if CONF_DEVICE_OUTDOOR_TEMPERATURE in device: - conf = device[CONF_DEVICE_OUTDOOR_TEMPERATURE] - sens = await sensor.new_sensor(conf) - cg.add(var_dev.set_outdoor_temperature_sensor(sens)) - - if CONF_DEVICE_INDOOR_EVA_IN_TEMPERATURE in device: - conf = device[CONF_DEVICE_INDOOR_EVA_IN_TEMPERATURE] - sens = await sensor.new_sensor(conf) - cg.add(var_dev.set_indoor_eva_in_temperature_sensor(sens)) - - if CONF_DEVICE_INDOOR_EVA_OUT_TEMPERATURE in device: - conf = device[CONF_DEVICE_INDOOR_EVA_OUT_TEMPERATURE] - sens = await sensor.new_sensor(conf) - cg.add(var_dev.set_indoor_eva_out_temperature_sensor(sens)) - - if CONF_DEVICE_ERROR_CODE in device: - conf = device[CONF_DEVICE_ERROR_CODE] - sens = await sensor.new_sensor(conf) - cg.add(var_dev.set_error_code_sensor(sens)) if CONF_DEVICE_WATER_TARGET_TEMPERATURE in device: conf = device[CONF_DEVICE_WATER_TARGET_TEMPERATURE] @@ -452,6 +418,19 @@ async def to_code(config): if (CONF_DEBUG_LOG_UNDEFINED_MESSAGES in config): cg.add(var.set_debug_log_undefined_messages(config[CONF_DEBUG_LOG_UNDEFINED_MESSAGES])) - + + # Mapping of config keys to their corresponding methods + config_actions = { + CONF_DEBUG_LOG_MESSAGES: var.set_debug_log_messages, + CONF_DEBUG_LOG_MESSAGES_RAW: var.set_debug_log_messages_raw, + CONF_NON_NASA_KEEPALIVE: var.set_non_nasa_keepalive, + CONF_DEBUG_LOG_UNDEFINED_MESSAGES: var.set_debug_log_undefined_messages, + } + + # Iterate over the actions + for key, method in config_actions.items(): + if key in config: + cg.add(method(config[key])) + await cg.register_component(var, config) await uart.register_uart_device(var, config) From 49accb61bdce54b14bccaea19967c0535bb65de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 00:23:45 +0300 Subject: [PATCH 15/44] Optimize conversions.cpp and reduce redundant code --- components/samsung_ac/conversions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/samsung_ac/conversions.cpp b/components/samsung_ac/conversions.cpp index 73e0aa42..fd99ef38 100644 --- a/components/samsung_ac/conversions.cpp +++ b/components/samsung_ac/conversions.cpp @@ -34,7 +34,7 @@ namespace esphome case Mode::Heat: return "Heat"; default: - return ""; + return "Unknown"; }; } @@ -64,7 +64,7 @@ namespace esphome case WaterHeaterMode::Force: return "Force"; default: - return ""; + return "Unknown"; }; } From 1b251cc9d316e574d343d3bec5d42c84faf3b521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 00:27:15 +0300 Subject: [PATCH 16/44] Optimize debug_mqtt.cpp and remove redundant code --- components/samsung_ac/debug_mqtt.cpp | 34 ++++++++++------------------ components/samsung_ac/debug_mqtt.h | 3 ++- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/components/samsung_ac/debug_mqtt.cpp b/components/samsung_ac/debug_mqtt.cpp index 0ea0bd2d..d4826feb 100644 --- a/components/samsung_ac/debug_mqtt.cpp +++ b/components/samsung_ac/debug_mqtt.cpp @@ -1,11 +1,10 @@ #include "esphome/core/log.h" #include "debug_mqtt.h" -#ifdef USE_ESP8266 +#if defined(USE_ESP8266) #include AsyncMqttClient *mqtt_client{nullptr}; -#endif -#ifdef USE_ESP32 +#elif defined(USE_ESP32) #include esp_mqtt_client_handle_t mqtt_client{nullptr}; #endif @@ -16,44 +15,40 @@ namespace esphome { bool debug_mqtt_connected() { -#ifdef USE_ESP8266 if (mqtt_client == nullptr) return false; +#if defined(USE_ESP8266) return mqtt_client->connected(); -#elif USE_ESP32 - if (mqtt_client == nullptr) - return false; - +#elif defined(USE_ESP32) return true; -#else - return false; #endif } void debug_mqtt_connect(const std::string &host, const uint16_t port, const std::string &username, const std::string &password) { - if (host.length() == 0) + if (host.empty()) return; -#ifdef USE_ESP8266 +#if defined(USE_ESP8266) if (mqtt_client == nullptr) { mqtt_client = new AsyncMqttClient(); mqtt_client->setServer(host.c_str(), port); - if (username.length() > 0) + if (!username.empty()) mqtt_client->setCredentials(username.c_str(), password.c_str()); } if (!mqtt_client->connected()) mqtt_client->connect(); -#elif USE_ESP32 + +#elif defined(USE_ESP32) if (mqtt_client == nullptr) { esp_mqtt_client_config_t mqtt_cfg = {}; mqtt_cfg.host = host.c_str(); mqtt_cfg.port = port; - if (username.length() > 0) + if (!username.empty()) { mqtt_cfg.username = username.c_str(); mqtt_cfg.password = password.c_str(); @@ -66,18 +61,13 @@ namespace esphome bool debug_mqtt_publish(const std::string &topic, const std::string &payload) { -#ifdef USE_ESP8266 if (mqtt_client == nullptr) return false; +#if defined(USE_ESP8266) return mqtt_client->publish(topic.c_str(), 0, false, payload.c_str()) != 0; -#elif USE_ESP32 - if (mqtt_client == nullptr) - return false; - +#elif defined(USE_ESP32) return esp_mqtt_client_publish(mqtt_client, topic.c_str(), payload.c_str(), payload.length(), 0, false) != -1; -#else - return true; #endif } } // namespace samsung_ac diff --git a/components/samsung_ac/debug_mqtt.h b/components/samsung_ac/debug_mqtt.h index 25d9b692..56fa6a0e 100644 --- a/components/samsung_ac/debug_mqtt.h +++ b/components/samsung_ac/debug_mqtt.h @@ -1,5 +1,6 @@ #pragma once -#include + +#include namespace esphome { From b4a080957ad0969a3dc163809f8e2b170dbe8fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 00:30:07 +0300 Subject: [PATCH 17/44] Optimize protocol_nasa.cpp and protocol_nasa.h by removing unused includes and redundant code --- components/samsung_ac/protocol_nasa.cpp | 7 ++----- components/samsung_ac/protocol_nasa.h | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/components/samsung_ac/protocol_nasa.cpp b/components/samsung_ac/protocol_nasa.cpp index 332a9bfd..6baa9198 100644 --- a/components/samsung_ac/protocol_nasa.cpp +++ b/components/samsung_ac/protocol_nasa.cpp @@ -1,9 +1,6 @@ -#include -#include #include #include "esphome/core/log.h" #include "esphome/core/util.h" -#include "esphome/core/hal.h" #include "util.h" #include "protocol_nasa.h" #include "debug_mqtt.h" @@ -82,8 +79,8 @@ namespace esphome std::string Address::to_string() { char str[9]; - sprintf(str, "%02x.%02x.%02x", (int)klass, channel, address); - return str; + sprintf(str, "%02x.%02x.%02x", klass, channel, address); + return std::string(str); } void Command::decode(std::vector &data, unsigned int index) diff --git a/components/samsung_ac/protocol_nasa.h b/components/samsung_ac/protocol_nasa.h index b987e24b..499d4075 100644 --- a/components/samsung_ac/protocol_nasa.h +++ b/components/samsung_ac/protocol_nasa.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include "protocol.h" namespace esphome From a2ed350f67d16747b63fcc88e2ad717ecd3012ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 00:35:51 +0300 Subject: [PATCH 18/44] Optimize protocol_non_nasa.cpp and protocol_non_nasa.h by removing unused includes and redundant code --- components/samsung_ac/protocol_non_nasa.cpp | 2 +- components/samsung_ac/protocol_non_nasa.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/components/samsung_ac/protocol_non_nasa.cpp b/components/samsung_ac/protocol_non_nasa.cpp index 2e9bdc13..1d503b78 100644 --- a/components/samsung_ac/protocol_non_nasa.cpp +++ b/components/samsung_ac/protocol_non_nasa.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "esphome/core/log.h" #include "esphome/core/hal.h" #include "util.h" diff --git a/components/samsung_ac/protocol_non_nasa.h b/components/samsung_ac/protocol_non_nasa.h index 21c6f825..3542c47c 100644 --- a/components/samsung_ac/protocol_non_nasa.h +++ b/components/samsung_ac/protocol_non_nasa.h @@ -2,7 +2,6 @@ #include #include -#include #include #include "protocol.h" #include "util.h" From 564e3febddc41d7c958fbba571fd81364707aaf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 00:39:12 +0300 Subject: [PATCH 19/44] Optimize samsung_ac, protocol, and device code for better performance and readability --- components/samsung_ac/samsung_ac.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/samsung_ac/samsung_ac.h b/components/samsung_ac/samsung_ac.h index 4bbaff76..985abd24 100644 --- a/components/samsung_ac/samsung_ac.h +++ b/components/samsung_ac/samsung_ac.h @@ -216,8 +216,8 @@ namespace esphome std::set addresses_; std::vector data_; - uint32_t last_transmission_{0}; - uint32_t last_protocol_update_{0}; + uint32_t last_transmission_ = 0; + uint32_t last_protocol_update_ = 0; bool data_processing_init = true; From c19dea02dec14afe926353c21f73c7e57603b7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 00:42:38 +0300 Subject: [PATCH 20/44] Optimized util.cpp and util.h functions for better performance and security. --- components/samsung_ac/samsung_ac.cpp | 58 +++++++++------------ components/samsung_ac/samsung_ac_device.cpp | 22 ++++---- components/samsung_ac/util.cpp | 17 +++--- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 764b91b0..25dadd0b 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -98,31 +98,25 @@ namespace esphome data_processing_init = false; } - std::string devices = ""; + std::string devices; for (const auto &pair : devices_) { - devices += devices.length() > 0 ? ", " + pair.second->address : pair.second->address; + if (!devices.empty()) + devices += ", "; + devices += pair.second->address; } ESP_LOGCONFIG(TAG, "Configured devices: %s", devices.c_str()); - std::string knownIndoor = ""; - std::string knownOutdoor = ""; - std::string knownOther = ""; - for (auto const &address : addresses_) + std::string knownIndoor, knownOutdoor, knownOther; + for (const auto &address : addresses_) { - switch (get_address_type(address)) - { - case AddressType::Outdoor: - knownOutdoor += knownOutdoor.length() > 0 ? ", " + address : address; - break; - case AddressType::Indoor: - knownIndoor += knownIndoor.length() > 0 ? ", " + address : address; - break; - default: - knownOther += knownOther.length() > 0 ? ", " + address : address; - break; - } + auto &target = (get_address_type(address) == AddressType::Outdoor) ? knownOutdoor : (get_address_type(address) == AddressType::Indoor) ? knownIndoor + : knownOther; + if (!target.empty()) + target += ", "; + target += address; } + ESP_LOGCONFIG(TAG, "Discovered devices:"); ESP_LOGCONFIG(TAG, " Outdoor: %s", (knownOutdoor.length() == 0 ? "-" : knownOutdoor.c_str())); ESP_LOGCONFIG(TAG, " Indoor: %s", (knownIndoor.length() == 0 ? "-" : knownIndoor.c_str())); @@ -160,31 +154,27 @@ namespace esphome return; const uint32_t now = millis(); - if (data_.size() > 0 && (now - last_transmission_ >= 500)) + if (!data_.empty() && (now - last_transmission_ >= 500)) { ESP_LOGW(TAG, "Last transmission too long ago. Reset RX index."); data_.clear(); } - // If there is no data we use the time to send - if (available()) + while (available()) { last_transmission_ = now; - while (available()) - { - uint8_t c; - if (!read_byte(&c)) - continue; - if (data_.size() == 0 && c != 0x32) - continue; // skip until start-byte found + uint8_t c; + if (!read_byte(&c)) + continue; + if (data_.empty() && c != 0x32) + continue; // skip until start-byte found - data_.push_back(c); + data_.push_back(c); - if (process_data(data_, this) == DataResult::Clear) - { - data_.clear(); - break; // wait for next loop - } + if (process_data(data_, this) == DataResult::Clear) + { + data_.clear(); + break; // wait for next loop } } diff --git a/components/samsung_ac/samsung_ac_device.cpp b/components/samsung_ac/samsung_ac_device.cpp index 56c14f31..99b713f4 100644 --- a/components/samsung_ac/samsung_ac_device.cpp +++ b/components/samsung_ac/samsung_ac_device.cpp @@ -20,19 +20,19 @@ namespace esphome traits.set_visual_min_temperature(16); traits.set_visual_max_temperature(30); - std::set modes; - modes.insert(climate::CLIMATE_MODE_OFF); - modes.insert(climate::CLIMATE_MODE_AUTO); - modes.insert(climate::CLIMATE_MODE_COOL); - modes.insert(climate::CLIMATE_MODE_DRY); - modes.insert(climate::CLIMATE_MODE_FAN_ONLY); - modes.insert(climate::CLIMATE_MODE_HEAT); + const std::set modes = { + climate::CLIMATE_MODE_OFF, + climate::CLIMATE_MODE_AUTO, + climate::CLIMATE_MODE_COOL, + climate::CLIMATE_MODE_DRY, + climate::CLIMATE_MODE_FAN_ONLY, + climate::CLIMATE_MODE_HEAT}; traits.set_supported_modes(modes); - std::set fan; - fan.insert(climate::ClimateFanMode::CLIMATE_FAN_HIGH); - fan.insert(climate::ClimateFanMode::CLIMATE_FAN_MIDDLE); - fan.insert(climate::ClimateFanMode::CLIMATE_FAN_LOW); + std::set fan = { + climate::ClimateFanMode::CLIMATE_FAN_HIGH, + climate::ClimateFanMode::CLIMATE_FAN_MIDDLE, + climate::ClimateFanMode::CLIMATE_FAN_LOW}; if (this->mode != climate::CLIMATE_MODE_FAN_ONLY) { diff --git a/components/samsung_ac/util.cpp b/components/samsung_ac/util.cpp index acaa7ad5..fa72f8f7 100644 --- a/components/samsung_ac/util.cpp +++ b/components/samsung_ac/util.cpp @@ -7,8 +7,8 @@ namespace esphome std::string long_to_hex(long number) { char str[10]; - sprintf(str, "%02lx", number); - return str; + snprintf(str, sizeof(str), "%02lx", number); // Use of snprintf for security reasons. + return std::string(str); } int hex_to_int(const std::string &hex) @@ -19,9 +19,12 @@ namespace esphome std::string bytes_to_hex(const std::vector &data) { std::string str; - for (int i = 0; i < data.size(); i++) + str.reserve(data.size() * 2); // Memory reservations are made to increase efficiency. + for (uint8_t byte : data) { - str += long_to_hex(data[i]); + char buf[3]; + snprintf(buf, sizeof(buf), "%02x", byte); + str += buf; } return str; } @@ -29,9 +32,11 @@ namespace esphome std::vector hex_to_bytes(const std::string &hex) { std::vector bytes; - for (unsigned int i = 0; i < hex.length(); i += 2) + bytes.reserve(hex.length() / 2); + for (size_t i = 0; i < hex.length(); i += 2) { - bytes.push_back((uint8_t)strtol(hex.substr(i, 2).c_str(), NULL, 16)); + uint8_t byte = (uint8_t)strtol(hex.substr(i, 2).c_str(), nullptr, 16); + bytes.push_back(byte); } return bytes; } From c76740219577f4ad67fcfd449f5a405781a4363a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Wed, 28 Aug 2024 01:07:45 +0300 Subject: [PATCH 21/44] Add Blueprint feature for Samsung AC error code monitoring and notifications --- readme.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/readme.md b/readme.md index dcf39859..72aebddc 100644 --- a/readme.md +++ b/readme.md @@ -20,6 +20,21 @@ The current implementation offers the following features: - **AC Mode Control:** The controller enables you to change the AC mode, giving you control over cooling, heating, or other operational modes. +## New Feature: ESPHome Samsung AC Blueprint + +We are excited to introduce a new Blueprint that integrates with the esphome_samsung_ac component. This Blueprint enhances your Home Assistant setup by enabling you to monitor error codes from your Samsung AC units and receive real-time notifications directly to your selected devices. + +### Key Features: +- **Error Code Monitoring:** Continuously monitors error codes from your Samsung AC unit, ensuring that you are always informed about any issues. +- **Automated Notifications:** Sends detailed notifications with corresponding error messages to selected devices whenever an error code is detected. +- **User-Friendly Setup:** Easily import and configure this Blueprint through Home Assistant’s Blueprint feature. + +For more detailed instructions on setup and usage, please refer to the [Blueprint documentation](https://github.com/omerfaruk-aran/esphome_samsung_ac_blueprint). + +This Blueprint adds a new layer of functionality to your Home Assistant setup, allowing for more proactive and informed management of your Samsung AC units. + +[![Add Blueprint to Home Assistant](https://community-assets.home-assistant.io/original/4X/d/7/6/d7625545838a4970873f3a996172212440b7e0ae.svg)](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https://raw.githubusercontent.com/omerfaruk-aran/esphome_samsung_ac_blueprint/main/blueprints/automation/esphome_samsung_ac/notification_blueprint.yaml) + ## Compatibility In general, all devices with dedicated communication wires (not only power) should work. If you want to be safe when buying a new AC, then just ask for NASA support. From 626fffdfba0706a92f7bcf810da221c47fa2c180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 15:09:29 +0300 Subject: [PATCH 22/44] Fix MessageTarget --- components/samsung_ac/protocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/samsung_ac/protocol.h b/components/samsung_ac/protocol.h index 2fc515c6..b7e0bfc4 100644 --- a/components/samsung_ac/protocol.h +++ b/components/samsung_ac/protocol.h @@ -70,7 +70,7 @@ namespace esphome All = 3 }; - class MessageTarget + class MessageTarget { public: virtual uint32_t get_miliseconds() = 0; From 325ac493be727614714b8da3f41a6ed7c42c970d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 15:16:19 +0300 Subject: [PATCH 23/44] Fix mode_to_string to mode_to_str conversions.cpp --- components/samsung_ac/samsung_ac.cpp | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index 25dadd0b..aec1ed24 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -19,25 +19,6 @@ namespace esphome std::map last_update_time; std::map pending_changes; const unsigned long TIMEOUT_PERIOD = 1000; - std::string mode_to_string(Mode mode) - { - switch (mode) - { - case Mode::Auto: - return "Auto"; - case Mode::Cool: - return "Cool"; - case Mode::Dry: - return "Dry"; - case Mode::Fan: - return "Fan"; - case Mode::Heat: - return "Heat"; - case Mode::Unknown: - default: - return "Unknown"; - } - } void Samsung_AC::update() { @@ -65,10 +46,10 @@ namespace esphome } } - if (current_value.has_value() && last_values[address] != mode_to_string(current_value.value())) + if (current_value.has_value() && last_values[address] != mode_to_str(current_value.value())) { pending_changes[address] = current_value.value(); - last_values[address] = mode_to_string(current_value.value()); + last_values[address] = mode_to_str(current_value.value()); last_update_time[address] = now; ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); From 3b57f06ad13fc28d6b7a64d152abcce979e836e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 15:55:27 +0300 Subject: [PATCH 24/44] Refactor: Implement DeviceStateTracker for State Management - Introduced DeviceStateTracker class to handle state changes and timeout management. - Refactored samsung_ac.h and samsung_ac.cpp to use DeviceStateTracker instead of manual state tracking. - Removed old state tracking variables and methods, replaced with DeviceStateTracker integration. --- components/samsung_ac/device_state_tracker.h | 51 ++++++++++++++++++++ components/samsung_ac/samsung_ac.cpp | 40 +-------------- components/samsung_ac/samsung_ac.h | 2 + 3 files changed, 55 insertions(+), 38 deletions(-) create mode 100644 components/samsung_ac/device_state_tracker.h diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h new file mode 100644 index 00000000..69ee4e17 --- /dev/null +++ b/components/samsung_ac/device_state_tracker.h @@ -0,0 +1,51 @@ +#ifndef DEVICE_STATE_TRACKER_H +#define DEVICE_STATE_TRACKER_H + +#include "esphome/core/log.h" +#include +#include + +template +class DeviceStateTracker { + public: + DeviceStateTracker(unsigned long timeout_period) + : TIMEOUT_PERIOD(timeout_period) {} + + void update(const std::string &address, const T ¤t_value) { + unsigned long now = millis(); + + if (pending_changes_.find(address) != pending_changes_.end()) { + if (current_value == pending_changes_[address]) { + pending_changes_.erase(address); + } else { + ESP_LOGI("DeviceStateTracker", "Stale value received for device: %s, ignoring.", address.c_str()); + return; + } + } + + if (last_values_.find(address) == last_values_.end() || last_values_[address] != current_value) { + pending_changes_[address] = current_value; + last_values_[address] = current_value; + last_update_time_[address] = now; + + ESP_LOGI("DeviceStateTracker", "Value changed for device: %s", address.c_str()); + } else { + ESP_LOGD("DeviceStateTracker", "No change in value for device: %s", address.c_str()); + + if (now - last_update_time_[address] > TIMEOUT_PERIOD) { + if (pending_changes_.find(address) != pending_changes_.end()) { + ESP_LOGW("DeviceStateTracker", "Timeout for device: %s, forcing update.", address.c_str()); + pending_changes_.erase(address); + } + } + } + } + + private: + std::map last_values_; + std::map last_update_time_; + std::map pending_changes_; + const unsigned long TIMEOUT_PERIOD; +}; + +#endif // DEVICE_STATE_TRACKER_H diff --git a/components/samsung_ac/samsung_ac.cpp b/components/samsung_ac/samsung_ac.cpp index aec1ed24..c7890db9 100644 --- a/components/samsung_ac/samsung_ac.cpp +++ b/components/samsung_ac/samsung_ac.cpp @@ -15,10 +15,6 @@ namespace esphome ESP_LOGW(TAG, "setup"); } } - std::map last_values; - std::map last_update_time; - std::map pending_changes; - const unsigned long TIMEOUT_PERIOD = 1000; void Samsung_AC::update() { @@ -31,42 +27,10 @@ namespace esphome { optional current_value = pair.second->_cur_mode; std::string address = pair.second->address; - unsigned long now = millis(); - if (pending_changes.find(address) != pending_changes.end()) + if (current_value.has_value()) { - if (current_value.has_value() && current_value.value() == pending_changes[address]) - { - pending_changes.erase(address); - } - else - { - ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); - continue; - } - } - - if (current_value.has_value() && last_values[address] != mode_to_str(current_value.value())) - { - pending_changes[address] = current_value.value(); - last_values[address] = mode_to_str(current_value.value()); - last_update_time[address] = now; - - ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); - } - else - { - ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); - - if (now - last_update_time[address] > TIMEOUT_PERIOD) - { - if (pending_changes.find(address) != pending_changes.end()) - { - ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); - pending_changes.erase(address); - } - } - continue; + state_tracker_.update(address, current_value.value()); } } diff --git a/components/samsung_ac/samsung_ac.h b/components/samsung_ac/samsung_ac.h index 985abd24..2919487e 100644 --- a/components/samsung_ac/samsung_ac.h +++ b/components/samsung_ac/samsung_ac.h @@ -8,6 +8,7 @@ #include "esphome/components/uart/uart.h" #include "samsung_ac_device.h" #include "protocol.h" +#include "device_state_tracker.h" namespace esphome { @@ -213,6 +214,7 @@ namespace esphome } std::map devices_; + DeviceStateTracker state_tracker_{1000}; std::set addresses_; std::vector data_; From f3bfdcdbf7cfffc5706db4d61d82b7a4591b1abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 15:58:32 +0300 Subject: [PATCH 25/44] Fix device_state_tracker.h --- components/samsung_ac/device_state_tracker.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index 69ee4e17..8b23a894 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - ESP_LOGI("DeviceStateTracker", "Stale value received for device: %s, ignoring.", address.c_str()); + this->ESP_LOGI("DeviceStateTracker", "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - ESP_LOGI("DeviceStateTracker", "Value changed for device: %s", address.c_str()); + this->ESP_LOGI("DeviceStateTracker", "Value changed for device: %s", address.c_str()); } else { ESP_LOGD("DeviceStateTracker", "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW("DeviceStateTracker", "Timeout for device: %s, forcing update.", address.c_str()); + this->ESP_LOGW("DeviceStateTracker", "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } From ad8dd7bf4cb332717236e04755e63fc883d69e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:02:50 +0300 Subject: [PATCH 26/44] Fix device_state_tracker.h --- components/samsung_ac/device_state_tracker.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index 8b23a894..69ee4e17 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - this->ESP_LOGI("DeviceStateTracker", "Stale value received for device: %s, ignoring.", address.c_str()); + ESP_LOGI("DeviceStateTracker", "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - this->ESP_LOGI("DeviceStateTracker", "Value changed for device: %s", address.c_str()); + ESP_LOGI("DeviceStateTracker", "Value changed for device: %s", address.c_str()); } else { ESP_LOGD("DeviceStateTracker", "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - this->ESP_LOGW("DeviceStateTracker", "Timeout for device: %s, forcing update.", address.c_str()); + ESP_LOGW("DeviceStateTracker", "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } From 6cce6841e15e66075f758daeb99ca1ef430e229f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:04:14 +0300 Subject: [PATCH 27/44] Fix device_state_tracker.h --- components/samsung_ac/device_state_tracker.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index 69ee4e17..fd19e635 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - ESP_LOGI("DeviceStateTracker", "Stale value received for device: %s, ignoring.", address.c_str()); + ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - ESP_LOGI("DeviceStateTracker", "Value changed for device: %s", address.c_str()); + ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); } else { - ESP_LOGD("DeviceStateTracker", "No change in value for device: %s", address.c_str()); + ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW("DeviceStateTracker", "Timeout for device: %s, forcing update.", address.c_str()); + ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } From 1f04375c6d402a7713e79677a621251efd509050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:07:12 +0300 Subject: [PATCH 28/44] Fix device_state_tracker.h --- components/samsung_ac/device_state_tracker.h | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index fd19e635..ac0a9c2f 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -5,6 +5,19 @@ #include #include +// Global log helper functions +inline void log_info(const char* tag, const char* format, const std::string &arg) { + ESP_LOGI(tag, format, arg.c_str()); +} + +inline void log_warn(const char* tag, const char* format, const std::string &arg) { + ESP_LOGW(tag, format, arg.c_str()); +} + +inline void log_debug(const char* tag, const char* format, const std::string &arg) { + ESP_LOGD(tag, format, arg.c_str()); +} + template class DeviceStateTracker { public: @@ -18,7 +31,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); + log_info("device_state_tracker", "Stale value received for device: %s, ignoring.", address); return; } } @@ -28,13 +41,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); + log_info("device_state_tracker", "Value changed for device: %s", address); } else { - ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); + log_debug("device_state_tracker", "No change in value for device: %s", address); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); + log_warn("device_state_tracker", "Timeout for device: %s, forcing update.", address); pending_changes_.erase(address); } } From 49840b432618a2232b9491d968f16a8c8d842588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:09:11 +0300 Subject: [PATCH 29/44] Fix device_state_tracker.h --- components/samsung_ac/device_state_tracker.h | 21 ++++---------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index ac0a9c2f..fd19e635 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -5,19 +5,6 @@ #include #include -// Global log helper functions -inline void log_info(const char* tag, const char* format, const std::string &arg) { - ESP_LOGI(tag, format, arg.c_str()); -} - -inline void log_warn(const char* tag, const char* format, const std::string &arg) { - ESP_LOGW(tag, format, arg.c_str()); -} - -inline void log_debug(const char* tag, const char* format, const std::string &arg) { - ESP_LOGD(tag, format, arg.c_str()); -} - template class DeviceStateTracker { public: @@ -31,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - log_info("device_state_tracker", "Stale value received for device: %s, ignoring.", address); + ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -41,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - log_info("device_state_tracker", "Value changed for device: %s", address); + ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); } else { - log_debug("device_state_tracker", "No change in value for device: %s", address); + ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - log_warn("device_state_tracker", "Timeout for device: %s, forcing update.", address); + ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } From a5cb293e5091b550608b2f967b8d21bf72c7a2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:11:37 +0300 Subject: [PATCH 30/44] Fix log.h ESP_LOGI rebuild --- test/esphome/core/log.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/esphome/core/log.h b/test/esphome/core/log.h index a4a04cee..2a4e890e 100644 --- a/test/esphome/core/log.h +++ b/test/esphome/core/log.h @@ -40,4 +40,13 @@ namespace esphome printf((str.c_str()), ##__VA_ARGS__); \ } while (0); +#define ESP_LOGI(tag, format, ...) \ + do \ + { \ + std::string str = ""; \ + str += format; \ + str += "\n"; \ + printf((str.c_str()), ##__VA_ARGS__); \ + } while (0); + } // namespace esphome From 0b3a5bedbbdfdee3e491c4ca3a0c8043d2e574b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:15:08 +0300 Subject: [PATCH 31/44] Fix log.h ESP_LOGI rebuild --- test/esphome/core/log.h | 48 ++++++++++++----------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/test/esphome/core/log.h b/test/esphome/core/log.h index 2a4e890e..0192269c 100644 --- a/test/esphome/core/log.h +++ b/test/esphome/core/log.h @@ -1,52 +1,32 @@ #pragma once -// Fake Log for Local Testing +#include +#include -namespace esphome -{ +namespace esphome { #define ESP_LOGD(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ + do { \ + printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ } while (0); #define ESP_LOGE(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ + do { \ + printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ } while (0); #define ESP_LOGW(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ + do { \ + printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ } while (0); #define ESP_LOGV(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ + do { \ + printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ } while (0); #define ESP_LOGI(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ + do { \ + printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ } while (0); - + } // namespace esphome From 5c27196e3c2f1b16c0945d00737487dcc00cb2bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:19:29 +0300 Subject: [PATCH 32/44] debug printf --- components/samsung_ac/device_state_tracker.h | 8 ++-- test/esphome/core/log.h | 48 ++++++++++++++------ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index fd19e635..02c4db55 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); + printf("Stale value received for device: %s, ignoring.\n", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); + printf("Value changed for device: %s\n", address.c_str()); } else { - ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); + printf("No change in value for device: %s\n", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); + printf("Timeout for device: %s, forcing update.\n", address.c_str()); pending_changes_.erase(address); } } diff --git a/test/esphome/core/log.h b/test/esphome/core/log.h index 0192269c..2a4e890e 100644 --- a/test/esphome/core/log.h +++ b/test/esphome/core/log.h @@ -1,32 +1,52 @@ #pragma once -#include -#include +// Fake Log for Local Testing -namespace esphome { +namespace esphome +{ #define ESP_LOGD(tag, format, ...) \ - do { \ - printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ + do \ + { \ + std::string str = ""; \ + str += format; \ + str += "\n"; \ + printf((str.c_str()), ##__VA_ARGS__); \ } while (0); #define ESP_LOGE(tag, format, ...) \ - do { \ - printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ + do \ + { \ + std::string str = ""; \ + str += format; \ + str += "\n"; \ + printf((str.c_str()), ##__VA_ARGS__); \ } while (0); #define ESP_LOGW(tag, format, ...) \ - do { \ - printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ + do \ + { \ + std::string str = ""; \ + str += format; \ + str += "\n"; \ + printf((str.c_str()), ##__VA_ARGS__); \ } while (0); #define ESP_LOGV(tag, format, ...) \ - do { \ - printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ + do \ + { \ + std::string str = ""; \ + str += format; \ + str += "\n"; \ + printf((str.c_str()), ##__VA_ARGS__); \ } while (0); #define ESP_LOGI(tag, format, ...) \ - do { \ - printf("[%s] " format "\n", tag, ##__VA_ARGS__); \ + do \ + { \ + std::string str = ""; \ + str += format; \ + str += "\n"; \ + printf((str.c_str()), ##__VA_ARGS__); \ } while (0); - + } // namespace esphome From 28f22b973a2d714c63280f80a91d585dcc8ffba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:23:50 +0300 Subject: [PATCH 33/44] debug printf --- components/samsung_ac/device_state_tracker.h | 8 ++++---- test/esphome/core/log.h | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index 02c4db55..fd19e635 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - printf("Stale value received for device: %s, ignoring.\n", address.c_str()); + ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - printf("Value changed for device: %s\n", address.c_str()); + ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); } else { - printf("No change in value for device: %s\n", address.c_str()); + ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - printf("Timeout for device: %s, forcing update.\n", address.c_str()); + ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } diff --git a/test/esphome/core/log.h b/test/esphome/core/log.h index 2a4e890e..2fc2d9a1 100644 --- a/test/esphome/core/log.h +++ b/test/esphome/core/log.h @@ -39,7 +39,7 @@ namespace esphome str += "\n"; \ printf((str.c_str()), ##__VA_ARGS__); \ } while (0); - + #define ESP_LOGI(tag, format, ...) \ do \ { \ @@ -48,5 +48,4 @@ namespace esphome str += "\n"; \ printf((str.c_str()), ##__VA_ARGS__); \ } while (0); - } // namespace esphome From d9b4a6227175651f54980eed267c044a14c22109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:32:43 +0300 Subject: [PATCH 34/44] debug printf --- components/samsung_ac/device_state_tracker.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index fd19e635..ca17a5fd 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); + ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); + ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); } else { - ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); + ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); + ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } @@ -46,6 +46,8 @@ class DeviceStateTracker { std::map last_update_time_; std::map pending_changes_; const unsigned long TIMEOUT_PERIOD; + + static constexpr const char *TAG = "device_state_tracker"; }; #endif // DEVICE_STATE_TRACKER_H From 1d95839b8381b5a6e3b443c310ed5cbdf1136cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:50:58 +0300 Subject: [PATCH 35/44] debug printf --- components/samsung_ac/device_state_tracker.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index ca17a5fd..fd19e635 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); + ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); + ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); } else { - ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); + ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); + ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } @@ -46,8 +46,6 @@ class DeviceStateTracker { std::map last_update_time_; std::map pending_changes_; const unsigned long TIMEOUT_PERIOD; - - static constexpr const char *TAG = "device_state_tracker"; }; #endif // DEVICE_STATE_TRACKER_H From 0db0c6b59eda36d780a03a09dff061b3dfb67af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:53:59 +0300 Subject: [PATCH 36/44] debug printf --- components/samsung_ac/device_state_tracker.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index fd19e635..f8d92bec 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -18,7 +18,7 @@ class DeviceStateTracker { if (current_value == pending_changes_[address]) { pending_changes_.erase(address); } else { - ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); + ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); return; } } @@ -28,13 +28,13 @@ class DeviceStateTracker { last_values_[address] = current_value; last_update_time_[address] = now; - ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); + ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); } else { - ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); + ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); if (now - last_update_time_[address] > TIMEOUT_PERIOD) { if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); + ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); pending_changes_.erase(address); } } From 56e756e0e0d07b83abe3c926b60b05359cc7b977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:54:59 +0300 Subject: [PATCH 37/44] debug printf --- components/samsung_ac/device_state_tracker.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index f8d92bec..02063fb8 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -2,6 +2,7 @@ #define DEVICE_STATE_TRACKER_H #include "esphome/core/log.h" +#include "util.h" #include #include From 21f8ca0cc1c8039e0ce7fb2c80a2530299a3c2a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 16:56:13 +0300 Subject: [PATCH 38/44] debug printf --- components/samsung_ac/device_state_tracker.h | 1 + 1 file changed, 1 insertion(+) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index 02063fb8..80570c5d 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -3,6 +3,7 @@ #include "esphome/core/log.h" #include "util.h" +#include #include #include From d858ba9d89c128f3a39228d7c6027493a02faa39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 17:00:06 +0300 Subject: [PATCH 39/44] Fix device_state_tracker.h and device_state_tracker.cpp file create --- .../samsung_ac/device_state_tracker.cpp | 33 +++++++++++++++++++ components/samsung_ac/device_state_tracker.h | 33 +------------------ 2 files changed, 34 insertions(+), 32 deletions(-) create mode 100644 components/samsung_ac/device_state_tracker.cpp diff --git a/components/samsung_ac/device_state_tracker.cpp b/components/samsung_ac/device_state_tracker.cpp new file mode 100644 index 00000000..eb48d2bd --- /dev/null +++ b/components/samsung_ac/device_state_tracker.cpp @@ -0,0 +1,33 @@ +#include "device_state_tracker.h" +#include "esphome/core/log.h" + +template +void DeviceStateTracker::update(const std::string &address, const T ¤t_value) { + unsigned long now = millis(); + + if (pending_changes_.find(address) != pending_changes_.end()) { + if (current_value == pending_changes_[address]) { + pending_changes_.erase(address); + } else { + ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); + return; + } + } + + if (last_values_.find(address) == last_values_.end() || last_values_[address] != current_value) { + pending_changes_[address] = current_value; + last_values_[address] = current_value; + last_update_time_[address] = now; + + ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); + } else { + ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); + + if (now - last_update_time_[address] > TIMEOUT_PERIOD) { + if (pending_changes_.find(address) != pending_changes_.end()) { + ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); + pending_changes_.erase(address); + } + } + } +} diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index 80570c5d..36ded8fb 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -1,9 +1,6 @@ #ifndef DEVICE_STATE_TRACKER_H #define DEVICE_STATE_TRACKER_H -#include "esphome/core/log.h" -#include "util.h" -#include #include #include @@ -13,35 +10,7 @@ class DeviceStateTracker { DeviceStateTracker(unsigned long timeout_period) : TIMEOUT_PERIOD(timeout_period) {} - void update(const std::string &address, const T ¤t_value) { - unsigned long now = millis(); - - if (pending_changes_.find(address) != pending_changes_.end()) { - if (current_value == pending_changes_[address]) { - pending_changes_.erase(address); - } else { - ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); - return; - } - } - - if (last_values_.find(address) == last_values_.end() || last_values_[address] != current_value) { - pending_changes_[address] = current_value; - last_values_[address] = current_value; - last_update_time_[address] = now; - - ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); - } else { - ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); - - if (now - last_update_time_[address] > TIMEOUT_PERIOD) { - if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); - pending_changes_.erase(address); - } - } - } - } + void update(const std::string &address, const T ¤t_value); private: std::map last_values_; From bcd144a9978249bf281f06da5fd9e9fe5cbeb979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 17:01:47 +0300 Subject: [PATCH 40/44] Fix device_state_tracker.h and device_state_tracker.cpp file create --- .../samsung_ac/device_state_tracker.cpp | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.cpp b/components/samsung_ac/device_state_tracker.cpp index eb48d2bd..79a21034 100644 --- a/components/samsung_ac/device_state_tracker.cpp +++ b/components/samsung_ac/device_state_tracker.cpp @@ -1,33 +1,41 @@ #include "device_state_tracker.h" #include "esphome/core/log.h" +#include "esphome/core/helpers.h" -template -void DeviceStateTracker::update(const std::string &address, const T ¤t_value) { - unsigned long now = millis(); +namespace esphome +{ + static const char *TAG = "device_state_tracker"; - if (pending_changes_.find(address) != pending_changes_.end()) { - if (current_value == pending_changes_[address]) { - pending_changes_.erase(address); - } else { - ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); - return; - } - } + template + void DeviceStateTracker::update(const std::string &address, const T ¤t_value) { + unsigned long now = millis(); - if (last_values_.find(address) == last_values_.end() || last_values_[address] != current_value) { - pending_changes_[address] = current_value; - last_values_[address] = current_value; - last_update_time_[address] = now; + if (pending_changes_.find(address) != pending_changes_.end()) { + if (current_value == pending_changes_[address]) { + pending_changes_.erase(address); + } else { + ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); + return; + } + } - ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); - } else { - ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); + if (last_values_.find(address) == last_values_.end() || last_values_[address] != current_value) { + pending_changes_[address] = current_value; + last_values_[address] = current_value; + last_update_time_[address] = now; - if (now - last_update_time_[address] > TIMEOUT_PERIOD) { - if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); - pending_changes_.erase(address); - } - } - } -} + ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); + } else { + ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); + + if (now - last_update_time_[address] > TIMEOUT_PERIOD) { + if (pending_changes_.find(address) != pending_changes_.end()) { + ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); + pending_changes_.erase(address); + } + } + } + } + + template class DeviceStateTracker; +} // namespace esphome From 07d066604458af222c7e0e40cf479deca409227d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 17:03:37 +0300 Subject: [PATCH 41/44] Fix device_state_tracker.cpp file remove --- .../samsung_ac/device_state_tracker.cpp | 41 ------------------- components/samsung_ac/device_state_tracker.h | 36 +++++++++++++++- 2 files changed, 35 insertions(+), 42 deletions(-) delete mode 100644 components/samsung_ac/device_state_tracker.cpp diff --git a/components/samsung_ac/device_state_tracker.cpp b/components/samsung_ac/device_state_tracker.cpp deleted file mode 100644 index 79a21034..00000000 --- a/components/samsung_ac/device_state_tracker.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "device_state_tracker.h" -#include "esphome/core/log.h" -#include "esphome/core/helpers.h" - -namespace esphome -{ - static const char *TAG = "device_state_tracker"; - - template - void DeviceStateTracker::update(const std::string &address, const T ¤t_value) { - unsigned long now = millis(); - - if (pending_changes_.find(address) != pending_changes_.end()) { - if (current_value == pending_changes_[address]) { - pending_changes_.erase(address); - } else { - ESP_LOGI(TAG, "Stale value received for device: %s, ignoring.", address.c_str()); - return; - } - } - - if (last_values_.find(address) == last_values_.end() || last_values_[address] != current_value) { - pending_changes_[address] = current_value; - last_values_[address] = current_value; - last_update_time_[address] = now; - - ESP_LOGI(TAG, "Value changed for device: %s", address.c_str()); - } else { - ESP_LOGD(TAG, "No change in value for device: %s", address.c_str()); - - if (now - last_update_time_[address] > TIMEOUT_PERIOD) { - if (pending_changes_.find(address) != pending_changes_.end()) { - ESP_LOGW(TAG, "Timeout for device: %s, forcing update.", address.c_str()); - pending_changes_.erase(address); - } - } - } - } - - template class DeviceStateTracker; -} // namespace esphome diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index 36ded8fb..f85c0028 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -1,16 +1,48 @@ #ifndef DEVICE_STATE_TRACKER_H #define DEVICE_STATE_TRACKER_H +#include "esphome/core/log.h" +#include "esphome/core/helpers.h" // millis() fonksiyonu için gerekli #include #include +namespace esphome { + template class DeviceStateTracker { public: DeviceStateTracker(unsigned long timeout_period) : TIMEOUT_PERIOD(timeout_period) {} - void update(const std::string &address, const T ¤t_value); + void update(const std::string &address, const T ¤t_value) { + unsigned long now = millis(); + + if (pending_changes_.find(address) != pending_changes_.end()) { + if (current_value == pending_changes_[address]) { + pending_changes_.erase(address); + } else { + ESP_LOGI("device_state_tracker", "Stale value received for device: %s, ignoring.", address.c_str()); + return; + } + } + + if (last_values_.find(address) == last_values_.end() || last_values_[address] != current_value) { + pending_changes_[address] = current_value; + last_values_[address] = current_value; + last_update_time_[address] = now; + + ESP_LOGI("device_state_tracker", "Value changed for device: %s", address.c_str()); + } else { + ESP_LOGD("device_state_tracker", "No change in value for device: %s", address.c_str()); + + if (now - last_update_time_[address] > TIMEOUT_PERIOD) { + if (pending_changes_.find(address) != pending_changes_.end()) { + ESP_LOGW("device_state_tracker", "Timeout for device: %s, forcing update.", address.c_str()); + pending_changes_.erase(address); + } + } + } + } private: std::map last_values_; @@ -19,4 +51,6 @@ class DeviceStateTracker { const unsigned long TIMEOUT_PERIOD; }; +} // namespace esphome + #endif // DEVICE_STATE_TRACKER_H From ac409b42a9874fa8d0d53e98919db89d89ad4f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Fri, 30 Aug 2024 19:07:35 +0300 Subject: [PATCH 42/44] Refactor: Simplified log macros and used consistent TAG casing --- components/samsung_ac/device_state_tracker.h | 2 +- test/esphome/core/log.h | 45 ++++---------------- 2 files changed, 10 insertions(+), 37 deletions(-) diff --git a/components/samsung_ac/device_state_tracker.h b/components/samsung_ac/device_state_tracker.h index f85c0028..394d4920 100644 --- a/components/samsung_ac/device_state_tracker.h +++ b/components/samsung_ac/device_state_tracker.h @@ -2,7 +2,7 @@ #define DEVICE_STATE_TRACKER_H #include "esphome/core/log.h" -#include "esphome/core/helpers.h" // millis() fonksiyonu için gerekli +#include "esphome/core/helpers.h" #include #include diff --git a/test/esphome/core/log.h b/test/esphome/core/log.h index 2fc2d9a1..644e55bf 100644 --- a/test/esphome/core/log.h +++ b/test/esphome/core/log.h @@ -4,48 +4,21 @@ namespace esphome { -#define ESP_LOGD(tag, format, ...) \ +#define ESP_LOG(level, TAG, format, ...) \ do \ { \ - std::string str = ""; \ + std::string str = "["; \ + str += level; \ + str += "] "; \ str += format; \ str += "\n"; \ printf((str.c_str()), ##__VA_ARGS__); \ } while (0); -#define ESP_LOGE(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ - } while (0); - -#define ESP_LOGW(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ - } while (0); +#define ESP_LOGD(TAG, format, ...) ESP_LOG("DEBUG", TAG, format, ##__VA_ARGS__) +#define ESP_LOGE(TAG, format, ...) ESP_LOG("ERROR", TAG, format, ##__VA_ARGS__) +#define ESP_LOGW(TAG, format, ...) ESP_LOG("WARN", TAG, format, ##__VA_ARGS__) +#define ESP_LOGV(TAG, format, ...) ESP_LOG("VERBOSE", TAG, format, ##__VA_ARGS__) +#define ESP_LOGI(TAG, format, ...) ESP_LOG("INFO", TAG, format, ##__VA_ARGS__) -#define ESP_LOGV(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ - } while (0); - -#define ESP_LOGI(tag, format, ...) \ - do \ - { \ - std::string str = ""; \ - str += format; \ - str += "\n"; \ - printf((str.c_str()), ##__VA_ARGS__); \ - } while (0); } // namespace esphome From e70a9329ab67c1831bf2e2f51c810df5276b39a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= Date: Tue, 10 Sep 2024 13:06:23 +0300 Subject: [PATCH 43/44] Add 'Eco Mode' to preset #172 --- components/samsung_ac/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/components/samsung_ac/__init__.py b/components/samsung_ac/__init__.py index fef77d9e..d0238013 100644 --- a/components/samsung_ac/__init__.py +++ b/components/samsung_ac/__init__.py @@ -104,6 +104,7 @@ def preset_entry( "quiet": {"value": 2, "displayName": "Quiet"}, "fast": {"value": 3, "displayName": "Fast"}, "longreach": {"value": 6, "displayName": "LongReach"}, + "eco": {"value": 7, "displayName": "Eco"}, "windfree": {"value": 9, "displayName": "WindFree"}, } From 5eea1f4a8c8559731fffb54279807beb67ec0005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20ARAN?= <89782300+omerfaruk-aran@users.noreply.github.com> Date: Tue, 8 Oct 2024 01:11:45 +0300 Subject: [PATCH 44/44] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 72aebddc..8204ad6d 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ This project offers a [ESPHome](https://esphome.io/index.html) component for integrating Samsung air conditioners into your home automation system. It provides the ability to monitor and control your AC units effortlessly. -This component is designed to connect to the F1 and F2 communication bus between the indoor and the outdoor devices. +This component is designed to connect to the Samsung HAVC devices with an F1/F2 communication bus (between the indoor and the outdoor devices). Samsung has employed different software protocols for their AC devices over the years. The older devices utilize the Non NASA protocol, while the newer ones utilize the NASA protocol. This ESPHome component is designed to support both protocols, ensuring compatibility with a wide range of Samsung AC units. @@ -47,7 +47,7 @@ There are also two Discussion threads about confirmed [NASA]([url](https://githu #### NASA -- AJ080TXJ4KG, AJ026TN1DKG, AR24TXHZAWKNEU, AR09TXFCAWKNEU, AC030KNZDCH/AA (CNH30ZDK), AE090RNYDEG, AE090RXEDEG, AE160JXYDEH/EU, AR09TXFCAWKNEU +- AJ080TXJ4KG, AJ026TN1DKG, AR24TXHZAWKNEU, AR24TXFCAWKN, AR09TXFCAWKNEU, AC030KNZDCH/AA (CNH30ZDK), AE090RNYDEG, AE090RXEDEG, AE160JXYDEH/EU, AR09TXFCAWKNEU, AR07TXFCAWKNEU #### NonNASA