Upgrade ArduinoJson to 6.18.5 and migrate code (#2844)

This commit is contained in:
Jesse Hills 2022-01-01 22:31:43 +13:00 committed by GitHub
parent 23edb18d7e
commit 33f17f75a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 126 additions and 231 deletions

View file

@ -75,8 +75,7 @@ from esphome.cpp_types import ( # noqa
optional,
arduino_json_ns,
JsonObject,
JsonObjectRef,
JsonObjectConstRef,
JsonObjectConst,
Controller,
GPIOPin,
InternalGPIOPin,

View file

@ -172,7 +172,7 @@ async def http_request_action_to_code(config, action_id, template_arg, args):
if CONF_JSON in config:
json_ = config[CONF_JSON]
if isinstance(json_, Lambda):
args_ = args + [(cg.JsonObjectRef, "root")]
args_ = args + [(cg.JsonObject, "root")]
lambda_ = await cg.process_lambda(json_, args_, return_type=cg.void)
cg.add(var.set_json(lambda_))
else:

View file

@ -78,7 +78,7 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
void add_json(const char *key, TemplatableValue<std::string, Ts...> value) { this->json_.insert({key, value}); }
void set_json(std::function<void(Ts..., JsonObject &)> json_func) { this->json_func_ = json_func; }
void set_json(std::function<void(Ts..., JsonObject)> json_func) { this->json_func_ = json_func; }
void register_response_trigger(HttpRequestResponseTrigger *trigger) { this->response_triggers_.push_back(trigger); }
@ -118,17 +118,17 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
}
protected:
void encode_json_(Ts... x, JsonObject &root) {
void encode_json_(Ts... x, JsonObject root) {
for (const auto &item : this->json_) {
auto val = item.second;
root[item.first] = val.value(x...);
}
}
void encode_json_func_(Ts... x, JsonObject &root) { this->json_func_(x..., root); }
void encode_json_func_(Ts... x, JsonObject root) { this->json_func_(x..., root); }
HttpRequestComponent *parent_;
std::map<const char *, TemplatableValue<const char *, Ts...>> headers_{};
std::map<const char *, TemplatableValue<std::string, Ts...>> json_{};
std::function<void(Ts..., JsonObject &)> json_func_{nullptr};
std::function<void(Ts..., JsonObject)> json_func_{nullptr};
std::vector<HttpRequestResponseTrigger *> response_triggers_;
};

View file

@ -7,12 +7,11 @@ json_ns = cg.esphome_ns.namespace("json")
CONFIG_SCHEMA = cv.All(
cv.Schema({}),
cv.only_with_arduino,
)
@coroutine_with_priority(1.0)
async def to_code(config):
cg.add_library("ottowinter/ArduinoJson-esphomelib", "5.13.3")
cg.add_library("bblanchon/ArduinoJson", "6.18.5")
cg.add_define("USE_JSON")
cg.add_global(json_ns.using)

View file

@ -1,8 +1,10 @@
#ifdef USE_ARDUINO
#include "json_util.h"
#include "esphome/core/log.h"
#ifdef USE_ESP8266
#include <Esp.h>
#endif
namespace esphome {
namespace json {
@ -10,110 +12,49 @@ static const char *const TAG = "json";
static std::vector<char> global_json_build_buffer; // NOLINT
const char *build_json(const json_build_t &f, size_t *length) {
global_json_buffer.clear();
JsonObject &root = global_json_buffer.createObject();
std::string build_json(const json_build_t &f) {
// Here we are allocating as much heap memory as available minus 2kb to be safe
// as we can not have a true dynamic sized document.
// The excess memory is freed below with `shrinkToFit()`
#ifdef USE_ESP8266
const size_t free_heap = ESP.getMaxFreeBlockSize() - 2048; // NOLINT(readability-static-accessed-through-instance)
#elif defined(USE_ESP32)
const size_t free_heap = heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT) - 2048;
#endif
DynamicJsonDocument json_document(free_heap);
JsonObject root = json_document.to<JsonObject>();
f(root);
json_document.shrinkToFit();
// The Json buffer size gives us a good estimate for the required size.
// Usually, it's a bit larger than the actual required string size
// | JSON Buffer Size | String Size |
// Discovery | 388 | 351 |
// Discovery | 372 | 356 |
// Discovery | 336 | 311 |
// Discovery | 408 | 393 |
global_json_build_buffer.reserve(global_json_buffer.size() + 1);
size_t bytes_written = root.printTo(global_json_build_buffer.data(), global_json_build_buffer.capacity());
if (bytes_written >= global_json_build_buffer.capacity() - 1) {
global_json_build_buffer.reserve(root.measureLength() + 1);
bytes_written = root.printTo(global_json_build_buffer.data(), global_json_build_buffer.capacity());
}
*length = bytes_written;
return global_json_build_buffer.data();
std::string output;
serializeJson(json_document, output);
return output;
}
void parse_json(const std::string &data, const json_parse_t &f) {
global_json_buffer.clear();
JsonObject &root = global_json_buffer.parseObject(data);
if (!root.success()) {
void parse_json(const std::string &data, const json_parse_t &f) {
// Here we are allocating as much heap memory as available minus 2kb to be safe
// as we can not have a true dynamic sized document.
// The excess memory is freed below with `shrinkToFit()`
#ifdef USE_ESP8266
const size_t free_heap = ESP.getMaxFreeBlockSize() - 2048; // NOLINT(readability-static-accessed-through-instance)
#elif defined(USE_ESP32)
const size_t free_heap = heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT) - 2048;
#endif
DynamicJsonDocument json_document(free_heap);
DeserializationError err = deserializeJson(json_document, data);
json_document.shrinkToFit();
JsonObject root = json_document.as<JsonObject>();
if (err) {
ESP_LOGW(TAG, "Parsing JSON failed.");
return;
}
f(root);
}
std::string build_json(const json_build_t &f) {
size_t len;
const char *c_str = build_json(f, &len);
return std::string(c_str, len);
}
VectorJsonBuffer::String::String(VectorJsonBuffer *parent) : parent_(parent), start_(parent->size_) {}
void VectorJsonBuffer::String::append(char c) const {
char *last = static_cast<char *>(this->parent_->do_alloc(1));
*last = c;
}
const char *VectorJsonBuffer::String::c_str() const {
this->append('\0');
return &this->parent_->buffer_[this->start_];
}
void VectorJsonBuffer::clear() {
for (char *block : this->free_blocks_)
free(block); // NOLINT
this->size_ = 0;
this->free_blocks_.clear();
}
VectorJsonBuffer::String VectorJsonBuffer::startString() { return {this}; } // NOLINT
void *VectorJsonBuffer::alloc(size_t bytes) {
// Make sure memory addresses are aligned
uint32_t new_size = round_size_up(this->size_);
this->resize(new_size);
return this->do_alloc(bytes);
}
void *VectorJsonBuffer::do_alloc(size_t bytes) { // NOLINT
const uint32_t begin = this->size_;
this->resize(begin + bytes);
return &this->buffer_[begin];
}
void VectorJsonBuffer::resize(size_t size) { // NOLINT
if (size <= this->size_) {
this->size_ = size;
return;
}
this->reserve(size);
this->size_ = size;
}
void VectorJsonBuffer::reserve(size_t size) { // NOLINT
if (size <= this->capacity_)
return;
uint32_t target_capacity = this->capacity_;
if (this->capacity_ == 0) {
// lazily initialize with a reasonable size
target_capacity = JSON_OBJECT_SIZE(16);
}
while (target_capacity < size)
target_capacity *= 2;
char *old_buffer = this->buffer_;
this->buffer_ = new char[target_capacity]; // NOLINT
if (old_buffer != nullptr && this->capacity_ != 0) {
this->free_blocks_.push_back(old_buffer);
memcpy(this->buffer_, old_buffer, this->capacity_);
}
this->capacity_ = target_capacity;
}
size_t VectorJsonBuffer::size() const { return this->size_; }
VectorJsonBuffer global_json_buffer; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
} // namespace json
} // namespace esphome
#endif // USE_ARDUINO

View file

@ -1,68 +1,28 @@
#pragma once
#ifdef USE_ARDUINO
#include <vector>
#include "esphome/core/helpers.h"
#undef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 1 // NOLINT
#include <ArduinoJson.h>
namespace esphome {
namespace json {
/// Callback function typedef for parsing JsonObjects.
using json_parse_t = std::function<void(JsonObject &)>;
using json_parse_t = std::function<void(JsonObject)>;
/// Callback function typedef for building JsonObjects.
using json_build_t = std::function<void(JsonObject &)>;
using json_build_t = std::function<void(JsonObject)>;
/// Build a JSON string with the provided json build function.
const char *build_json(const json_build_t &f, size_t *length);
std::string build_json(const json_build_t &f);
/// Parse a JSON string and run the provided json parse function if it's valid.
void parse_json(const std::string &data, const json_parse_t &f);
class VectorJsonBuffer : public ArduinoJson::Internals::JsonBufferBase<VectorJsonBuffer> {
public:
class String {
public:
String(VectorJsonBuffer *parent);
void append(char c) const;
const char *c_str() const;
protected:
VectorJsonBuffer *parent_;
uint32_t start_;
};
void *alloc(size_t bytes) override;
size_t size() const;
void clear();
String startString(); // NOLINT
protected:
void *do_alloc(size_t bytes); // NOLINT
void resize(size_t size); // NOLINT
void reserve(size_t size); // NOLINT
char *buffer_{nullptr};
size_t size_{0};
size_t capacity_{0};
std::vector<char *> free_blocks_;
};
extern VectorJsonBuffer global_json_buffer; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
} // namespace json
} // namespace esphome
#endif // USE_ARDUINO

View file

@ -8,7 +8,7 @@ namespace light {
// See https://www.home-assistant.io/integrations/light.mqtt/#json-schema for documentation on the schema
void LightJSONSchema::dump_json(LightState &state, JsonObject &root) {
void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
if (state.supports_effects())
root["effect"] = state.get_effect_name();
@ -52,7 +52,7 @@ void LightJSONSchema::dump_json(LightState &state, JsonObject &root) {
if (values.get_color_mode() & ColorCapability::BRIGHTNESS)
root["brightness"] = uint8_t(values.get_brightness() * 255);
JsonObject &color = root.createNestedObject("color");
JsonObject color = root.createNestedObject("color");
if (values.get_color_mode() & ColorCapability::RGB) {
color["r"] = uint8_t(values.get_color_brightness() * values.get_red() * 255);
color["g"] = uint8_t(values.get_color_brightness() * values.get_green() * 255);
@ -72,7 +72,7 @@ void LightJSONSchema::dump_json(LightState &state, JsonObject &root) {
}
}
void LightJSONSchema::parse_color_json(LightState &state, LightCall &call, JsonObject &root) {
void LightJSONSchema::parse_color_json(LightState &state, LightCall &call, JsonObject root) {
if (root.containsKey("state")) {
auto val = parse_on_off(root["state"]);
switch (val) {
@ -95,7 +95,7 @@ void LightJSONSchema::parse_color_json(LightState &state, LightCall &call, JsonO
}
if (root.containsKey("color")) {
JsonObject &color = root["color"];
JsonObject color = root["color"];
// HA also encodes brightness information in the r, g, b values, so extract that and set it as color brightness.
float max_rgb = 0.0f;
if (color.containsKey("r")) {
@ -140,7 +140,7 @@ void LightJSONSchema::parse_color_json(LightState &state, LightCall &call, JsonO
}
}
void LightJSONSchema::parse_json(LightState &state, LightCall &call, JsonObject &root) {
void LightJSONSchema::parse_json(LightState &state, LightCall &call, JsonObject root) {
LightJSONSchema::parse_color_json(state, call, root);
if (root.containsKey("flash")) {

View file

@ -14,12 +14,12 @@ namespace light {
class LightJSONSchema {
public:
/// Dump the state of a light as JSON.
static void dump_json(LightState &state, JsonObject &root);
static void dump_json(LightState &state, JsonObject root);
/// Parse the JSON state of a light to a LightCall.
static void parse_json(LightState &state, LightCall &call, JsonObject &root);
static void parse_json(LightState &state, LightCall &call, JsonObject root);
protected:
static void parse_color_json(LightState &state, LightCall &call, JsonObject &root);
static void parse_color_json(LightState &state, LightCall &call, JsonObject root);
};
} // namespace light

View file

@ -80,7 +80,7 @@ MQTTMessageTrigger = mqtt_ns.class_(
"MQTTMessageTrigger", automation.Trigger.template(cg.std_string), cg.Component
)
MQTTJsonMessageTrigger = mqtt_ns.class_(
"MQTTJsonMessageTrigger", automation.Trigger.template(cg.JsonObjectConstRef)
"MQTTJsonMessageTrigger", automation.Trigger.template(cg.JsonObjectConst)
)
MQTTComponent = mqtt_ns.class_("MQTTComponent", cg.Component)
MQTTConnectedCondition = mqtt_ns.class_("MQTTConnectedCondition", Condition)
@ -311,7 +311,7 @@ async def to_code(config):
for conf in config.get(CONF_ON_JSON_MESSAGE, []):
trig = cg.new_Pvariable(conf[CONF_TRIGGER_ID], conf[CONF_TOPIC], conf[CONF_QOS])
await automation.build_automation(trig, [(cg.JsonObjectConstRef, "x")], conf)
await automation.build_automation(trig, [(cg.JsonObjectConst, "x")], conf)
MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema(
@ -363,7 +363,7 @@ async def mqtt_publish_json_action_to_code(config, action_id, template_arg, args
template_ = await cg.templatable(config[CONF_TOPIC], args, cg.std_string)
cg.add(var.set_topic(template_))
args_ = args + [(cg.JsonObjectRef, "root")]
args_ = args + [(cg.JsonObject, "root")]
lambda_ = await cg.process_lambda(config[CONF_PAYLOAD], args_, return_type=cg.void)
cg.add(var.set_payload(lambda_))
template_ = await cg.templatable(config[CONF_QOS], args, cg.uint8)

View file

@ -74,9 +74,9 @@ class CustomMQTTDevice {
* }
*
* // topic parameter can be remove if not needed:
* // e.g.: void on_json_message(JsonObject &payload) {
* // e.g.: void on_json_message(JsonObject payload) {
*
* void on_json_message(const std::string &topic, JsonObject &payload) {
* void on_json_message(const std::string &topic, JsonObject payload) {
* // do something with topic and payload
* if (payload["number"] == 1) {
* digitalWrite(5, HIGH);
@ -93,11 +93,9 @@ class CustomMQTTDevice {
* @param qos The Quality of Service to subscribe with. Defaults to 0.
*/
template<typename T>
void subscribe_json(const std::string &topic, void (T::*callback)(const std::string &, JsonObject &),
uint8_t qos = 0);
void subscribe_json(const std::string &topic, void (T::*callback)(const std::string &, JsonObject), uint8_t qos = 0);
template<typename T>
void subscribe_json(const std::string &topic, void (T::*callback)(JsonObject &), uint8_t qos = 0);
template<typename T> void subscribe_json(const std::string &topic, void (T::*callback)(JsonObject), uint8_t qos = 0);
/** Publish an MQTT message with the given payload and QoS and retain settings.
*
@ -155,7 +153,7 @@ class CustomMQTTDevice {
*
* ```cpp
* void in_some_method() {
* publish("the/topic", [=](JsonObject &root) {
* publish("the/topic", [=](JsonObject root) {
* root["the_key"] = "Hello World!";
* }, 0, false);
* }
@ -174,7 +172,7 @@ class CustomMQTTDevice {
*
* ```cpp
* void in_some_method() {
* publish("the/topic", [=](JsonObject &root) {
* publish("the/topic", [=](JsonObject root) {
* root["the_key"] = "Hello World!";
* });
* }
@ -205,13 +203,13 @@ template<typename T> void CustomMQTTDevice::subscribe(const std::string &topic,
global_mqtt_client->subscribe(topic, f, qos);
}
template<typename T>
void CustomMQTTDevice::subscribe_json(const std::string &topic, void (T::*callback)(const std::string &, JsonObject &),
void CustomMQTTDevice::subscribe_json(const std::string &topic, void (T::*callback)(const std::string &, JsonObject),
uint8_t qos) {
auto f = std::bind(callback, (T *) this, std::placeholders::_1, std::placeholders::_2);
global_mqtt_client->subscribe_json(topic, f, qos);
}
template<typename T>
void CustomMQTTDevice::subscribe_json(const std::string &topic, void (T::*callback)(JsonObject &), uint8_t qos) {
void CustomMQTTDevice::subscribe_json(const std::string &topic, void (T::*callback)(JsonObject), uint8_t qos) {
auto f = std::bind(callback, (T *) this, std::placeholders::_2);
global_mqtt_client->subscribe_json(topic, f, qos);
}

View file

@ -29,7 +29,7 @@ MQTTBinarySensorComponent::MQTTBinarySensorComponent(binary_sensor::BinarySensor
}
}
void MQTTBinarySensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTBinarySensorComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
if (!this->binary_sensor_->get_device_class().empty())
root[MQTT_DEVICE_CLASS] = this->binary_sensor_->get_device_class();
if (this->binary_sensor_->is_status_binary_sensor())

View file

@ -22,7 +22,7 @@ class MQTTBinarySensorComponent : public mqtt::MQTTComponent {
void dump_config() override;
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
void set_is_status(bool status);

View file

@ -30,7 +30,7 @@ void MQTTButtonComponent::dump_config() {
LOG_MQTT_COMPONENT(true, true);
}
void MQTTButtonComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTButtonComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
config.state_topic = false;
if (!this->button_->get_device_class().empty())
root[MQTT_DEVICE_CLASS] = this->button_->get_device_class();

View file

@ -23,7 +23,7 @@ class MQTTButtonComponent : public mqtt::MQTTComponent {
/// Buttons do not send a state so just return true.
bool send_initial_state() override { return true; }
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
protected:
/// "button" component type.

View file

@ -1,4 +1,5 @@
#include "mqtt_client.h"
#define USE_MQTT
#ifdef USE_MQTT
@ -346,7 +347,7 @@ void MQTTClientComponent::subscribe(const std::string &topic, mqtt_callback_t ca
void MQTTClientComponent::subscribe_json(const std::string &topic, const mqtt_json_callback_t &callback, uint8_t qos) {
auto f = [callback](const std::string &topic, const std::string &payload) {
json::parse_json(payload, [topic, callback](JsonObject &root) { callback(topic, root); });
json::parse_json(payload, [topic, callback](JsonObject root) { callback(topic, root); });
};
MQTTSubscription subscription{
.topic = topic,
@ -416,9 +417,8 @@ bool MQTTClientComponent::publish(const MQTTMessage &message) {
}
bool MQTTClientComponent::publish_json(const std::string &topic, const json::json_build_t &f, uint8_t qos,
bool retain) {
size_t len;
const char *message = json::build_json(f, &len);
return this->publish(topic, message, len, qos, retain);
std::string message = json::build_json(f);
return this->publish(topic, message, qos, retain);
}
/** Check if the message topic matches the given subscription topic

View file

@ -20,7 +20,7 @@ namespace mqtt {
* First parameter is the topic, the second one is the payload.
*/
using mqtt_callback_t = std::function<void(const std::string &, const std::string &)>;
using mqtt_json_callback_t = std::function<void(const std::string &, JsonObject &)>;
using mqtt_json_callback_t = std::function<void(const std::string &, JsonObject)>;
/// internal struct for MQTT messages.
struct MQTTMessage {
@ -306,11 +306,11 @@ class MQTTMessageTrigger : public Trigger<std::string>, public Component {
optional<std::string> payload_;
};
class MQTTJsonMessageTrigger : public Trigger<const JsonObject &> {
class MQTTJsonMessageTrigger : public Trigger<JsonObjectConst> {
public:
explicit MQTTJsonMessageTrigger(const std::string &topic, uint8_t qos) {
global_mqtt_client->subscribe_json(
topic, [this](const std::string &topic, JsonObject &root) { this->trigger(root); }, qos);
topic, [this](const std::string &topic, JsonObject root) { this->trigger(root); }, qos);
}
};
@ -338,7 +338,7 @@ template<typename... Ts> class MQTTPublishJsonAction : public Action<Ts...> {
TEMPLATABLE_VALUE(uint8_t, qos)
TEMPLATABLE_VALUE(bool, retain)
void set_payload(std::function<void(Ts..., JsonObject &)> payload) { this->payload_ = payload; }
void set_payload(std::function<void(Ts..., JsonObject)> payload) { this->payload_ = payload; }
void play(Ts... x) override {
auto f = std::bind(&MQTTPublishJsonAction<Ts...>::encode_, this, x..., std::placeholders::_1);
@ -349,8 +349,8 @@ template<typename... Ts> class MQTTPublishJsonAction : public Action<Ts...> {
}
protected:
void encode_(Ts... x, JsonObject &root) { this->payload_(x..., root); }
std::function<void(Ts..., JsonObject &)> payload_;
void encode_(Ts... x, JsonObject root) { this->payload_(x..., root); }
std::function<void(Ts..., JsonObject)> payload_;
MQTTClientComponent *parent_;
};

View file

@ -13,7 +13,7 @@ static const char *const TAG = "mqtt.climate";
using namespace esphome::climate;
void MQTTClimateComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
auto traits = this->device_->get_traits();
// current_temperature_topic
if (traits.get_supports_current_temperature()) {
@ -25,7 +25,7 @@ void MQTTClimateComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryC
// mode_state_topic
root[MQTT_MODE_STATE_TOPIC] = this->get_mode_state_topic();
// modes
JsonArray &modes = root.createNestedArray(MQTT_MODES);
JsonArray modes = root.createNestedArray(MQTT_MODES);
// sort array for nice UI in HA
if (traits.supports_mode(CLIMATE_MODE_AUTO))
modes.add("auto");
@ -83,7 +83,7 @@ void MQTTClimateComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryC
// fan_mode_state_topic
root[MQTT_FAN_MODE_STATE_TOPIC] = this->get_fan_mode_state_topic();
// fan_modes
JsonArray &fan_modes = root.createNestedArray("fan_modes");
JsonArray fan_modes = root.createNestedArray("fan_modes");
if (traits.supports_fan_mode(CLIMATE_FAN_ON))
fan_modes.add("on");
if (traits.supports_fan_mode(CLIMATE_FAN_OFF))
@ -112,7 +112,7 @@ void MQTTClimateComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryC
// swing_mode_state_topic
root[MQTT_SWING_MODE_STATE_TOPIC] = this->get_swing_mode_state_topic();
// swing_modes
JsonArray &swing_modes = root.createNestedArray("swing_modes");
JsonArray swing_modes = root.createNestedArray("swing_modes");
if (traits.supports_swing_mode(CLIMATE_SWING_OFF))
swing_modes.add("off");
if (traits.supports_swing_mode(CLIMATE_SWING_BOTH))

View file

@ -14,7 +14,7 @@ namespace mqtt {
class MQTTClimateComponent : public mqtt::MQTTComponent {
public:
MQTTClimateComponent(climate::Climate *device);
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
bool send_initial_state() override;
std::string component_type() const override;
void setup() override;

View file

@ -63,7 +63,7 @@ bool MQTTComponent::send_discovery_() {
return global_mqtt_client->publish_json(
this->get_discovery_topic_(discovery_info),
[this](JsonObject &root) {
[this](JsonObject root) {
SendDiscoveryConfig config;
config.state_topic = true;
config.command_topic = true;
@ -127,7 +127,7 @@ bool MQTTComponent::send_discovery_() {
}
}
JsonObject &device_info = root.createNestedObject(MQTT_DEVICE);
JsonObject device_info = root.createNestedObject(MQTT_DEVICE);
device_info[MQTT_DEVICE_IDENTIFIERS] = get_mac_address();
device_info[MQTT_DEVICE_NAME] = node_name;
device_info[MQTT_DEVICE_SW_VERSION] = "esphome v" ESPHOME_VERSION " " + App.get_compilation_time();

View file

@ -70,7 +70,7 @@ class MQTTComponent : public Component {
void call_dump_config() override;
/// Send discovery info the Home Assistant, override this.
virtual void send_discovery(JsonObject &root, SendDiscoveryConfig &config) = 0;
virtual void send_discovery(JsonObject root, SendDiscoveryConfig &config) = 0;
virtual bool send_initial_state() = 0;

View file

@ -63,7 +63,7 @@ void MQTTCoverComponent::dump_config() {
ESP_LOGCONFIG(TAG, " Tilt Command Topic: '%s'", this->get_tilt_command_topic().c_str());
}
}
void MQTTCoverComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTCoverComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
if (!this->cover_->get_device_class().empty())
root[MQTT_DEVICE_CLASS] = this->cover_->get_device_class();

View file

@ -16,7 +16,7 @@ class MQTTCoverComponent : public mqtt::MQTTComponent {
explicit MQTTCoverComponent(cover::Cover *cover);
void setup() override;
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
MQTT_COMPONENT_CUSTOM_TOPIC(position, command)
MQTT_COMPONENT_CUSTOM_TOPIC(position, state)

View file

@ -120,7 +120,7 @@ void MQTTFanComponent::dump_config() {
bool MQTTFanComponent::send_initial_state() { return this->publish_state(); }
void MQTTFanComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTFanComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
if (this->state_->get_traits().supports_oscillation()) {
root[MQTT_OSCILLATION_COMMAND_TOPIC] = this->get_oscillation_command_topic();
root[MQTT_OSCILLATION_STATE_TOPIC] = this->get_oscillation_state_topic();

View file

@ -22,7 +22,7 @@ class MQTTFanComponent : public mqtt::MQTTComponent {
MQTT_COMPONENT_CUSTOM_TOPIC(speed, command)
MQTT_COMPONENT_CUSTOM_TOPIC(speed, state)
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)

View file

@ -18,7 +18,7 @@ std::string MQTTJSONLightComponent::component_type() const { return "light"; }
const EntityBase *MQTTJSONLightComponent::get_entity() const { return this->state_; }
void MQTTJSONLightComponent::setup() {
this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject &root) {
this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject root) {
LightCall call = this->state_->make_call();
LightJSONSchema::parse_json(*this->state_, call, root);
call.perform();
@ -32,16 +32,16 @@ MQTTJSONLightComponent::MQTTJSONLightComponent(LightState *state) : MQTTComponen
bool MQTTJSONLightComponent::publish_state_() {
return this->publish_json(this->get_state_topic_(),
[this](JsonObject &root) { LightJSONSchema::dump_json(*this->state_, root); });
[this](JsonObject root) { LightJSONSchema::dump_json(*this->state_, root); });
}
LightState *MQTTJSONLightComponent::get_state() const { return this->state_; }
void MQTTJSONLightComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTJSONLightComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
root["schema"] = "json";
auto traits = this->state_->get_traits();
root[MQTT_COLOR_MODE] = true;
JsonArray &color_modes = root.createNestedArray("supported_color_modes");
JsonArray color_modes = root.createNestedArray("supported_color_modes");
if (traits.supports_color_mode(ColorMode::ON_OFF))
color_modes.add("onoff");
if (traits.supports_color_mode(ColorMode::BRIGHTNESS))
@ -66,7 +66,7 @@ void MQTTJSONLightComponent::send_discovery(JsonObject &root, mqtt::SendDiscover
if (this->state_->supports_effects()) {
root["effect"] = true;
JsonArray &effect_list = root.createNestedArray(MQTT_EFFECT_LIST);
JsonArray effect_list = root.createNestedArray(MQTT_EFFECT_LIST);
for (auto *effect : this->state_->get_effects())
effect_list.add(effect->get_name());
effect_list.add("None");

View file

@ -21,7 +21,7 @@ class MQTTJSONLightComponent : public mqtt::MQTTComponent {
void dump_config() override;
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
bool send_initial_state() override;

View file

@ -37,7 +37,7 @@ void MQTTNumberComponent::dump_config() {
std::string MQTTNumberComponent::component_type() const { return "number"; }
const EntityBase *MQTTNumberComponent::get_entity() const { return this->number_; }
void MQTTNumberComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTNumberComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
const auto &traits = number_->traits;
// https://www.home-assistant.io/integrations/number.mqtt/
root[MQTT_MIN] = traits.get_min_value();

View file

@ -25,7 +25,7 @@ class MQTTNumberComponent : public mqtt::MQTTComponent {
void setup() override;
void dump_config() override;
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
bool send_initial_state() override;

View file

@ -32,10 +32,10 @@ void MQTTSelectComponent::dump_config() {
std::string MQTTSelectComponent::component_type() const { return "select"; }
const EntityBase *MQTTSelectComponent::get_entity() const { return this->select_; }
void MQTTSelectComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTSelectComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
const auto &traits = select_->traits;
// https://www.home-assistant.io/integrations/select.mqtt/
JsonArray &options = root.createNestedArray(MQTT_OPTIONS);
JsonArray options = root.createNestedArray(MQTT_OPTIONS);
for (const auto &option : traits.get_options())
options.add(option);

View file

@ -25,7 +25,7 @@ class MQTTSelectComponent : public mqtt::MQTTComponent {
void setup() override;
void dump_config() override;
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
bool send_initial_state() override;

View file

@ -42,7 +42,7 @@ uint32_t MQTTSensorComponent::get_expire_after() const {
void MQTTSensorComponent::set_expire_after(uint32_t expire_after) { this->expire_after_ = expire_after; }
void MQTTSensorComponent::disable_expire_after() { this->expire_after_ = 0; }
void MQTTSensorComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTSensorComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
if (!this->sensor_->get_device_class().empty())
root[MQTT_DEVICE_CLASS] = this->sensor_->get_device_class();

View file

@ -27,7 +27,7 @@ class MQTTSensorComponent : public mqtt::MQTTComponent {
/// Disable Home Assistant value expiry.
void disable_expire_after();
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)

View file

@ -44,7 +44,7 @@ void MQTTSwitchComponent::dump_config() {
std::string MQTTSwitchComponent::component_type() const { return "switch"; }
const EntityBase *MQTTSwitchComponent::get_entity() const { return this->switch_; }
void MQTTSwitchComponent::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTSwitchComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
if (this->switch_->assumed_state())
root[MQTT_OPTIMISTIC] = true;
}

View file

@ -20,7 +20,7 @@ class MQTTSwitchComponent : public mqtt::MQTTComponent {
void setup() override;
void dump_config() override;
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
bool send_initial_state() override;

View file

@ -12,7 +12,7 @@ static const char *const TAG = "mqtt.text_sensor";
using namespace esphome::text_sensor;
MQTTTextSensor::MQTTTextSensor(TextSensor *sensor) : MQTTComponent(), sensor_(sensor) {}
void MQTTTextSensor::send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) {
void MQTTTextSensor::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
config.command_topic = false;
}
void MQTTTextSensor::setup() {

View file

@ -15,7 +15,7 @@ class MQTTTextSensor : public mqtt::MQTTComponent {
public:
explicit MQTTTextSensor(text_sensor::TextSensor *sensor);
void send_discovery(JsonObject &root, mqtt::SendDiscoveryConfig &config) override;
void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
void setup() override;

View file

@ -316,7 +316,7 @@ void WebServer::handle_sensor_request(AsyncWebServerRequest *request, const UrlM
request->send(404);
}
std::string WebServer::sensor_json(sensor::Sensor *obj, float value) {
return json::build_json([obj, value](JsonObject &root) {
return json::build_json([obj, value](JsonObject root) {
root["id"] = "sensor-" + obj->get_object_id();
std::string state = value_accuracy_to_string(value, obj->get_accuracy_decimals());
if (!obj->get_unit_of_measurement().empty())
@ -342,7 +342,7 @@ void WebServer::handle_text_sensor_request(AsyncWebServerRequest *request, const
request->send(404);
}
std::string WebServer::text_sensor_json(text_sensor::TextSensor *obj, const std::string &value) {
return json::build_json([obj, value](JsonObject &root) {
return json::build_json([obj, value](JsonObject root) {
root["id"] = "text_sensor-" + obj->get_object_id();
root["state"] = value;
root["value"] = value;
@ -355,7 +355,7 @@ void WebServer::on_switch_update(switch_::Switch *obj, bool state) {
this->events_.send(this->switch_json(obj, state).c_str(), "state");
}
std::string WebServer::switch_json(switch_::Switch *obj, bool value) {
return json::build_json([obj, value](JsonObject &root) {
return json::build_json([obj, value](JsonObject root) {
root["id"] = "switch-" + obj->get_object_id();
root["state"] = value ? "ON" : "OFF";
root["value"] = value;
@ -410,7 +410,7 @@ void WebServer::on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool s
this->events_.send(this->binary_sensor_json(obj, state).c_str(), "state");
}
std::string WebServer::binary_sensor_json(binary_sensor::BinarySensor *obj, bool value) {
return json::build_json([obj, value](JsonObject &root) {
return json::build_json([obj, value](JsonObject root) {
root["id"] = "binary_sensor-" + obj->get_object_id();
root["state"] = value ? "ON" : "OFF";
root["value"] = value;
@ -431,7 +431,7 @@ void WebServer::handle_binary_sensor_request(AsyncWebServerRequest *request, con
#ifdef USE_FAN
void WebServer::on_fan_update(fan::FanState *obj) { this->events_.send(this->fan_json(obj).c_str(), "state"); }
std::string WebServer::fan_json(fan::FanState *obj) {
return json::build_json([obj](JsonObject &root) {
return json::build_json([obj](JsonObject root) {
root["id"] = "fan-" + obj->get_object_id();
root["state"] = obj->state ? "ON" : "OFF";
root["value"] = obj->state;
@ -580,7 +580,7 @@ void WebServer::handle_light_request(AsyncWebServerRequest *request, const UrlMa
request->send(404);
}
std::string WebServer::light_json(light::LightState *obj) {
return json::build_json([obj](JsonObject &root) {
return json::build_json([obj](JsonObject root) {
root["id"] = "light-" + obj->get_object_id();
root["state"] = obj->remote_values.is_on() ? "ON" : "OFF";
light::LightJSONSchema::dump_json(*obj, root);
@ -632,7 +632,7 @@ void WebServer::handle_cover_request(AsyncWebServerRequest *request, const UrlMa
request->send(404);
}
std::string WebServer::cover_json(cover::Cover *obj) {
return json::build_json([obj](JsonObject &root) {
return json::build_json([obj](JsonObject root) {
root["id"] = "cover-" + obj->get_object_id();
root["state"] = obj->is_fully_closed() ? "CLOSED" : "OPEN";
root["value"] = obj->position;
@ -659,7 +659,7 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM
request->send(404);
}
std::string WebServer::number_json(number::Number *obj, float value) {
return json::build_json([obj, value](JsonObject &root) {
return json::build_json([obj, value](JsonObject root) {
root["id"] = "number-" + obj->get_object_id();
char buffer[64];
snprintf(buffer, sizeof(buffer), "%f", value);
@ -703,7 +703,7 @@ void WebServer::handle_select_request(AsyncWebServerRequest *request, const UrlM
request->send(404);
}
std::string WebServer::select_json(select::Select *obj, const std::string &value) {
return json::build_json([obj, value](JsonObject &root) {
return json::build_json([obj, value](JsonObject root) {
root["id"] = "select-" + obj->get_object_id();
root["state"] = value;
root["value"] = value;

View file

@ -27,8 +27,7 @@ Application = esphome_ns.class_("Application")
optional = esphome_ns.class_("optional")
arduino_json_ns = global_ns.namespace("ArduinoJson")
JsonObject = arduino_json_ns.class_("JsonObject")
JsonObjectRef = JsonObject.operator("ref")
JsonObjectConstRef = JsonObjectRef.operator("const")
JsonObjectConst = arduino_json_ns.class_("JsonObjectConst")
Controller = esphome_ns.class_("Controller")
GPIOPin = esphome_ns.class_("GPIOPin")
InternalGPIOPin = esphome_ns.class_("InternalGPIOPin", GPIOPin)

View file

@ -27,9 +27,10 @@ build_flags =
[common]
lib_deps =
esphome/noise-c@0.1.4 ; api
makuna/NeoPixelBus@2.6.9 ; neopixelbus
esphome/Improv@1.0.0 ; improv_serial / esp32_improv
esphome/noise-c@0.1.4 ; api
makuna/NeoPixelBus@2.6.9 ; neopixelbus
esphome/Improv@1.0.0 ; improv_serial / esp32_improv
bblanchon/ArduinoJson@6.18.5 ; json
build_flags =
-DESPHOME_LOG_LEVEL=ESPHOME_LOG_LEVEL_VERY_VERBOSE
src_filter =
@ -42,7 +43,6 @@ extends = common
lib_deps =
${common.lib_deps}
ottowinter/AsyncMqttClient-esphome@0.8.6 ; mqtt
ottowinter/ArduinoJson-esphomelib@5.13.3 ; json
esphome/ESPAsyncWebServer-esphome@2.1.0 ; web_server_base
fastled/FastLED@3.3.2 ; fastled_base
mikalhart/TinyGPSPlus@1.0.2 ; gps

View file

@ -68,8 +68,7 @@ from esphome import codegen as cg
"optional",
"arduino_json_ns",
"JsonObject",
"JsonObjectRef",
"JsonObjectConstRef",
"JsonObjectConst",
"Controller",
"GPIOPin",
),