mirror of
https://github.com/esphome/esphome.git
synced 2025-07-28 14:16:40 +00:00
[mdns] Support templatable config options for MDNS extra services (#8606)
This commit is contained in:
parent
fdc4ec8a57
commit
253e3ec6f6
@ -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";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user