From 0a48a3b067029cf592b0f1336b00843d320162ab Mon Sep 17 00:00:00 2001
From: sqozz <sqozz-git@geekify.de>
Date: Sun, 22 Sep 2024 01:00:57 +0200
Subject: [PATCH] Add central select validator and parser

---
 select/tw7100_select.cpp | 191 +++++++++++++++++++++++++++++++++++++++
 select/tw7100_select.h   |  77 +---------------
 tw7100.cpp               |  33 +++----
 3 files changed, 204 insertions(+), 97 deletions(-)

diff --git a/select/tw7100_select.cpp b/select/tw7100_select.cpp
index 42c8e7a..293fdb9 100644
--- a/select/tw7100_select.cpp
+++ b/select/tw7100_select.cpp
@@ -6,6 +6,82 @@
 
 namespace esphome {
 namespace tw7100 {
+
+std::map<std::string, std::string> tw7100Select::sources = {
+  {"30", "HDMI1"},
+  {"53", "LAN"},
+  {"A0", "HDMI2"}
+};
+std::map<std::string, std::string> tw7100Select::luminance = {
+  {"00", "Normal"},
+  {"01", "Eco"},
+  {"02", "Medium"}
+};
+std::map<std::string, std::string> tw7100Select::aspect = {
+  {"00", "Normal"},
+  {"30", "Auto"},
+  {"40", "Full"},
+  {"50", "Zoom"},
+  {"80", "Anamorphic"},
+  {"90", "Hsqueeze"}
+};
+std::map<std::string, std::string> tw7100Select::msel = {
+  {"00", "Black"},
+  {"01", "Blue"},
+  {"02", "User logo"}
+};
+std::map<std::string, std::string> tw7100Select::speed = {
+  {"00", "9600bps"},
+  {"01", "19200bps"},
+  {"02", "38400bps"},
+  {"03", "57600bps"}
+};
+std::map<std::string, std::string> tw7100Select::mcfi = {
+  {"00", "Off"},
+  {"01", "Low"},
+  {"02", "Normal"},
+  {"03", "High"}
+};
+std::map<std::string, std::string> tw7100Select::clrspace = {
+  {"00", "Auto"},
+  {"01", "BT.709"},
+  {"02", "BT.2020"}
+};
+std::map<std::string, std::string> tw7100Select::dynrange = {
+  {"00", "Auto"},
+  {"01", "SDR"},
+  {"20", "HDR10"},
+  {"30", "HLG"}
+};
+std::map<std::string, std::string> tw7100Select::imgpreset = {
+  {"00", "Off"},
+  {"01", "Setting 1"},
+  {"02", "Setting 2"},
+  {"03", "Setting 3"},
+  {"04", "Setting 4"},
+  {"05", "Setting 5"}
+};
+std::map<std::string, std::string> tw7100Select::gamma = {
+  {"20", "Setting 2"},
+  {"21", "Setting 1"},
+  {"22", "Setting 0"},
+  {"23", "Setting -1"},
+  {"24", "Setting -2"},
+  {"F0", "Custom"}
+};
+std::map<std::string, std::string> tw7100Select::cmode = {
+  {"06", "Dynamic"},
+  {"07", "Natural"},
+  {"0C", "Bright Cinema"},
+  {"15", "Cinema"}
+};
+std::map<std::string, std::string> tw7100Select::ovscan = {
+  {"00", "Off"},
+  {"02", "4%"},
+  {"04", "8%"},
+  {"A0", "Auto"}
+};
+
 std::vector<std::string> get_map_keys(std::map<std::string, std::string> map_) {
   std::vector<std::string> map_keys;
   for (auto element : map_) { map_keys.push_back(element.first); }
@@ -64,6 +140,24 @@ void tw7100Select::control(const std::string &value) {
     for (auto element : luminance) { if (element.second == value) { param = element.first; break; } }
   } else if (cmd_ == "ASPECT") {
     for (auto element : aspect) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "OVSCAN") {
+    for (auto element : aspect) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "CMODE") {
+    for (auto element : cmode) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "GAMMA") {
+    for (auto element : gamma) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "IMGPRESET") {
+    for (auto element : imgpreset) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "MCFI") {
+    for (auto element : mcfi) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "CLRSPACE") {
+    for (auto element : clrspace) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "DYNRANGE") {
+    for (auto element : dynrange) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "MSEL") {
+    for (auto element : msel) { if (element.second == value) { param = element.first; break; } }
+  } else if ( cmd_ == "SPEED") {
+    //for (auto element : speed) { if (element.second == value) { param = element.first; break; } }
   }
 
   if (param.length() > 0) {
@@ -77,5 +171,102 @@ void tw7100Select::control(const std::string &value) {
   ESP_LOGV(TAG, "control done");
 };
 
+void tw7100Select::set_option_by_key(std::string key) {
+  static const char *const TAG = "tw7100Select::set_option_by_key()";
+
+  std::string value_found = "";
+  if ( cmd_ == "LUMINANCE") {
+    ESP_LOGV(TAG, "updating luminance select");
+    if(tw7100Select::luminance.find(key) != tw7100Select::luminance.end()) {
+      value_found = tw7100Select::luminance[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "SOURCE") {
+    ESP_LOGV(TAG, "updating source select");
+    if(tw7100Select::sources.find(key) != tw7100Select::sources.end()) {
+      value_found = tw7100Select::sources[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "ASPECT") {
+    ESP_LOGV(TAG, "updating aspect select");
+    if(tw7100Select::aspect.find(key) != tw7100Select::aspect.end()) {
+      value_found = tw7100Select::aspect[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "OVSCAN") {
+    ESP_LOGV(TAG, "updating ovscan select");
+    if(tw7100Select::ovscan.find(key) != tw7100Select::ovscan.end()) {
+      value_found = tw7100Select::ovscan[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "CMODE") {
+    ESP_LOGV(TAG, "updating cmode select");
+    if(tw7100Select::cmode.find(key) != tw7100Select::cmode.end()) {
+      value_found = tw7100Select::cmode[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "GAMMA") {
+    ESP_LOGV(TAG, "updating gamma select");
+    if(tw7100Select::gamma.find(key) != tw7100Select::gamma.end()) {
+      value_found = tw7100Select::gamma[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "IMGPRESET") {
+    ESP_LOGV(TAG, "updating imgpreset select");
+    if(tw7100Select::imgpreset.find(key) != tw7100Select::imgpreset.end()) {
+      value_found = tw7100Select::imgpreset[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "MCFI") {
+    ESP_LOGV(TAG, "updating mcfi select");
+    if(tw7100Select::mcfi.find(key) != tw7100Select::mcfi.end()) {
+      value_found = tw7100Select::mcfi[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "CLRSPACE") {
+    ESP_LOGV(TAG, "updating clrspace select");
+    if(tw7100Select::clrspace.find(key) != tw7100Select::clrspace.end()) {
+      value_found = tw7100Select::clrspace[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "DYNRANGE") {
+    ESP_LOGV(TAG, "updating dynrange select");
+    if(tw7100Select::dynrange.find(key) != tw7100Select::dynrange.end()) {
+      value_found = tw7100Select::dynrange[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "MSEL") {
+    ESP_LOGV(TAG, "updating msel select");
+    if(tw7100Select::msel.find(key) != tw7100Select::msel.end()) {
+      value_found = tw7100Select::msel[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  } else if ( cmd_ == "SPEED") {
+    ESP_LOGV(TAG, "updating speed select");
+    if(tw7100Select::speed.find(key) != tw7100Select::speed.end()) {
+      value_found = tw7100Select::speed[key];
+    } else {
+      ESP_LOGE(TAG, "Result %s not present in options", key);
+    }
+  }
+
+  if (value_found.length() > 0) {
+    auto call = make_call();
+    call.set_option(value_found);
+    call.perform();
+  }
+};
+
 }  // namespace tw7100
 }  // namespace esphome
diff --git a/select/tw7100_select.h b/select/tw7100_select.h
index e57f44f..5f4c280 100644
--- a/select/tw7100_select.h
+++ b/select/tw7100_select.h
@@ -15,6 +15,7 @@ class tw7100Select : public select::Select, public Component {
     void dump_config() override;
     void set_tw7100_parent(tw7100Component *parent) { this->parent_ = parent; }
     void set_cmd(std::string cmd) { this->cmd_ = cmd; }
+    void set_option_by_key(std::string key);
     static std::map<std::string, std::string> sources;
     static std::map<std::string, std::string> luminance;
     static std::map<std::string, std::string> aspect;
@@ -32,82 +33,6 @@ class tw7100Select : public select::Select, public Component {
     void control(const std::string &value) override;
     std::string cmd_;
     tw7100Component *parent_;
-
-
-std::map<std::string, std::string> tw7100Select::sources = {
-  {"30", "HDMI1"},
-  {"53", "LAN"},
-  {"A0", "HDMI2"}
-};
-std::map<std::string, std::string> tw7100Select::luminance = {
-  {"00", "Normal"},
-  {"01", "Eco"},
-  {"02", "Medium"}
-};
-std::map<std::string, std::string> tw7100Select::aspect = {
-  {"00", "Normal"},
-  {"30", "Auto"},
-  {"40", "Full"},
-  {"50", "Zoom"},
-  {"80", "Anamorphic"},
-  {"90", "Hsqueeze"}
-};
-std::map<std::string, std::string> tw7100Select::msel = {
-  {"00", "Black"},
-  {"01", "Blue"},
-  {"02", "User logo"}
-};
-std::map<std::string, std::string> tw7100Select::speed = {
-  {"00", "9600bps"},
-  {"01", "19200bps"},
-  {"02", "38400bps"},
-  {"03", "57600bps"}
-};
-std::map<std::string, std::string> tw7100Select::mcfi = {
-  {"00", "Off"},
-  {"01", "Low"},
-  {"02", "Normal"},
-  {"03", "High"}
-};
-std::map<std::string, std::string> tw7100Select::clrspace = {
-  {"00", "Auto"},
-  {"01", "BT.709"},
-  {"02", "BT.2020"}
-};
-std::map<std::string, std::string> tw7100Select::dynrange = {
-  {"00", "Auto"},
-  {"01", "SDR"},
-  {"20", "HDR10"},
-  {"30", "HLG"}
-};
-std::map<std::string, std::string> tw7100Select::imgpreset = {
-  {"00", "Off"},
-  {"01", "Setting 1"},
-  {"02", "Setting 2"},
-  {"03", "Setting 3"},
-  {"04", "Setting 4"},
-  {"05", "Setting 5"}
-};
-std::map<std::string, std::string> tw7100Select::gamma = {
-  {"20", "Setting 2"},
-  {"21", "Setting 1"},
-  {"22", "Setting 0"},
-  {"23", "Setting -1"},
-  {"24", "Setting -2"},
-  {"F0", "Custom"}
-};
-std::map<std::string, std::string> tw7100Select::cmode = {
-  {"06", "Dynamic"},
-  {"07", "Natural"},
-  {"0C", "Bright Cinema"},
-  {"15", "Cinema"}
-};
-std::map<std::string, std::string> tw7100Select::ovscan = {
-  {"00", "Off"},
-  {"02", "4%"},
-  {"04", "8%"},
-  {"A0", "Auto"}
-};
 };
 
 }  // namespace tw7100
diff --git a/tw7100.cpp b/tw7100.cpp
index 4de5463..e2bd9cf 100644
--- a/tw7100.cpp
+++ b/tw7100.cpp
@@ -247,49 +247,40 @@ void tw7100Component::update_sensor(std::pair<std::string, std::string> data) {
     ESP_LOGV(TAG, "updating luminance sensors");
     int value = std::stoi(value_string);
     luminance_level_->publish_state(value);
-    if(tw7100Select::luminance.find(value_string) != tw7100Select::luminance.end()) {
-      auto call = luminance_select_->make_call();
-      call.set_option(tw7100Select::luminance[value_string]);
-      call.perform();
-    } else {
-      ESP_LOGE(TAG, "Result %s not present in options", value_string);
-    }
+    luminance_select_->set_option_by_key(value_string);
   } else if (cmd == "SOURCE") {
     ESP_LOGV(TAG, "updating source select");
-    if(tw7100Select::sources.find(value_string) != tw7100Select::sources.end()) {
-      auto call = source_select_->make_call();
-      call.set_option(tw7100Select::sources[value_string]);
-      call.perform();
-    } else {
-      ESP_LOGE(TAG, "Result %s not present in options", value_string);
-    }
+    source_select_->set_option_by_key(value_string);
   } else if (cmd == "ASPECT") {
     ESP_LOGV(TAG, "updating aspect select");
-    if(tw7100Select::aspect.find(value_string) != tw7100Select::aspect.end()) {
-      auto call = aspect_select_->make_call();
-      call.set_option(tw7100Select::aspect[value_string]);
-      call.perform();
-    } else {
-      ESP_LOGE(TAG, "Result %s not present in options", value_string);
-    }
+    aspect_select_->set_option_by_key(value_string);
   } else if (cmd == "OVSCAN") {
     ESP_LOGV(TAG, "updating ovscan select");
+    ovscan_select_->set_option_by_key(value_string);
   } else if (cmd == "CMODE") {
     ESP_LOGV(TAG, "updating cmode select");
+    cmode_select_->set_option_by_key(value_string);
   } else if (cmd == "GAMMA") {
     ESP_LOGV(TAG, "updating gamma select");
+    gamma_select_->set_option_by_key(value_string);
   } else if (cmd == "IMGPRESET") {
     ESP_LOGV(TAG, "updating imgpreset select");
+    imgpreset_select_->set_option_by_key(value_string);
   } else if (cmd == "MCFI") {
     ESP_LOGV(TAG, "updating mcfi select");
+    mcfi_select_->set_option_by_key(value_string);
   } else if (cmd == "CLRSPACE") {
     ESP_LOGV(TAG, "updating clrspace select");
+    clrspace_select_->set_option_by_key(value_string);
   } else if (cmd == "DYNRANGE") {
     ESP_LOGV(TAG, "updating dynrange select");
+    dynrange_select_->set_option_by_key(value_string);
   } else if (cmd == "MSEL") {
     ESP_LOGV(TAG, "updating msel select");
+    msel_select_->set_option_by_key(value_string);
   } else if (cmd == "SPEED") {
     ESP_LOGV(TAG, "updating speed select");
+    speed_select_->set_option_by_key(value_string);
 #endif
 #ifdef USE_TEXT_SENSOR
   } else if (cmd == "SNO") {