Add next_url to improv serial component config (#4343)

This commit is contained in:
Jesse Hills 2023-01-25 14:37:01 +13:00 committed by GitHub
parent 4aac76c549
commit 79040c116d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 111 additions and 7 deletions

View file

@ -107,6 +107,7 @@ esphome/components/hte501/* @Stock-M
esphome/components/hydreon_rgxx/* @functionpointer
esphome/components/i2c/* @esphome/core
esphome/components/i2s_audio/* @jesserockz
esphome/components/improv_base/* @esphome/core
esphome/components/improv_serial/* @esphome/core
esphome/components/ina260/* @MrEditor97
esphome/components/inkbird_ibsth1_mini/* @fkirill

View file

@ -0,0 +1,42 @@
import re
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import __version__
CODEOWNERS = ["@esphome/core"]
CONF_NEXT_URL = "next_url"
VALID_SUBSTITUTIONS = ["esphome_version", "ip_address", "device_name"]
def validate_next_url(value):
value = cv.url(value)
test = r"{{(?!" + r"\b|".join(VALID_SUBSTITUTIONS) + r"\b)(\w+)}}"
result = re.search(test, value)
if result:
raise cv.Invalid(
f"Invalid substitution(s) ({', '.join(result.groups())}) in next_url. Valid substitutions are: {', '.join(VALID_SUBSTITUTIONS)}"
)
return value
IMPROV_SCHEMA = cv.Schema(
{
cv.Optional(CONF_NEXT_URL): validate_next_url,
}
)
def _process_next_url(url: str):
if "{{esphome_version}}" in url:
url = url.replace("{{esphome_version}}", __version__)
return url
async def setup_improv_core(var, config):
if CONF_NEXT_URL in config:
cg.add(var.set_next_url(_process_next_url(config[CONF_NEXT_URL])))
cg.add_library("esphome/Improv", "1.2.3")

View file

@ -0,0 +1,32 @@
#include "improv_base.h"
#include "esphome/components/network/util.h"
#include "esphome/core/application.h"
namespace esphome {
namespace improv_base {
std::string ImprovBase::get_formatted_next_url_() {
if (this->next_url_.empty()) {
return "";
}
std::string copy = this->next_url_;
// Device name
std::size_t pos = this->next_url_.find("{{device_name}}");
if (pos != std::string::npos) {
const std::string &device_name = App.get_name();
copy.replace(pos, 15, device_name);
}
// Ip address
pos = this->next_url_.find("{{ip_address}}");
if (pos != std::string::npos) {
std::string ip = network::IPAddress(network::get_ip_address()).str();
copy.replace(pos, 14, ip);
}
return copy;
}
} // namespace improv_base
} // namespace esphome

View file

@ -0,0 +1,18 @@
#pragma once
#include <string>
namespace esphome {
namespace improv_base {
class ImprovBase {
public:
void set_next_url(const std::string &next_url) { this->next_url_ = next_url; }
protected:
std::string get_formatted_next_url_();
std::string next_url_;
};
} // namespace improv_base
} // namespace esphome

View file

@ -4,7 +4,9 @@ import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.core import CORE
import esphome.final_validate as fv
from esphome.components import improv_base
AUTO_LOAD = ["improv_base"]
CODEOWNERS = ["@esphome/core"]
DEPENDENCIES = ["logger", "wifi"]
@ -12,11 +14,15 @@ improv_serial_ns = cg.esphome_ns.namespace("improv_serial")
ImprovSerialComponent = improv_serial_ns.class_("ImprovSerialComponent", cg.Component)
CONFIG_SCHEMA = cv.Schema(
{
cv.GenerateID(): cv.declare_id(ImprovSerialComponent),
}
).extend(cv.COMPONENT_SCHEMA)
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(ImprovSerialComponent),
}
)
.extend(improv_base.IMPROV_SCHEMA)
.extend(cv.COMPONENT_SCHEMA)
)
def validate_logger(config):
@ -37,4 +43,4 @@ FINAL_VALIDATE_SCHEMA = validate_logger
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
cg.add_library("esphome/Improv", "1.2.3")
await improv_base.setup_improv_core(var, config)

View file

@ -95,6 +95,9 @@ void ImprovSerialComponent::loop() {
std::vector<uint8_t> ImprovSerialComponent::build_rpc_settings_response_(improv::Command command) {
std::vector<std::string> urls;
if (!this->next_url_.empty()) {
urls.push_back(this->get_formatted_next_url_());
}
#ifdef USE_WEBSERVER
auto ip = wifi::global_wifi_component->wifi_sta_ip();
std::string webserver_url = "http://" + ip.str() + ":" + to_string(USE_WEBSERVER_PORT);

View file

@ -1,5 +1,6 @@
#pragma once
#include "esphome/components/improv_base/improv_base.h"
#include "esphome/components/wifi/wifi_component.h"
#include "esphome/core/component.h"
#include "esphome/core/defines.h"
@ -27,7 +28,7 @@ enum ImprovSerialType : uint8_t {
static const uint8_t IMPROV_SERIAL_VERSION = 1;
class ImprovSerialComponent : public Component {
class ImprovSerialComponent : public Component, public improv_base::ImprovBase {
public:
void setup() override;
void loop() override;

View file

@ -298,6 +298,7 @@ logger:
esp8266_store_log_strings_in_flash: true
improv_serial:
next_url: https://esphome.io/?name={{device_name}}&version={{esphome_version}}&ip={{ip_address}}
deep_sleep:
run_duration: 20s