mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	[mdns] Support templatable config options for MDNS extra services (#8606)
This commit is contained in:
		| @@ -35,8 +35,8 @@ SERVICE_SCHEMA = cv.Schema( | |||||||
|     { |     { | ||||||
|         cv.Required(CONF_SERVICE): cv.string, |         cv.Required(CONF_SERVICE): cv.string, | ||||||
|         cv.Required(CONF_PROTOCOL): cv.string, |         cv.Required(CONF_PROTOCOL): cv.string, | ||||||
|         cv.Optional(CONF_PORT, default=0): cv.Any(0, cv.port), |         cv.Optional(CONF_PORT, default=0): cv.templatable(cv.Any(0, cv.port)), | ||||||
|         cv.Optional(CONF_TXT, default={}): {cv.string: cv.string}, |         cv.Optional(CONF_TXT, default={}): {cv.string: cv.templatable(cv.string)}, | ||||||
|     } |     } | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -102,12 +102,18 @@ async def to_code(config): | |||||||
|  |  | ||||||
|     for service in config[CONF_SERVICES]: |     for service in config[CONF_SERVICES]: | ||||||
|         txt = [ |         txt = [ | ||||||
|             mdns_txt_record(txt_key, txt_value) |             cg.StructInitializer( | ||||||
|  |                 MDNSTXTRecord, | ||||||
|  |                 ("key", txt_key), | ||||||
|  |                 ("value", await cg.templatable(txt_value, [], cg.std_string)), | ||||||
|  |             ) | ||||||
|             for txt_key, txt_value in service[CONF_TXT].items() |             for txt_key, txt_value in service[CONF_TXT].items() | ||||||
|         ] |         ] | ||||||
|  |  | ||||||
|         exp = mdns_service( |         exp = mdns_service( | ||||||
|             service[CONF_SERVICE], service[CONF_PROTOCOL], service[CONF_PORT], txt |             service[CONF_SERVICE], | ||||||
|  |             service[CONF_PROTOCOL], | ||||||
|  |             await cg.templatable(service[CONF_PORT], [], cg.uint16), | ||||||
|  |             txt, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         cg.add(var.add_extra_service(exp)) |         cg.add(var.add_extra_service(exp)) | ||||||
|   | |||||||
| @@ -121,9 +121,11 @@ void MDNSComponent::dump_config() { | |||||||
|   ESP_LOGCONFIG(TAG, "  Hostname: %s", this->hostname_.c_str()); |   ESP_LOGCONFIG(TAG, "  Hostname: %s", this->hostname_.c_str()); | ||||||
|   ESP_LOGV(TAG, "  Services:"); |   ESP_LOGV(TAG, "  Services:"); | ||||||
|   for (const auto &service : this->services_) { |   for (const auto &service : this->services_) { | ||||||
|     ESP_LOGV(TAG, "  - %s, %s, %d", service.service_type.c_str(), service.proto.c_str(), service.port); |     ESP_LOGV(TAG, "  - %s, %s, %d", service.service_type.c_str(), service.proto.c_str(), | ||||||
|  |              const_cast<TemplatableValue<uint16_t> &>(service.port).value()); | ||||||
|     for (const auto &record : service.txt_records) { |     for (const auto &record : service.txt_records) { | ||||||
|       ESP_LOGV(TAG, "    TXT: %s = %s", record.key.c_str(), record.value.c_str()); |       ESP_LOGV(TAG, "    TXT: %s = %s", record.key.c_str(), | ||||||
|  |                const_cast<TemplatableValue<std::string> &>(record.value).value().c_str()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| #ifdef USE_MDNS | #ifdef USE_MDNS | ||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include "esphome/core/automation.h" | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| @@ -10,7 +11,7 @@ namespace mdns { | |||||||
|  |  | ||||||
| struct MDNSTXTRecord { | struct MDNSTXTRecord { | ||||||
|   std::string key; |   std::string key; | ||||||
|   std::string value; |   TemplatableValue<std::string> value; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct MDNSService { | struct MDNSService { | ||||||
| @@ -20,7 +21,7 @@ struct MDNSService { | |||||||
|   // second label indicating protocol _including_ underscore character prefix |   // second label indicating protocol _including_ underscore character prefix | ||||||
|   // as defined in RFC6763 Section 7, like "_tcp" or "_udp" |   // as defined in RFC6763 Section 7, like "_tcp" or "_udp" | ||||||
|   std::string proto; |   std::string proto; | ||||||
|   uint16_t port; |   TemplatableValue<uint16_t> port; | ||||||
|   std::vector<MDNSTXTRecord> txt_records; |   std::vector<MDNSTXTRecord> txt_records; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,11 +31,12 @@ void MDNSComponent::setup() { | |||||||
|       mdns_txt_item_t it{}; |       mdns_txt_item_t it{}; | ||||||
|       // dup strings to ensure the pointer is valid even after the record loop |       // dup strings to ensure the pointer is valid even after the record loop | ||||||
|       it.key = strdup(record.key.c_str()); |       it.key = strdup(record.key.c_str()); | ||||||
|       it.value = strdup(record.value.c_str()); |       it.value = strdup(const_cast<TemplatableValue<std::string> &>(record.value).value().c_str()); | ||||||
|       txt_records.push_back(it); |       txt_records.push_back(it); | ||||||
|     } |     } | ||||||
|     err = mdns_service_add(nullptr, service.service_type.c_str(), service.proto.c_str(), service.port, |     uint16_t port = const_cast<TemplatableValue<uint16_t> &>(service.port).value(); | ||||||
|                            txt_records.data(), txt_records.size()); |     err = mdns_service_add(nullptr, service.service_type.c_str(), service.proto.c_str(), port, txt_records.data(), | ||||||
|  |                            txt_records.size()); | ||||||
|  |  | ||||||
|     // free records |     // free records | ||||||
|     for (const auto &it : txt_records) { |     for (const auto &it : txt_records) { | ||||||
|   | |||||||
| @@ -29,9 +29,11 @@ void MDNSComponent::setup() { | |||||||
|     while (*service_type == '_') { |     while (*service_type == '_') { | ||||||
|       service_type++; |       service_type++; | ||||||
|     } |     } | ||||||
|     MDNS.addService(service_type, proto, service.port); |     uint16_t port = const_cast<TemplatableValue<uint16_t> &>(service.port).value(); | ||||||
|  |     MDNS.addService(service_type, proto, port); | ||||||
|     for (const auto &record : service.txt_records) { |     for (const auto &record : service.txt_records) { | ||||||
|       MDNS.addServiceTxt(service_type, proto, record.key.c_str(), record.value.c_str()); |       MDNS.addServiceTxt(service_type, proto, record.key.c_str(), | ||||||
|  |                          const_cast<TemplatableValue<std::string> &>(record.value).value().c_str()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,9 +29,11 @@ void MDNSComponent::setup() { | |||||||
|     while (*service_type == '_') { |     while (*service_type == '_') { | ||||||
|       service_type++; |       service_type++; | ||||||
|     } |     } | ||||||
|     MDNS.addService(service_type, proto, service.port); |     uint16_t port_ = const_cast<TemplatableValue<uint16_t> &>(service.port).value(); | ||||||
|  |     MDNS.addService(service_type, proto, port_); | ||||||
|     for (const auto &record : service.txt_records) { |     for (const auto &record : service.txt_records) { | ||||||
|       MDNS.addServiceTxt(service_type, proto, record.key.c_str(), record.value.c_str()); |       MDNS.addServiceTxt(service_type, proto, record.key.c_str(), | ||||||
|  |                          const_cast<TemplatableValue<std::string> &>(record.value).value().c_str()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,9 +29,11 @@ void MDNSComponent::setup() { | |||||||
|     while (*service_type == '_') { |     while (*service_type == '_') { | ||||||
|       service_type++; |       service_type++; | ||||||
|     } |     } | ||||||
|     MDNS.addService(service_type, proto, service.port); |     uint16_t port = const_cast<TemplatableValue<uint16_t> &>(service.port).value(); | ||||||
|  |     MDNS.addService(service_type, proto, port); | ||||||
|     for (const auto &record : service.txt_records) { |     for (const auto &record : service.txt_records) { | ||||||
|       MDNS.addServiceTxt(service_type, proto, record.key.c_str(), record.value.c_str()); |       MDNS.addServiceTxt(service_type, proto, record.key.c_str(), | ||||||
|  |                          const_cast<TemplatableValue<std::string> &>(record.value).value().c_str()); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,10 +1,11 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <vector> |  | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
| #include "esphome/core/helpers.h" |  | ||||||
| #include "esphome/core/defines.h" | #include "esphome/core/defines.h" | ||||||
|  | #include "esphome/core/helpers.h" | ||||||
| #include "esphome/core/preferences.h" | #include "esphome/core/preferences.h" | ||||||
|  | #include <utility> | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
|  |  | ||||||
| @@ -27,7 +28,7 @@ template<typename T, typename... X> class TemplatableValue { | |||||||
|   TemplatableValue() : type_(NONE) {} |   TemplatableValue() : type_(NONE) {} | ||||||
|  |  | ||||||
|   template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0> |   template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0> | ||||||
|   TemplatableValue(F value) : type_(VALUE), value_(value) {} |   TemplatableValue(F value) : type_(VALUE), value_(std::move(value)) {} | ||||||
|  |  | ||||||
|   template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0> |   template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0> | ||||||
|   TemplatableValue(F f) : type_(LAMBDA), f_(f) {} |   TemplatableValue(F f) : type_(LAMBDA), f_(f) {} | ||||||
|   | |||||||
| @@ -4,3 +4,10 @@ wifi: | |||||||
|  |  | ||||||
| mdns: | mdns: | ||||||
|   disabled: false |   disabled: false | ||||||
|  |   services: | ||||||
|  |     - service: _test_service | ||||||
|  |       protocol: _tcp | ||||||
|  |       port: 8888 | ||||||
|  |       txt: | ||||||
|  |         static_string: Anything | ||||||
|  |         templated_string: !lambda return "Something else"; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user