mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	| @@ -60,6 +60,7 @@ from esphome.cpp_types import (  # noqa | ||||
|     std_ns, | ||||
|     std_shared_ptr, | ||||
|     std_string, | ||||
|     std_string_ref, | ||||
|     std_vector, | ||||
|     uint8, | ||||
|     uint16, | ||||
|   | ||||
| @@ -145,24 +145,21 @@ bool DallasTemperatureSensor::check_scratch_pad_() { | ||||
| float DallasTemperatureSensor::get_temp_c_() { | ||||
|   int16_t temp = (this->scratch_pad_[1] << 8) | this->scratch_pad_[0]; | ||||
|   if ((this->address_ & 0xff) == DALLAS_MODEL_DS18S20) { | ||||
|     if (this->scratch_pad_[7] != 0x10) | ||||
|       ESP_LOGE(TAG, "unexpected COUNT_PER_C value: %u", this->scratch_pad_[7]); | ||||
|     temp = ((temp & 0xfff7) << 3) + (0x10 - this->scratch_pad_[6]) - 4; | ||||
|   } else { | ||||
|     switch (this->resolution_) { | ||||
|       case 9: | ||||
|         temp &= 0xfff8; | ||||
|         break; | ||||
|       case 10: | ||||
|         temp &= 0xfffc; | ||||
|         break; | ||||
|       case 11: | ||||
|         temp &= 0xfffe; | ||||
|         break; | ||||
|       case 12: | ||||
|       default: | ||||
|         break; | ||||
|     } | ||||
|     return (temp >> 1) + (this->scratch_pad_[7] - this->scratch_pad_[6]) / float(this->scratch_pad_[7]) - 0.25; | ||||
|   } | ||||
|   switch (this->resolution_) { | ||||
|     case 9: | ||||
|       temp &= 0xfff8; | ||||
|       break; | ||||
|     case 10: | ||||
|       temp &= 0xfffc; | ||||
|       break; | ||||
|     case 11: | ||||
|       temp &= 0xfffe; | ||||
|       break; | ||||
|     case 12: | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
|  | ||||
|   return temp / 16.0f; | ||||
|   | ||||
| @@ -37,14 +37,18 @@ void DS1307Component::read_time() { | ||||
|     ESP_LOGW(TAG, "RTC halted, not syncing to system clock."); | ||||
|     return; | ||||
|   } | ||||
|   ESPTime rtc_time{.second = uint8_t(ds1307_.reg.second + 10 * ds1307_.reg.second_10), | ||||
|                    .minute = uint8_t(ds1307_.reg.minute + 10u * ds1307_.reg.minute_10), | ||||
|                    .hour = uint8_t(ds1307_.reg.hour + 10u * ds1307_.reg.hour_10), | ||||
|                    .day_of_week = uint8_t(ds1307_.reg.weekday), | ||||
|                    .day_of_month = uint8_t(ds1307_.reg.day + 10u * ds1307_.reg.day_10), | ||||
|                    .day_of_year = 1,  // ignored by recalc_timestamp_utc(false) | ||||
|                    .month = uint8_t(ds1307_.reg.month + 10u * ds1307_.reg.month_10), | ||||
|                    .year = uint16_t(ds1307_.reg.year + 10u * ds1307_.reg.year_10 + 2000)}; | ||||
|   ESPTime rtc_time{ | ||||
|       .second = uint8_t(ds1307_.reg.second + 10 * ds1307_.reg.second_10), | ||||
|       .minute = uint8_t(ds1307_.reg.minute + 10u * ds1307_.reg.minute_10), | ||||
|       .hour = uint8_t(ds1307_.reg.hour + 10u * ds1307_.reg.hour_10), | ||||
|       .day_of_week = uint8_t(ds1307_.reg.weekday), | ||||
|       .day_of_month = uint8_t(ds1307_.reg.day + 10u * ds1307_.reg.day_10), | ||||
|       .day_of_year = 1,  // ignored by recalc_timestamp_utc(false) | ||||
|       .month = uint8_t(ds1307_.reg.month + 10u * ds1307_.reg.month_10), | ||||
|       .year = uint16_t(ds1307_.reg.year + 10u * ds1307_.reg.year_10 + 2000), | ||||
|       .is_dst = false,  // not used | ||||
|       .timestamp = 0    // overwritten by recalc_timestamp_utc(false) | ||||
|   }; | ||||
|   rtc_time.recalc_timestamp_utc(false); | ||||
|   if (!rtc_time.is_valid()) { | ||||
|     ESP_LOGE(TAG, "Invalid RTC time, not syncing to system clock."); | ||||
|   | ||||
| @@ -1,10 +1,14 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| import esphome.final_validate as fv | ||||
| from esphome.components.ota import BASE_OTA_SCHEMA, ota_to_code, OTAComponent | ||||
| from esphome.const import ( | ||||
|     CONF_ESPHOME, | ||||
|     CONF_ID, | ||||
|     CONF_NUM_ATTEMPTS, | ||||
|     CONF_OTA, | ||||
|     CONF_PASSWORD, | ||||
|     CONF_PLATFORM, | ||||
|     CONF_PORT, | ||||
|     CONF_REBOOT_TIMEOUT, | ||||
|     CONF_SAFE_MODE, | ||||
| @@ -21,6 +25,19 @@ esphome = cg.esphome_ns.namespace("esphome") | ||||
| ESPHomeOTAComponent = esphome.class_("ESPHomeOTAComponent", OTAComponent) | ||||
|  | ||||
|  | ||||
| def ota_esphome_final_validate(config): | ||||
|     fconf = fv.full_config.get()[CONF_OTA] | ||||
|     used_ports = [] | ||||
|     for ota_conf in fconf: | ||||
|         if ota_conf.get(CONF_PLATFORM) == CONF_ESPHOME: | ||||
|             if (plat_port := ota_conf.get(CONF_PORT)) not in used_ports: | ||||
|                 used_ports.append(plat_port) | ||||
|             else: | ||||
|                 raise cv.Invalid( | ||||
|                     f"Only one instance of the {CONF_ESPHOME} {CONF_OTA} {CONF_PLATFORM} is allowed per port. Note that this error may result from OTA specified in packages" | ||||
|                 ) | ||||
|  | ||||
|  | ||||
| CONFIG_SCHEMA = ( | ||||
|     cv.Schema( | ||||
|         { | ||||
| @@ -50,6 +67,8 @@ CONFIG_SCHEMA = ( | ||||
|     .extend(cv.COMPONENT_SCHEMA) | ||||
| ) | ||||
|  | ||||
| FINAL_VALIDATE_SCHEMA = ota_esphome_final_validate | ||||
|  | ||||
|  | ||||
| @coroutine_with_priority(52.0) | ||||
| async def to_code(config): | ||||
|   | ||||
| @@ -257,7 +257,7 @@ async def http_request_action_to_code(config, action_id, template_arg, args): | ||||
|             trigger, | ||||
|             [ | ||||
|                 (cg.std_shared_ptr.template(HttpContainer), "response"), | ||||
|                 (cg.std_string, "body"), | ||||
|                 (cg.std_string_ref, "body"), | ||||
|             ], | ||||
|             conf, | ||||
|         ) | ||||
|   | ||||
| @@ -43,10 +43,10 @@ class HttpContainer : public Parented<HttpRequestComponent> { | ||||
|   bool secure_{false}; | ||||
| }; | ||||
|  | ||||
| class HttpRequestResponseTrigger : public Trigger<std::shared_ptr<HttpContainer>, std::string> { | ||||
| class HttpRequestResponseTrigger : public Trigger<std::shared_ptr<HttpContainer>, std::string &> { | ||||
|  public: | ||||
|   void process(std::shared_ptr<HttpContainer> container, std::string response_body) { | ||||
|     this->trigger(std::move(container), std::move(response_body)); | ||||
|   void process(std::shared_ptr<HttpContainer> container, std::string &response_body) { | ||||
|     this->trigger(std::move(container), response_body); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| @@ -153,8 +153,17 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> { | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     for (auto *trigger : this->response_triggers_) { | ||||
|       trigger->process(container, response_body); | ||||
|     if (this->response_triggers_.size() == 1) { | ||||
|       // if there is only one trigger, no need to copy the response body | ||||
|       this->response_triggers_[0]->process(container, response_body); | ||||
|     } else { | ||||
|       for (auto *trigger : this->response_triggers_) { | ||||
|         // with multiple triggers, pass a copy of the response body to each | ||||
|         // one so that modifications made in one trigger are not visible to | ||||
|         // the others | ||||
|         auto response_body_copy = std::string(response_body); | ||||
|         trigger->process(container, response_body_copy); | ||||
|       } | ||||
|     } | ||||
|     container->end(); | ||||
|   } | ||||
|   | ||||
| @@ -116,7 +116,8 @@ void ModbusController::on_modbus_read_registers(uint8_t function_code, uint16_t | ||||
|         ESP_LOGD(TAG, "Matched register. Address: 0x%02X. Value type: %zu. Register count: %u. Value: %0.1f.", | ||||
|                  server_register->address, static_cast<uint8_t>(server_register->value_type), | ||||
|                  server_register->register_count, value); | ||||
|         number_to_payload(sixteen_bit_response, value, server_register->value_type); | ||||
|         std::vector<uint16_t> payload = float_to_payload(value, server_register->value_type); | ||||
|         sixteen_bit_response.insert(sixteen_bit_response.end(), payload.cbegin(), payload.cend()); | ||||
|         current_address += server_register->register_count; | ||||
|         found = true; | ||||
|         break; | ||||
|   | ||||
| @@ -15,7 +15,7 @@ void ModbusTextSensor::parse_and_publish(const std::vector<uint8_t> &data) { | ||||
|   std::ostringstream output; | ||||
|   uint8_t items_left = this->response_bytes; | ||||
|   uint8_t index = this->offset; | ||||
|   char buffer[4]; | ||||
|   char buffer[5]; | ||||
|   while ((items_left > 0) && index < data.size()) { | ||||
|     uint8_t b = data[index]; | ||||
|     switch (this->encode_) { | ||||
|   | ||||
| @@ -56,21 +56,20 @@ CONFIG_SCHEMA = cv.All( | ||||
|  | ||||
| @coroutine_with_priority(50.0) | ||||
| async def to_code(config): | ||||
|     if config[CONF_DISABLED]: | ||||
|         return | ||||
|     if not config[CONF_DISABLED]: | ||||
|         var = cg.new_Pvariable(config[CONF_ID]) | ||||
|         await cg.register_component(var, config) | ||||
|  | ||||
|     var = cg.new_Pvariable(config[CONF_ID]) | ||||
|     await cg.register_component(var, config) | ||||
|         for conf in config.get(CONF_ON_SAFE_MODE, []): | ||||
|             trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) | ||||
|             await automation.build_automation(trigger, [], conf) | ||||
|  | ||||
|     for conf in config.get(CONF_ON_SAFE_MODE, []): | ||||
|         trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) | ||||
|         await automation.build_automation(trigger, [], conf) | ||||
|         condition = var.should_enter_safe_mode( | ||||
|             config[CONF_NUM_ATTEMPTS], | ||||
|             config[CONF_REBOOT_TIMEOUT], | ||||
|             config[CONF_BOOT_IS_GOOD_AFTER], | ||||
|         ) | ||||
|         cg.add(RawExpression(f"if ({condition}) return")) | ||||
|  | ||||
|     condition = var.should_enter_safe_mode( | ||||
|         config[CONF_NUM_ATTEMPTS], | ||||
|         config[CONF_REBOOT_TIMEOUT], | ||||
|         config[CONF_BOOT_IS_GOOD_AFTER], | ||||
|     ) | ||||
|     cg.add(RawExpression(f"if ({condition}) return")) | ||||
|     CORE.data[CONF_SAFE_MODE] = {} | ||||
|     CORE.data[CONF_SAFE_MODE][KEY_PAST_SAFE_MODE] = True | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| """Constants used by esphome.""" | ||||
|  | ||||
| __version__ = "2024.6.2" | ||||
| __version__ = "2024.6.3" | ||||
|  | ||||
| ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" | ||||
| VALID_SUBSTITUTIONS_CHARACTERS = ( | ||||
|   | ||||
| @@ -10,6 +10,7 @@ int_ = global_ns.namespace("int") | ||||
| std_ns = global_ns.namespace("std") | ||||
| std_shared_ptr = std_ns.class_("shared_ptr") | ||||
| std_string = std_ns.class_("string") | ||||
| std_string_ref = std_ns.namespace("string &") | ||||
| std_vector = std_ns.class_("vector") | ||||
| uint8 = global_ns.namespace("uint8_t") | ||||
| uint16 = global_ns.namespace("uint16_t") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user