From 48a66234d66872cfa735e240c5afba9bebddb3b5 Mon Sep 17 00:00:00 2001 From: Oliver Kleinecke Date: Tue, 18 Feb 2025 16:44:46 +0100 Subject: [PATCH] feat: refactor lamp handling in DynamicLampComponent to support lamp lists and improve timer functionality --- .../components/dynamic_lamp/dynamic_lamp.cpp | 125 +++++++++++++++--- .../components/dynamic_lamp/dynamic_lamp.h | 26 +++- 2 files changed, 133 insertions(+), 18 deletions(-) diff --git a/esphome/components/dynamic_lamp/dynamic_lamp.cpp b/esphome/components/dynamic_lamp/dynamic_lamp.cpp index e483b5ea29..3541b9701b 100644 --- a/esphome/components/dynamic_lamp/dynamic_lamp.cpp +++ b/esphome/components/dynamic_lamp/dynamic_lamp.cpp @@ -214,27 +214,33 @@ std::array DynamicLampComponent::get_lamp_outputs(uint8_t lamp_number) return bool_array; } -std::array DynamicLampComponent::get_lamp_outputs_by_name(std::string lamp_name) { +uint8_t DynamicLampComponent::get_lamp_index_by_name(std::string lamp_name) { uint8_t i = 0; - std::array bool_array; for (i = 0; i < this->lamp_count_; i++) { if (this->active_lamps_[i].name == lamp_name) { - return this->get_lamp_outputs(i); + return i; } } this->status_set_warning(); ESP_LOGW(TAG, "No lamp with name %s defined !", lamp_name.c_str()); - return bool_array; + return 255; } -bool DynamicLampComponent::add_timer(std::string lamp_name, bool timer_active, uint8_t mode, uint8_t hour, +std::array DynamicLampComponent::get_lamp_outputs_by_name(std::string lamp_name) { + uint8_t lamp_index = this->get_lamp_index_by_name(lamp_name); + if (lamp_index == 255) { + std::array bool_array; + return bool_array; + } + return this->get_lamp_outputs(i); +} + +bool DynamicLampComponent::add_timer(std::string lamp_list_str, bool timer_active, uint8_t mode, uint8_t hour, uint8_t minute, bool monday, bool tuesday, bool wednesday, bool thursday, bool friday, bool saturday, bool sunday) { - //unsigned char* lamp_name_cstr = lamp_name.c_str(); - unsigned char lamp_name_buffer[32]; - strncpy(static_cast(static_cast(&lamp_name_buffer)), lamp_name.c_str(), 32); + LampList lamp_list = this->build_lamp_list_from_list_str_(lamp_list_str); DynamicLampTimer new_timer; - memcpy(new_timer.lamp_name, lamp_name_buffer, 32); + memcpy(new_timer.lamp_list, &lamp_list, 2); new_timer.active = timer_active; new_timer.mode = mode; new_timer.hour = hour; @@ -254,12 +260,80 @@ bool DynamicLampComponent::add_timer(std::string lamp_name, bool timer_active, u new_timer.end_date = end_date; unsigned char* timer_as_bytes = static_cast(static_cast(&new_timer)); ESP_LOGV(TAG, "Added new timer for lamp %s, active %d, mode %d, hour %d, minute %d, monday %d, tuesday %d, wednesday %d, thursday %d, friday %d, saturday %d, sunday %d", - new_timer.lamp_name, new_timer.active, new_timer.mode, new_timer.hour, new_timer.minute, new_timer.monday, new_timer.tuesday, new_timer.wednesday, + lamp_list_str.c_str(), new_timer.active, new_timer.mode, new_timer.hour, new_timer.minute, new_timer.monday, new_timer.tuesday, new_timer.wednesday, new_timer.thursday, new_timer.friday, new_timer.saturday, new_timer.sunday); ESP_LOGV(TAG, "Size of struct is %" PRIu8 "", static_cast(sizeof(new_timer))); - //this->fram_->write(2048, reinterpret_cast(lamp_name_buffer), 32); - this->fram_->write((2048), timer_as_bytes, 56); - return true; + this->fram_->write((2048), timer_as_bytes, 24); + return true; +} + +LampList DynamicLampComponent::build_lamp_list_from_list_str_(std::string lamp_list_str) { + std::string delimiter = ","; + std::vector lamp_list_vector = this->split_to_int_array_(s, delimiter); + if (lamp_list_vector.size() > 16) { + ESP_LOGW(TAG, "Too many lamps in list, only 16 supported!"); + this->status_set_warning(); + return false; + } + LampList lamp_list; + for (uint8_t i = 0; i < lamp_list_vector.size(); i++) { + if (lamp_list_vector[i] > 15) { + ESP_LOGW(TAG, "Lamp index %" PRIu8 " is out of range, only [0-15] supported!", lamp_list_vector[i]); + this->status_set_warning(); + return false; + } + switch (lamp_list_vector[i]) { + case 0: + lamp_list.lamp_0 = true; + break; + case 1: + lamp_list.lamp_1 = true; + break; + case 2: + lamp_list.lamp_2 = true; + break; + case 3: + lamp_list.lamp_3 = true; + break; + case 4: + lamp_list.lamp_4 = true; + break; + case 5: + lamp_list.lamp_5 = true; + break; + case 6: + lamp_list.lamp_6 = true; + break; + case 7: + lamp_list.lamp_7 = true; + break; + case 8: + lamp_list.lamp_8 = true; + break; + case 9: + lamp_list.lamp_9 = true; + break; + case 10: + lamp_list.lamp_10 = true; + break; + case 11: + lamp_list.lamp_11 = true; + break; + case 12: + lamp_list.lamp_12 = true; + break; + case 13: + lamp_list.lamp_13 = true; + break; + case 14: + lamp_list.lamp_14 = true; + break; + case 15: + lamp_list.lamp_15 = true; + break; + } + } + return lamp_list; } void DynamicLampComponent::read_timers_to_log() { @@ -267,10 +341,15 @@ void DynamicLampComponent::read_timers_to_log() { for (i = 0; i < 16; i++) { if (this->active_lamps_[i].active) { DynamicLampTimer timer; - this->fram_->read((2048), reinterpret_cast(&timer), 56); - ESP_LOGV(TAG, "Timer found for lamp %s: %d, mode: %d, hour: %d, minute: %d, monday: %d, tuesday: %d, wednesday: %d, thursday: %d, friday: %d, saturday: %d, sunday: %d", - timer.lamp_name, timer.active, timer.mode, timer.hour, timer.minute, timer.monday, timer.tuesday, + this->fram_->read((2048), reinterpret_cast(&timer), 24); + LampList lamp_list = *reinterpret_cast(&timer.lamp_list); + for (uint8_t j = 0; j < 16; j++) { + if (lamp_list[j]) { + ESP_LOGV(TAG, "Timer found for lamp %s: %d, mode: %d, hour: %d, minute: %d, monday: %d, tuesday: %d, wednesday: %d, thursday: %d, friday: %d, saturday: %d, sunday: %d", + this->active_lamps_[j].name, timer.active, timer.mode, timer.hour, timer.minute, timer.monday, timer.tuesday, timer.wednesday, timer.thursday, timer.friday, timer.saturday, timer.sunday); + } + } } } } @@ -296,5 +375,19 @@ void DynamicLampComponent::restore_lamp_values_(uint8_t lamp_number) { this->active_lamps_[lamp_number].active = false; } +std::vector DynamicLampComponent::split_to_int_array_(const std::string& s, const std::string& delimiter) { + std::vector tokens; + size_t pos = 0; + std::string token; + while ((pos = s.find(delimiter)) != std::string::npos) { + token = static_cast(atoi(s.substr(0, pos))); + tokens.push_back(token); + s.erase(0, pos + delimiter.length()); + } + tokens.push_back(s); + + return tokens; +} + } // namespace dynamic_lamp } // namespace esphome diff --git a/esphome/components/dynamic_lamp/dynamic_lamp.h b/esphome/components/dynamic_lamp/dynamic_lamp.h index 9ab0be16ca..0444824ae4 100644 --- a/esphome/components/dynamic_lamp/dynamic_lamp.h +++ b/esphome/components/dynamic_lamp/dynamic_lamp.h @@ -68,9 +68,29 @@ struct CombinedLamp { bool used_outputs[16]; }; +struct LampList { + bool lamp_0 : 1; + bool lamp_1 : 1; + bool lamp_2 : 1; + bool lamp_3 : 1; + bool lamp_4 : 1; + bool lamp_5 : 1; + bool lamp_6 : 1; + bool lamp_7 : 1; + bool lamp_8 : 1; + bool lamp_9 : 1; + bool lamp_10 : 1; + bool lamp_11 : 1; + bool lamp_12 : 1; + bool lamp_13 : 1; + bool lamp_14 : 1; + bool lamp_15 : 1; +}; + struct DynamicLampTimer { - unsigned char lamp_name[32]; - uint8_t mode : 1; + unsigned char validation[3] = { "D", "L", "T" }; + uint8_t lamp_list[2]; + uint8_t action : 3; uint8_t hour : 5; uint8_t minute : 6; bool active : 1; @@ -116,6 +136,8 @@ class DynamicLampComponent : public Component { void restore_lamp_values_(uint8_t lamp_number); void set_lamp_values_(uint8_t lamp_number, bool active, uint16_t selected_outputs, uint8_t mode, uint8_t mode_value); bool write_state_(uint8_t lamp_number, float state); + std::vector split_to_int_array_(const std::string& s, const std::string& delimiter); + LampList build_lamp_list_from_list_str_(std::string lamp_list_str); CombinedLamp active_lamps_[16]; LinkedOutput available_outputs_[16];