diff --git a/esphome/components/ethernet/ethernet_component.cpp b/esphome/components/ethernet/ethernet_component.cpp index 5c504214d4..275c2774c3 100644 --- a/esphome/components/ethernet/ethernet_component.cpp +++ b/esphome/components/ethernet/ethernet_component.cpp @@ -815,8 +815,10 @@ void EthernetComponent::write_phy_register_(esp_eth_mac_t *mac, PHYRegister regi ESPHL_ERROR_CHECK(err, "Select PHY Register page failed"); } - ESP_LOGD(TAG, "Writing to PHY Register Address: 0x%02" PRIX32, register_data.address); - ESP_LOGD(TAG, "Writing to PHY Register Value: 0x%04" PRIX32, register_data.value); + ESP_LOGD(TAG, + "Writing to PHY Register Address: 0x%02" PRIX32 "\n" + "Writing to PHY Register Value: 0x%04" PRIX32, + register_data.address, register_data.value); err = mac->write_phy_reg(mac, this->phy_addr_, register_data.address, register_data.value); ESPHL_ERROR_CHECK(err, "Writing PHY Register failed"); diff --git a/esphome/components/i2c/__init__.py b/esphome/components/i2c/__init__.py index 56e0c8e4ab..19efda0b49 100644 --- a/esphome/components/i2c/__init__.py +++ b/esphome/components/i2c/__init__.py @@ -250,7 +250,7 @@ async def register_i2c_device(var, config): Sets the i2c bus to use and the i2c address. - This is a coroutine, you need to await it with a 'yield' expression! + This is a coroutine, you need to await it with an 'await' expression! """ parent = await cg.get_variable(config[CONF_I2C_ID]) cg.add(var.set_i2c_bus(parent)) diff --git a/esphome/components/mhz19/mhz19.h b/esphome/components/mhz19/mhz19.h index feb67bdd82..5898bab649 100644 --- a/esphome/components/mhz19/mhz19.h +++ b/esphome/components/mhz19/mhz19.h @@ -52,45 +52,26 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice { MHZ19DetectionRange detection_range_{MHZ19_DETECTION_RANGE_DEFAULT}; }; -template class MHZ19CalibrateZeroAction : public Action { +template class MHZ19CalibrateZeroAction : public Action, public Parented { public: - MHZ19CalibrateZeroAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} - - void play(const Ts &...x) override { this->mhz19_->calibrate_zero(); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->calibrate_zero(); } }; -template class MHZ19ABCEnableAction : public Action { +template class MHZ19ABCEnableAction : public Action, public Parented { public: - MHZ19ABCEnableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} - - void play(const Ts &...x) override { this->mhz19_->abc_enable(); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->abc_enable(); } }; -template class MHZ19ABCDisableAction : public Action { +template class MHZ19ABCDisableAction : public Action, public Parented { public: - MHZ19ABCDisableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} - - void play(const Ts &...x) override { this->mhz19_->abc_disable(); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->abc_disable(); } }; -template class MHZ19DetectionRangeSetAction : public Action { +template class MHZ19DetectionRangeSetAction : public Action, public Parented { public: - MHZ19DetectionRangeSetAction(MHZ19Component *mhz19) : mhz19_(mhz19) {} TEMPLATABLE_VALUE(MHZ19DetectionRange, detection_range) - void play(const Ts &...x) override { this->mhz19_->range_set(this->detection_range_.value(x...)); } - - protected: - MHZ19Component *mhz19_; + void play(const Ts &...x) override { this->parent_->range_set(this->detection_range_.value(x...)); } }; } // namespace mhz19 diff --git a/esphome/components/mhz19/sensor.py b/esphome/components/mhz19/sensor.py index 0156ee4be0..1f698be404 100644 --- a/esphome/components/mhz19/sensor.py +++ b/esphome/components/mhz19/sensor.py @@ -24,12 +24,18 @@ CONF_DETECTION_RANGE = "detection_range" mhz19_ns = cg.esphome_ns.namespace("mhz19") MHZ19Component = mhz19_ns.class_("MHZ19Component", cg.PollingComponent, uart.UARTDevice) MHZ19CalibrateZeroAction = mhz19_ns.class_( - "MHZ19CalibrateZeroAction", automation.Action + "MHZ19CalibrateZeroAction", automation.Action, cg.Parented.template(MHZ19Component) +) +MHZ19ABCEnableAction = mhz19_ns.class_( + "MHZ19ABCEnableAction", automation.Action, cg.Parented.template(MHZ19Component) +) +MHZ19ABCDisableAction = mhz19_ns.class_( + "MHZ19ABCDisableAction", automation.Action, cg.Parented.template(MHZ19Component) ) -MHZ19ABCEnableAction = mhz19_ns.class_("MHZ19ABCEnableAction", automation.Action) -MHZ19ABCDisableAction = mhz19_ns.class_("MHZ19ABCDisableAction", automation.Action) MHZ19DetectionRangeSetAction = mhz19_ns.class_( - "MHZ19DetectionRangeSetAction", automation.Action + "MHZ19DetectionRangeSetAction", + automation.Action, + cg.Parented.template(MHZ19Component), ) mhz19_detection_range = mhz19_ns.enum("MHZ19DetectionRange") @@ -98,7 +104,7 @@ async def to_code(config): cg.add(var.set_detection_range(config[CONF_DETECTION_RANGE])) -CALIBRATION_ACTION_SCHEMA = maybe_simple_id( +NO_ARGS_ACTION_SCHEMA = maybe_simple_id( { cv.Required(CONF_ID): cv.use_id(MHZ19Component), } @@ -106,17 +112,18 @@ CALIBRATION_ACTION_SCHEMA = maybe_simple_id( @automation.register_action( - "mhz19.calibrate_zero", MHZ19CalibrateZeroAction, CALIBRATION_ACTION_SCHEMA + "mhz19.calibrate_zero", MHZ19CalibrateZeroAction, NO_ARGS_ACTION_SCHEMA ) @automation.register_action( - "mhz19.abc_enable", MHZ19ABCEnableAction, CALIBRATION_ACTION_SCHEMA + "mhz19.abc_enable", MHZ19ABCEnableAction, NO_ARGS_ACTION_SCHEMA ) @automation.register_action( - "mhz19.abc_disable", MHZ19ABCDisableAction, CALIBRATION_ACTION_SCHEMA + "mhz19.abc_disable", MHZ19ABCDisableAction, NO_ARGS_ACTION_SCHEMA ) -async def mhz19_calibration_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_ID]) - return cg.new_Pvariable(action_id, template_arg, paren) +async def mhz19_no_args_action_to_code(config, action_id, template_arg, args): + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) + return var RANGE_ACTION_SCHEMA = maybe_simple_id( @@ -133,8 +140,8 @@ RANGE_ACTION_SCHEMA = maybe_simple_id( "mhz19.detection_range_set", MHZ19DetectionRangeSetAction, RANGE_ACTION_SCHEMA ) async def mhz19_detection_range_set_to_code(config, action_id, template_arg, args): - paren = await cg.get_variable(config[CONF_ID]) - var = cg.new_Pvariable(action_id, template_arg, paren) + var = cg.new_Pvariable(action_id, template_arg) + await cg.register_parented(var, config[CONF_ID]) detection_range = config.get(CONF_DETECTION_RANGE) template_ = await cg.templatable(detection_range, args, mhz19_detection_range) cg.add(var.set_detection_range(template_)) diff --git a/esphome/components/one_wire/__init__.py b/esphome/components/one_wire/__init__.py index e12cca3e27..9173b7014b 100644 --- a/esphome/components/one_wire/__init__.py +++ b/esphome/components/one_wire/__init__.py @@ -32,7 +32,7 @@ async def register_one_wire_device(var, config): Sets the 1-wire bus to use and the 1-wire address. - This is a coroutine, you need to await it with a 'yield' expression! + This is a coroutine, you need to await it with an 'await' expression! """ parent = await cg.get_variable(config[CONF_ONE_WIRE_ID]) cg.add(var.set_one_wire_bus(parent)) diff --git a/esphome/components/uart/__init__.py b/esphome/components/uart/__init__.py index 9e8917419d..31e37a06e0 100644 --- a/esphome/components/uart/__init__.py +++ b/esphome/components/uart/__init__.py @@ -504,7 +504,7 @@ def final_validate_device_schema( async def register_uart_device(var, config): """Register a UART device, setting up all the internal values. - This is a coroutine, you need to await it with a 'yield' expression! + This is a coroutine, you need to await it with an 'await' expression! """ parent = await cg.get_variable(config[CONF_UART_ID]) cg.add(var.set_uart_parent(parent)) diff --git a/esphome/components/wts01/wts01.cpp b/esphome/components/wts01/wts01.cpp index cb910d89cf..a7948c805a 100644 --- a/esphome/components/wts01/wts01.cpp +++ b/esphome/components/wts01/wts01.cpp @@ -71,17 +71,20 @@ void WTS01Sensor::process_packet_() { } // Extract temperature value - int8_t temp = this->buffer_[6]; - int32_t sign = 1; + const uint8_t raw = this->buffer_[6]; - // Handle negative temperatures - if (temp < 0) { - sign = -1; + // WTS01 encodes sign in bit 7, magnitude in bits 0-6 + const bool negative = (raw & 0x80) != 0; + const uint8_t magnitude = raw & 0x7F; + + const float decimal = static_cast(this->buffer_[7]) / 100.0f; + + float temperature = static_cast(magnitude) + decimal; + + if (negative) { + temperature = -temperature; } - // Calculate temperature (temp + decimal/100) - float temperature = static_cast(temp) + (sign * static_cast(this->buffer_[7]) / 100.0f); - ESP_LOGV(TAG, "Received new temperature: %.2f°C", temperature); this->publish_state(temperature); diff --git a/esphome/cpp_generator.py b/esphome/cpp_generator.py index ddccb574e4..cff0748c95 100644 --- a/esphome/cpp_generator.py +++ b/esphome/cpp_generator.py @@ -643,7 +643,7 @@ async def get_variable(id_: ID) -> "MockObj": Wait for the given ID to be defined in the code generation and return it as a MockObj. - This is a coroutine, you need to await it with a 'await' expression! + This is a coroutine, you need to await it with an 'await' expression! :param id_: The ID to retrieve :return: The variable as a MockObj. @@ -656,7 +656,7 @@ async def get_variable_with_full_id(id_: ID) -> tuple[ID, "MockObj"]: Wait for the given ID to be defined in the code generation and return it as a MockObj. - This is a coroutine, you need to await it with a 'await' expression! + This is a coroutine, you need to await it with an 'await' expression! :param id_: The ID to retrieve :return: The variable as a MockObj. diff --git a/requirements.txt b/requirements.txt index 833ccbb0ed..bada581f56 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,13 @@ ruamel.yaml==0.19.1 # dashboard_import ruamel.yaml.clib==0.2.15 # dashboard_import esphome-glyphsets==0.2.0 pillow==11.3.0 -cairosvg==2.8.2 + +# pycairo fork for Windows +cairosvg @ git+https://github.com/clydebarrow/cairosvg.git@release ; sys_platform == 'win32' + +# Original for everything else +cairosvg==2.8.2 ; sys_platform != 'win32' + freetype-py==2.5.1 jinja2==3.1.6 bleak==2.1.1