diff --git a/__init__.py b/__init__.py index a8553f3..d1eb51f 100644 --- a/__init__.py +++ b/__init__.py @@ -6,7 +6,7 @@ from esphome.const import CONF_ID CODEOWNERS = ["@sqozz"] DEPENDENCIES = ["uart"] -AUTO_LOAD = ["binary_sensor", "sensor", "text_sensor"] +AUTO_LOAD = ["binary_sensor", "sensor", "text_sensor", "number", "switch"] tw7100_ns = cg.esphome_ns.namespace("tw7100") tw7100 = tw7100_ns.class_("tw7100Component", cg.PollingComponent, uart.UARTDevice) diff --git a/select/__init__.py b/select/__init__.py index 5423bfc..9ead2bb 100644 --- a/select/__init__.py +++ b/select/__init__.py @@ -10,30 +10,35 @@ CODEOWNERS = ["@sqozz"] tw7100Select = tw7100_ns.class_("tw7100Select", select.Select, cg.Component) -CONFIG_SCHEMA = cv.Schema( - { - cv.GenerateID(): cv.use_id(tw7100), - cv.Optional("SOURCE"): select.select_schema( - tw7100Select - ), - cv.Optional("LUMINANCE"): select.select_schema( - tw7100Select - ), - } -) +selects = [ + ("SOURCE", "mdi:video-input-hdmi"), + ("LUMINANCE", "mdi:brightness-6"), + ("CMODE", ""), + ("GAMMA", "mdi:gamma"), + ("IMGPRESET", "mdi:palette"), + ("MCFI", "mdi:image-multiple"), + ("CLRSPACE", ""), + ("DYNRANGE", "mdi:hdr"), + ("IMGPROC", ""), + ("MSEL", "mdi:image-off"), + ("SPEED", "mdi:speedometer"), + ("OVSCAN", "mdi:overscan"), + ("ASPECT", "mdi:aspect-ratio") +] + +schema={cv.GenerateID(): cv.use_id(tw7100)} +for name,icon in selects: + schema.update({cv.Optional(name): select.select_schema(tw7100Select, icon=icon)}) + +CONFIG_SCHEMA = cv.Schema(schema) async def to_code(config): parent = await cg.get_variable(config[CONF_ID]) - if "SOURCE" in config: - select_ = await select.new_select(config["SOURCE"], options=[]) - cg.add(select_.set_cmd("SOURCE")) - cg.add(select_.set_tw7100_parent(parent)) - cg.add(parent.set_set_source(select_)) - - if "LUMINANCE" in config: - select_ = await select.new_select(config["LUMINANCE"], options=[]) - cg.add(select_.set_cmd("LUMINANCE")) - cg.add(select_.set_tw7100_parent(parent)) - cg.add(parent.set_set_luminance(select_)) + for name,icon in selects: + if name in config: + select_ = await select.new_select(config[name], options=[]) + cg.add(select_.set_cmd(name)) + cg.add(select_.set_tw7100_parent(parent)) + cg.add(getattr(parent, "set_set_{}".format(name.lower()))(select_)) diff --git a/select/tw7100_select.cpp b/select/tw7100_select.cpp index f197b9d..49413e2 100644 --- a/select/tw7100_select.cpp +++ b/select/tw7100_select.cpp @@ -25,6 +25,26 @@ void tw7100Select::setup() { traits.set_options(get_map_values(sources)); } else if (cmd_ == "LUMINANCE") { traits.set_options(get_map_values(luminance)); + } else if (cmd_ == "ASPECT") { + traits.set_options(get_map_values(aspect)); + } else if (cmd_ == "OVSCAN") { + traits.set_options(get_map_values(ovscan)); + } else if (cmd_ == "CMODE") { + traits.set_options(get_map_values(cmode)); + } else if (cmd_ == "GAMMA") { + traits.set_options(get_map_values(gamma)); + } else if (cmd_ == "IMGPRESET") { + traits.set_options(get_map_values(imgpreset)); + } else if (cmd_ == "MCFI") { + traits.set_options(get_map_values(mcfi)); + } else if (cmd_ == "CLRSPACE") { + traits.set_options(get_map_values(clrspace)); + } else if (cmd_ == "DYNRANGE") { + traits.set_options(get_map_values(dynrange)); + } else if (cmd_ == "MSEL") { + traits.set_options(get_map_values(msel)); + } else if (cmd_ == "SPEED") { + traits.set_options(get_map_values(speed)); } ESP_LOGV(TAG, "setup done"); } @@ -43,14 +63,18 @@ void tw7100Select::control(const std::string &value) { for (auto element : sources) { if (element.second == value) { param = element.first; break; } } } else if (cmd_ == "LUMINANCE") { 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; } } } - if (param.length() > 0 && state != value) { - parent_->push_cmd(cmd_, param); - ESP_LOGV("", "CMD: %s, PARAM: %s", cmd_.c_str(), param.c_str()); + if (param.length() > 0) { + if (active_index() != index_of(value)) { // only send out commands if the value actually changed + parent_->push_cmd(cmd_, param); + ESP_LOGV("", "CMD: %s, PARAM: %s", cmd_.c_str(), param.c_str()); + } } + publish_state(value); // but acknowledge everything - publish_state(value); ESP_LOGV(TAG, "control done"); }; diff --git a/select/tw7100_select.h b/select/tw7100_select.h index 8460223..80e2fbd 100644 --- a/select/tw7100_select.h +++ b/select/tw7100_select.h @@ -13,7 +13,6 @@ class tw7100Select : public select::Select, public Component { public: void setup() override; void dump_config() override; - void set_options(std::vector options) { this->traits.set_options(options); } void set_tw7100_parent(tw7100Component *parent) { this->parent_ = parent; } void set_cmd(std::string cmd) { this->cmd_ = cmd; } std::map sources = { @@ -26,6 +25,70 @@ class tw7100Select : public select::Select, public Component { {"01", "Eco"}, {"02", "Medium"} }; + std::map aspect = { + {"00", "Normal"}, + {"30", "Auto"}, + {"40", "Full"}, + {"50", "Zoom"}, + {"80", "Anamorphic"}, + {"90", "Hsqueeze"} + }; + std::map msel = { + {"00", "Black"}, + {"01", "Blue"}, + {"02", "User logo"} + }; + std::map speed = { + {"00", "9600bps"}, + {"01", "19200bps"}, + {"02", "38400bps"}, + {"03", "57600bps"} + }; + std::map mcfi = { + {"00", "Off"}, + {"01", "Low"}, + {"02", "Normal"}, + {"03", "High"} + }; + std::map clrspace = { + {"00", "Auto"}, + {"01", "BT.709"}, + {"02", "BT.2020"} + }; + std::map dynrange = { + {"00", "Auto"}, + {"01", "SDR"}, + {"20", "HDR10"}, + {"30", "HLG"} + }; + std::map imgpreset = { + {"00", "Off"}, + {"01", "Setting 1"}, + {"02", "Setting 2"}, + {"03", "Setting 3"}, + {"04", "Setting 4"}, + {"05", "Setting 5"} + }; + std::map gamma = { + {"20", "Setting 2"}, + {"21", "Setting 1"}, + {"22", "Setting 0"}, + {"23", "Setting -1"}, + {"24", "Setting -2"}, + {"F0", "Custom"} + }; + std::map cmode = { + {"06", "Dynamic"}, + {"07", "Natural"}, + {"0C", "Bright Cinema"}, + {"15", "Cinema"} + }; + std::map ovscan = { + {"00", "Off"}, + {"02", "4%"}, + {"04", "8%"}, + {"A0", "Auto"} + }; protected: void control(const std::string &value) override; diff --git a/tw7100.cpp b/tw7100.cpp index b1bbdad..7c602cc 100644 --- a/tw7100.cpp +++ b/tw7100.cpp @@ -20,18 +20,17 @@ std::vector pwr_on_query_cmds{ // Projection screen adjustment settings "VKEYSTONE?", "HKEYSTONE?", + "ASPECT?", + "LUMINANCE?", + "OVSCAN?", /* "QC?", "CORRECTMET?", - "ASPECT?", */ - "LUMINANCE?", -/* - "OVSCAN?", -*/ -// + // Source/Input/Resolution settings "SOURCE?", + // Image settings "BRIGHT?", "CONTRAST?", @@ -39,9 +38,7 @@ std::vector pwr_on_query_cmds{ "TINT?", "CTEMP?", "FCOLOR?", -/* "CMODE?", -*/ "NRS?", "MPEGNRS?", "OFFSETR?", @@ -50,25 +47,19 @@ std::vector pwr_on_query_cmds{ "GAINR?", "GAING?", "GAINB?", -/* "GAMMA?", "CSEL?", -*/ "4KENHANCE?", -/* "IMGPRESET?", -*/ "SHRF?", "SHRS?", "DERANGE?", "DESTRENGTH?", -/* "MCFI?", "CLRSPACE?", "DYNRANGE?", "HDRPQ?", "HDRHLG?", -*/ "IMGPROC?", // Sound settings @@ -79,10 +70,8 @@ std::vector pwr_on_query_cmds{ // Environment settings "HREVERSE?", "VREVERSE?", -/* "MSEL?", "SPEED?", -*/ "ILLUM?", "STANDBYCONF?", // "PRODUCT?", // produces ERR @@ -98,17 +87,27 @@ std::vector pwr_on_query_cmds{ // Information "SIGNAL?", -// "SOURCELIST?" // Parser present in git history but removed until esphome can update selects after api connections are established -// "SOURCELISTA?", // same as SOURCELIST "LOGTO?", // produces ERR // "SNO?" // Pushed on demand if sensor value is empty (e.g. after boot-up) +// "SOURCELIST?" // Parser present in git history but removed until esphome can update selects after api connections are established +// "SOURCELISTA?", // same as SOURCELIST }; void tw7100Component::setup() { static const char *const TAG = "setup()"; ESP_LOGV(TAG, "SETUP"); - source_select_->setup(); - luminance_select_->setup(); + if (source_select_ != nullptr) source_select_->setup(); + if (luminance_select_ != nullptr) luminance_select_->setup(); + if (aspect_select_ != nullptr) aspect_select_->setup(); + if (cmode_select_ != nullptr) cmode_select_->setup(); + if (gamma_select_ != nullptr) gamma_select_->setup(); + if (imgpreset_select_ != nullptr) imgpreset_select_->setup(); + if (mcfi_select_ != nullptr) mcfi_select_->setup(); + if (ovscan_select_ != nullptr) ovscan_select_->setup(); + if (clrspace_select_ != nullptr) clrspace_select_->setup(); + if (dynrange_select_ != nullptr) dynrange_select_->setup(); + if (msel_select_ != nullptr) msel_select_->setup(); + if (speed_select_ != nullptr) speed_select_->setup(); }; void tw7100Component::update() { @@ -233,6 +232,38 @@ void tw7100Component::update_sensor(std::pair data) { auto call = luminance_select_->make_call(); call.set_option(luminance_select_->luminance[value_string]); call.perform(); + } else if (cmd == "SOURCE") { + ESP_LOGV(TAG, "updating source select"); + auto call = source_select_->make_call(); + call.set_option(source_select_->sources[value_string]); + call.perform(); + } else if (cmd == "ASPECT") { + ESP_LOGV(TAG, "updating aspect select"); + if(aspect_select_->aspect.find(value_string) != aspect_select_->aspect.end()) { + auto call = aspect_select_->make_call(); + call.set_option(aspect_select_->aspect[value_string]); + call.perform(); + } else { + ESP_LOGE(TAG, "Result %s not present in options", value_string); + } + } else if (cmd == "OVSCAN") { + ESP_LOGV(TAG, "updating ovscan select"); + } else if (cmd == "CMODE") { + ESP_LOGV(TAG, "updating cmode select"); + } else if (cmd == "GAMMA") { + ESP_LOGV(TAG, "updating gamma select"); + } else if (cmd == "IMGPRESET") { + ESP_LOGV(TAG, "updating imgpreset select"); + } else if (cmd == "MCFI") { + ESP_LOGV(TAG, "updating mcfi select"); + } else if (cmd == "CLRSPACE") { + ESP_LOGV(TAG, "updating clrspace select"); + } else if (cmd == "DYNRANGE") { + ESP_LOGV(TAG, "updating dynrange select"); + } else if (cmd == "MSEL") { + ESP_LOGV(TAG, "updating msel select"); + } else if (cmd == "SPEED") { + ESP_LOGV(TAG, "updating speed select"); } else if (cmd == "SNO") { serial_->publish_state(value_string); } else if (cmd == "BTAUDIO") { @@ -277,11 +308,6 @@ void tw7100Component::update_sensor(std::pair data) { ESP_LOGV(TAG, "updating logto switch"); int value = std::stoi(value_string); logto_switch_->publish_state(value == 1); - } else if (cmd == "SOURCE") { - ESP_LOGV(TAG, "updating source select"); - auto call = source_select_->make_call(); - call.set_option(source_select_->sources[value_string]); - call.perform(); } else if (cmd == "MUTE") { ESP_LOGV(TAG, "updating mute switch with value %s", value_string.c_str()); mute_switch_->publish_state(value_string == "ON"); @@ -300,7 +326,7 @@ void tw7100Component::update_sensor(std::pair data) { } else if (cmd == "BRIGHT") { int value = std::stoi(value_string); ESP_LOGV(TAG, "updating brightness number with value %s", value_string.c_str()); - brightness_number_->publish_state(value); + if (brightness_number_ != nullptr) brightness_number_->publish_state(value); } else if (cmd == "CONTRAST") { int value = std::stoi(value_string); ESP_LOGV(TAG, "updating contrast number with value %s", value_string.c_str()); @@ -325,9 +351,9 @@ void tw7100Component::update_sensor(std::pair data) { int value = std::stoi(value_string); ESP_LOGV(TAG, "updating nrs number with value %s", value_string.c_str()); nrs_number_->publish_state(value); - } else if (cmd == "MPRGNRS") { + } else if (cmd == "MPEGNRS") { int value = std::stoi(value_string); - ESP_LOGV(TAG, "updating mprgngs number with value %s", value_string.c_str()); + ESP_LOGV(TAG, "updating mpegngs number with value %s", value_string.c_str()); mpegnrs_number_->publish_state(value); } else if (cmd == "OFFSETR") { int value = std::stoi(value_string); diff --git a/tw7100.h b/tw7100.h index 7c35d64..b94455a 100644 --- a/tw7100.h +++ b/tw7100.h @@ -56,8 +56,18 @@ class tw7100Component : public PollingComponent, public uart::UARTDevice { void set_set_imgproc(switch_::Switch *switch_) { this->img_processing_switch_ = switch_; } void set_set_4kenhance(switch_::Switch *switch_) { this->_4kenhance_switch_ = switch_; } void set_set_logto(switch_::Switch *switch_) { this->logto_switch_ = switch_; } - void set_set_source(tw7100::tw7100Select *source_) { this->source_select_ = source_; } - void set_set_luminance(tw7100::tw7100Select *luminance_) { this->luminance_select_ = luminance_; } + void set_set_source(tw7100::tw7100Select *select_) { this->source_select_ = select_; } + void set_set_luminance(tw7100::tw7100Select *select_) { this->luminance_select_ = select_; } + void set_set_aspect(tw7100::tw7100Select *select_) { this->aspect_select_ = select_; } + void set_set_ovscan(tw7100::tw7100Select *select_) { this->ovscan_select_ = select_; } + void set_set_cmode(tw7100::tw7100Select *select_) { this->cmode_select_ = select_; } + void set_set_gamma(tw7100::tw7100Select *select_) { this->gamma_select_ = select_; } + void set_set_imgpreset(tw7100::tw7100Select *select_) { this->imgpreset_select_ = select_; } + void set_set_mcfi(tw7100::tw7100Select *select_) { this->mcfi_select_ = select_; } + void set_set_clrspace(tw7100::tw7100Select *select_) { this->clrspace_select_ = select_; } + void set_set_dynrange(tw7100::tw7100Select *select_) { this->dynrange_select_ = select_; } + void set_set_msel(tw7100::tw7100Select *select_) { this->msel_select_ = select_; } + void set_set_speed(tw7100::tw7100Select *select_) { this->speed_select_ = select_; } void set_set_vol(tw7100::tw7100Number *number_) { this->volume_number_ = number_; } void set_set_vkeystone(tw7100::tw7100Number *number_) { this->vkeystone_number_ = number_; } void set_set_hkeystone(tw7100::tw7100Number *number_) { this->hkeystone_number_ = number_; } @@ -105,6 +115,16 @@ class tw7100Component : public PollingComponent, public uart::UARTDevice { switch_::Switch *logto_switch_{nullptr}; tw7100::tw7100Select *source_select_{nullptr}; tw7100::tw7100Select *luminance_select_{nullptr}; + tw7100::tw7100Select *aspect_select_{nullptr}; + tw7100::tw7100Select *ovscan_select_{nullptr}; + tw7100::tw7100Select *cmode_select_{nullptr}; + tw7100::tw7100Select *gamma_select_{nullptr}; + tw7100::tw7100Select *imgpreset_select_{nullptr}; + tw7100::tw7100Select *mcfi_select_{nullptr}; + tw7100::tw7100Select *clrspace_select_{nullptr}; + tw7100::tw7100Select *dynrange_select_{nullptr}; + tw7100::tw7100Select *msel_select_{nullptr}; + tw7100::tw7100Select *speed_select_{nullptr}; tw7100::tw7100Number *volume_number_{nullptr}; tw7100::tw7100Number *vkeystone_number_{nullptr}; tw7100::tw7100Number *hkeystone_number_{nullptr};