mirror of
https://github.com/esphome/esphome.git
synced 2025-08-03 00:47:47 +00:00
Merge remote-tracking branch 'kahrendt/json-bump-library' into integration
This commit is contained in:
commit
cf9130f906
@ -83,8 +83,7 @@ void HttpRequestUpdate::update_task(void *params) {
|
||||
container.reset(); // Release ownership of the container's shared_ptr
|
||||
|
||||
valid = json::parse_json(response, [this_update](JsonObject root) -> bool {
|
||||
if (!root["name"].is<const char *>() || !root["version"].is<const char *>() ||
|
||||
!root["builds"].is<const char *>()) {
|
||||
if (!root["name"].is<const char *>() || !root["version"].is<const char *>() || !root["builds"].is<JsonArray>()) {
|
||||
ESP_LOGE(TAG, "Manifest does not contain required fields");
|
||||
return false;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "json_util.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
#include <ArduinoJson/Memory/Allocator.hpp>
|
||||
// ArduinoJson::Allocator is included via ArduinoJson.h in json_util.h
|
||||
|
||||
namespace esphome {
|
||||
namespace json {
|
||||
@ -13,7 +13,12 @@ struct SpiRamAllocator : ArduinoJson::Allocator {
|
||||
void *allocate(size_t size) override { return this->allocator_.allocate(size); }
|
||||
|
||||
void deallocate(void *pointer) override {
|
||||
// RAMAllocator requires passing the size of the allocated space which don't know, so use free directly
|
||||
// ArduinoJson's Allocator interface doesn't provide the size parameter in deallocate.
|
||||
// RAMAllocator::deallocate() requires the size, which we don't have access to here.
|
||||
// RAMAllocator::deallocate implementation just calls free() regardless of whether
|
||||
// the memory was allocated with heap_caps_malloc or malloc.
|
||||
// This is safe because ESP-IDF's heap implementation internally tracks the memory region
|
||||
// and routes free() to the appropriate heap.
|
||||
free(pointer); // NOLINT(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc)
|
||||
}
|
||||
|
||||
@ -26,18 +31,15 @@ struct SpiRamAllocator : ArduinoJson::Allocator {
|
||||
};
|
||||
|
||||
std::string build_json(const json_build_t &f) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
auto doc_allocator = SpiRamAllocator();
|
||||
JsonDocument json_document(&doc_allocator);
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
if (json_document.overflowed()) {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
||||
return "{}";
|
||||
}
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
JsonObject root = json_document.to<JsonObject>();
|
||||
f(root);
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
if (json_document.overflowed()) {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
||||
return "{}";
|
||||
@ -45,18 +47,17 @@ std::string build_json(const json_build_t &f) {
|
||||
std::string output;
|
||||
serializeJson(json_document, output);
|
||||
return output;
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
bool parse_json(const std::string &data, const json_parse_t &f) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
auto doc_allocator = SpiRamAllocator();
|
||||
JsonDocument json_document(&doc_allocator);
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
if (json_document.overflowed()) {
|
||||
ESP_LOGE(TAG, "Could not allocate memory for JSON document!");
|
||||
return false;
|
||||
}
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
DeserializationError err = deserializeJson(json_document, data);
|
||||
|
||||
JsonObject root = json_document.as<JsonObject>();
|
||||
@ -69,6 +70,7 @@ bool parse_json(const std::string &data, const json_parse_t &f) {
|
||||
}
|
||||
ESP_LOGE(TAG, "Parse error: %s", err.c_str());
|
||||
return false;
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
@ -31,10 +31,12 @@ void MQTTButtonComponent::dump_config() {
|
||||
}
|
||||
|
||||
void MQTTButtonComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
config.state_topic = false;
|
||||
if (!this->button_->get_device_class().empty())
|
||||
if (!this->button_->get_device_class().empty()) {
|
||||
root[MQTT_DEVICE_CLASS] = this->button_->get_device_class();
|
||||
}
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
std::string MQTTButtonComponent::component_type() const { return "button"; }
|
||||
|
@ -92,10 +92,10 @@ void MQTTClientComponent::send_device_info_() {
|
||||
std::string topic = "esphome/discover/";
|
||||
topic.append(App.get_name());
|
||||
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
this->publish_json(
|
||||
topic,
|
||||
[](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
uint8_t index = 0;
|
||||
for (auto &ip : network::get_ip_addresses()) {
|
||||
if (ip.is_set()) {
|
||||
@ -148,6 +148,7 @@ void MQTTClientComponent::send_device_info_() {
|
||||
#endif
|
||||
},
|
||||
2, this->discovery_info_.retain);
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
void MQTTClientComponent::dump_config() {
|
||||
|
@ -14,7 +14,7 @@ static const char *const TAG = "mqtt.climate";
|
||||
using namespace esphome::climate;
|
||||
|
||||
void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
auto traits = this->device_->get_traits();
|
||||
// current_temperature_topic
|
||||
if (traits.get_supports_current_temperature()) {
|
||||
@ -29,7 +29,6 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
|
||||
// mode_state_topic
|
||||
root[MQTT_MODE_STATE_TOPIC] = this->get_mode_state_topic();
|
||||
// modes
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
JsonArray modes = root[MQTT_MODES].to<JsonArray>();
|
||||
// sort array for nice UI in HA
|
||||
if (traits.supports_mode(CLIMATE_MODE_AUTO))
|
||||
@ -165,6 +164,7 @@ void MQTTClimateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCo
|
||||
|
||||
config.state_topic = false;
|
||||
config.command_topic = false;
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
void MQTTClimateComponent::setup() {
|
||||
auto traits = this->device_->get_traits();
|
||||
|
@ -70,10 +70,10 @@ bool MQTTComponent::send_discovery_() {
|
||||
|
||||
ESP_LOGV(TAG, "'%s': Sending discovery", this->friendly_name().c_str());
|
||||
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
return global_mqtt_client->publish_json(
|
||||
this->get_discovery_topic_(discovery_info),
|
||||
[this](JsonObject root) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
SendDiscoveryConfig config;
|
||||
config.state_topic = true;
|
||||
config.command_topic = true;
|
||||
@ -189,11 +189,11 @@ bool MQTTComponent::send_discovery_() {
|
||||
device_info[MQTT_DEVICE_SUGGESTED_AREA] = node_area;
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
device_info[MQTT_DEVICE_CONNECTIONS][0][0] = "mac";
|
||||
device_info[MQTT_DEVICE_CONNECTIONS][0][1] = mac;
|
||||
},
|
||||
this->qos_, discovery_info.retain);
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
|
||||
uint8_t MQTTComponent::get_qos() const { return this->qos_; }
|
||||
|
@ -26,7 +26,7 @@ void MQTTDateComponent::setup() {
|
||||
if (root["month"].is<uint8_t>()) {
|
||||
call.set_month(root["month"]);
|
||||
}
|
||||
if (root["day"].is<uint16_t>()) {
|
||||
if (root["day"].is<uint8_t>()) {
|
||||
call.set_day(root["day"]);
|
||||
}
|
||||
call.perform();
|
||||
|
@ -29,13 +29,13 @@ void MQTTDateTimeComponent::setup() {
|
||||
if (root["day"].is<uint8_t>()) {
|
||||
call.set_day(root["day"]);
|
||||
}
|
||||
if (root["hour"].is<uint16_t>()) {
|
||||
if (root["hour"].is<uint8_t>()) {
|
||||
call.set_hour(root["hour"]);
|
||||
}
|
||||
if (root["minute"].is<uint16_t>()) {
|
||||
if (root["minute"].is<uint8_t>()) {
|
||||
call.set_minute(root["minute"]);
|
||||
}
|
||||
if (root["second"].is<uint16_t>()) {
|
||||
if (root["second"].is<uint8_t>()) {
|
||||
call.set_second(root["second"]);
|
||||
}
|
||||
call.perform();
|
||||
|
@ -45,6 +45,7 @@ void MQTTJSONLightComponent::send_discovery(JsonObject root, mqtt::SendDiscovery
|
||||
auto traits = this->state_->get_traits();
|
||||
|
||||
root[MQTT_COLOR_MODE] = true;
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
JsonArray color_modes = root["supported_color_modes"].to<JsonArray>();
|
||||
if (traits.supports_color_mode(ColorMode::ON_OFF))
|
||||
color_modes.add("onoff");
|
||||
|
@ -38,9 +38,9 @@ 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) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
const auto &traits = number_->traits;
|
||||
// https://www.home-assistant.io/integrations/number.mqtt/
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
root[MQTT_MIN] = traits.get_min_value();
|
||||
root[MQTT_MAX] = traits.get_max_value();
|
||||
root[MQTT_STEP] = traits.get_step();
|
||||
|
@ -33,9 +33,9 @@ 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) {
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
const auto &traits = select_->traits;
|
||||
// https://www.home-assistant.io/integrations/select.mqtt/
|
||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
JsonArray options = root[MQTT_OPTIONS].to<JsonArray>();
|
||||
for (const auto &option : traits.get_options())
|
||||
options.add(option);
|
||||
|
@ -20,13 +20,13 @@ MQTTTimeComponent::MQTTTimeComponent(TimeEntity *time) : time_(time) {}
|
||||
void MQTTTimeComponent::setup() {
|
||||
this->subscribe_json(this->get_command_topic_(), [this](const std::string &topic, JsonObject root) {
|
||||
auto call = this->time_->make_call();
|
||||
if (root["hour"].is<uint16_t>()) {
|
||||
if (root["hour"].is<uint8_t>()) {
|
||||
call.set_hour(root["hour"]);
|
||||
}
|
||||
if (root["minute"].is<uint16_t>()) {
|
||||
if (root["minute"].is<uint8_t>()) {
|
||||
call.set_minute(root["minute"]);
|
||||
}
|
||||
if (root["second"].is<uint16_t>()) {
|
||||
if (root["second"].is<uint8_t>()) {
|
||||
call.set_second(root["second"]);
|
||||
}
|
||||
call.perform();
|
||||
|
@ -1322,6 +1322,7 @@ std::string WebServer::climate_all_json_generator(WebServer *web_server, void *s
|
||||
return web_server->climate_json((climate::Climate *) (source), DETAIL_ALL);
|
||||
}
|
||||
std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_config) {
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
return json::build_json([this, obj, start_config](JsonObject root) {
|
||||
set_json_id(root, obj, "climate-" + obj->get_object_id(), start_config);
|
||||
const auto traits = obj->get_traits();
|
||||
@ -1407,6 +1408,7 @@ std::string WebServer::climate_json(climate::Climate *obj, JsonDetail start_conf
|
||||
root["state"] = root["target_temperature"];
|
||||
}
|
||||
});
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1682,6 +1684,7 @@ std::string WebServer::update_all_json_generator(WebServer *web_server, void *so
|
||||
return web_server->update_json((update::UpdateEntity *) (source), DETAIL_STATE);
|
||||
}
|
||||
std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_config) {
|
||||
// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
|
||||
return json::build_json([this, obj, start_config](JsonObject root) {
|
||||
set_json_id(root, obj, "update-" + obj->get_object_id(), start_config);
|
||||
root["value"] = obj->update_info.latest_version;
|
||||
@ -1707,6 +1710,7 @@ std::string WebServer::update_json(update::UpdateEntity *obj, JsonDetail start_c
|
||||
this->add_sorting_info_(root, obj);
|
||||
}
|
||||
});
|
||||
// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user