You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
5.7 KiB

  1. #pragma once
  2. #include "../common.h"
  3. namespace esphome {
  4. namespace xiaomi {
  5. namespace bslamp2 {
  6. class Preset {
  7. public:
  8. std::string name;
  9. Preset *next_preset = nullptr;
  10. std::string group_name;
  11. light::LightCall *light_call;
  12. explicit Preset(std::string name, std::string group_name) :
  13. name(name), group_name(group_name) {}
  14. void set_light_call(light::LightCall *light_call) {
  15. this->light_call = light_call;
  16. }
  17. void apply() {
  18. ESP_LOGI(TAG, "Activating light preset: %s/%s",
  19. group_name.c_str(), name.c_str());
  20. light_call->perform();
  21. }
  22. };
  23. class PresetGroup {
  24. public:
  25. std::string name;
  26. PresetGroup *next_group = nullptr;
  27. Preset *first_preset = nullptr;
  28. Preset *last_preset = nullptr;
  29. Preset *active_preset = nullptr;
  30. explicit PresetGroup(std::string g_name) : name(g_name) {}
  31. Preset *make_preset(std::string p_name) {
  32. auto p = get_preset(p_name);
  33. if (p == nullptr) {
  34. p = new Preset(p_name, this->name);
  35. if (first_preset == nullptr) {
  36. first_preset = last_preset = active_preset = p;
  37. } else {
  38. last_preset->next_preset = p;
  39. last_preset = p;
  40. }
  41. }
  42. return p;
  43. }
  44. Preset *get_preset(std::string p_name) {
  45. for (auto p = first_preset; p != nullptr; p = p->next_preset) {
  46. if (p->name == p_name) {
  47. return p;
  48. }
  49. }
  50. return nullptr;
  51. }
  52. };
  53. class PresetsContainer : public Component {
  54. public:
  55. PresetGroup *first_group = nullptr;
  56. PresetGroup *last_group = nullptr;
  57. PresetGroup *active_group = nullptr;
  58. explicit PresetsContainer(light::LightState *light) : _light(light) { }
  59. void dump_config() {
  60. if (first_group == nullptr) {
  61. return;
  62. }
  63. ESP_LOGCONFIG(TAG, "Light Presets:");
  64. for (auto g = first_group; g != nullptr; g = g->next_group) {
  65. ESP_LOGCONFIG(TAG, " Preset group: %s", g->name.c_str());
  66. for (auto p = g->first_preset; p != nullptr; p = p->next_preset) {
  67. ESP_LOGCONFIG(TAG, " Preset: %s", p->name.c_str());
  68. }
  69. }
  70. }
  71. void add(std::string g_name, std::string p_name, float r, float g, float b) {
  72. auto call = make_preset_call_(g_name, p_name);
  73. call->set_rgb(r, g, b);
  74. }
  75. void add(std::string g_name, std::string p_name, float t) {
  76. auto call = make_preset_call_(g_name, p_name);
  77. call->set_color_temperature(t);
  78. }
  79. PresetGroup *get_group(std::string g_name) {
  80. for (auto g = first_group; g != nullptr; g = g->next_group) {
  81. if (g->name == g_name) {
  82. return g;
  83. }
  84. }
  85. return nullptr;
  86. }
  87. void activate_next_group() {
  88. if (active_group == nullptr) {
  89. ESP_LOGW(TAG, "activate_next_group(): no preset groups defined");
  90. return;
  91. }
  92. active_group = active_group->next_group == nullptr
  93. ? first_group : active_group->next_group;
  94. if (active_group->active_preset == nullptr) {
  95. ESP_LOGW(TAG, "activate_next_group(): no presets defined for group %s",
  96. active_group->name.c_str());
  97. return;
  98. }
  99. active_group->active_preset->apply();
  100. }
  101. void activate_next_preset() {
  102. if (active_group == nullptr) {
  103. ESP_LOGW(TAG, "activate_next_preset(): no preset groups defined");
  104. return;
  105. }
  106. auto p = active_group->active_preset;
  107. if (p == nullptr) {
  108. ESP_LOGW(TAG, "activate_next_preset(): no presets defined for group %s",
  109. active_group->name.c_str());
  110. return;
  111. }
  112. active_group->active_preset = p->next_preset == nullptr
  113. ? active_group->first_preset : p->next_preset;
  114. active_group->active_preset->apply();
  115. }
  116. void activate_group(std::string g_name) {
  117. auto g = get_group(g_name);
  118. if (g == nullptr) {
  119. ESP_LOGE(TAG, "activate_group(%s): preset group does not exist",
  120. g_name.c_str());
  121. return;
  122. }
  123. auto p = g->active_preset;
  124. if (p == nullptr) {
  125. ESP_LOGW(TAG, "activate_group(%s): no presets defined for group",
  126. g_name.c_str());
  127. return;
  128. }
  129. p->apply();
  130. }
  131. void activate_preset(std::string g_name, std::string p_name) {
  132. auto g = get_group(g_name);
  133. if (g == nullptr) {
  134. ESP_LOGE(TAG, "activate_preset(%s, %s): preset group %s does not exist",
  135. g_name.c_str(), p_name.c_str(), g_name.c_str());
  136. return;
  137. }
  138. auto p = g->get_preset(p_name);
  139. if (p == nullptr) {
  140. ESP_LOGE(TAG, "activate_preset(%s, %s): preset %s does not exist in group %s",
  141. g_name.c_str(), p_name.c_str(), p_name.c_str(), g_name.c_str());
  142. return;
  143. }
  144. p->apply();
  145. }
  146. protected:
  147. light::LightState *_light;
  148. PresetGroup *make_preset_group_(std::string g_name) {
  149. auto g = get_group(g_name);
  150. if (g == nullptr) {
  151. g = new PresetGroup(g_name);
  152. if (first_group == nullptr) {
  153. first_group = last_group = active_group = g;
  154. } else {
  155. last_group->next_group = g;
  156. last_group = g;
  157. }
  158. }
  159. return g;
  160. }
  161. light::LightCall *make_preset_call_(std::string g_name, std::string p_name) {
  162. auto g = make_preset_group_(g_name);
  163. auto p = g->make_preset(p_name);
  164. auto c = new light::LightCall(_light);
  165. p->set_light_call(c);
  166. return c;
  167. }
  168. };
  169. } // namespace bslamp2
  170. } // namespace xiaomi
  171. } // namespace esphome