From 59bfa79870bbd9bff761314a1fa9ec3c67ae377d Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 20 Sep 2024 15:54:28 +0200 Subject: [PATCH 01/11] Set relay1 high on speed medium On the original implementation from Sonoff, the medium speed have both relays 1 and 2 on HIGH, which makes sense, as those two have the same capacitance. With the previous implementation (only relay 2 HIGH) there's no difference between speed low and speed medium, as the capacitors and therefore the resulting voltage are the same when only relay 1 or only relay 2. --- components/ifan/ifan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ifan/ifan.cpp b/components/ifan/ifan.cpp index 7baa3374..884c18e1 100644 --- a/components/ifan/ifan.cpp +++ b/components/ifan/ifan.cpp @@ -80,7 +80,7 @@ void IFan::set_low() { beep(); } void IFan::set_med() { - digitalWrite(relay_1, LOW); + digitalWrite(relay_1, HIGH); digitalWrite(relay_2, HIGH); digitalWrite(relay_3, LOW); beep(2); From 643fd3384c893606b913e1d017e6fe8f20c9d9a4 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 06:45:06 +0200 Subject: [PATCH 02/11] Use `fan.fan_schema` --- components/ifan04/__init__.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/components/ifan04/__init__.py b/components/ifan04/__init__.py index e0971498..30130fe0 100644 --- a/components/ifan04/__init__.py +++ b/components/ifan04/__init__.py @@ -1,8 +1,7 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import automation -from esphome.components import uart -from esphome.const import CONF_ID +from esphome.components import fan, uart DEPENDENCIES = ['uart'] @@ -14,8 +13,8 @@ CONF_ON_LIGHT = "on_light" CONF_ON_BUZZER = "on_buzzer" -CONFIG_SCHEMA = cv.COMPONENT_SCHEMA.extend({ - cv.GenerateID(): cv.declare_id(IFan04), +CONFIG_SCHEMA = ({ + fan.fan_schema(IFan04) cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True), cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True), cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True), @@ -23,7 +22,7 @@ async def to_code(config): - var = cg.new_Pvariable(config[CONF_ID]) + var = await fan.new_fan(config) await cg.register_component(var, config) await uart.register_uart_device(var, config) From 010c30f21b7f425be709e6c8f71c5c41c4ef99c6 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 06:53:21 +0200 Subject: [PATCH 03/11] Use `fan.fan_schema` --- components/ifan/fan.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/components/ifan/fan.py b/components/ifan/fan.py index c602ebd0..c71d56fa 100644 --- a/components/ifan/fan.py +++ b/components/ifan/fan.py @@ -1,6 +1,6 @@ import esphome.codegen as cg import esphome.config_validation as cv -from esphome.components import fan,uart +from esphome.components import fan, uart from esphome import automation from esphome.automation import maybe_simple_id @@ -19,12 +19,10 @@ IFan = ifan_ns.class_("IFan", cg.Component, fan.Fan, uart.UARTDevice) CycleSpeedAction = ifan_ns.class_("CycleSpeedAction", automation.Action) -CONFIG_SCHEMA = fan.FAN_SCHEMA.extend( - { - cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(IFan), - cv.Optional(BUZZER_ENABLE, default=True): cv.boolean, - cv.Optional(REMOTE_ENABLE, default=True): cv.boolean, - } +CONFIG_SCHEMA = ( + fan.fan_schema(IFan) + .extend(cv.Optional(BUZZER_ENABLE, default=True): cv.boolean) + .extend(cv.Optional(REMOTE_ENABLE, default=True): cv.boolean) ).extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA) FAN_ACTION_SCHEMA = maybe_simple_id( { @@ -40,7 +38,7 @@ async def fan_cycle_speed_to_code(config, action_id, template_arg, args): async def to_code(config): cg.add_define("USE_FAN") - var = cg.new_Pvariable(config[CONF_OUTPUT_ID]) + var = await fan.new_fan(config) cg.add(var.set_buzzer_enable(config[BUZZER_ENABLE])) cg.add(var.set_remote_enable(config[REMOTE_ENABLE])) if REMOTE_ENABLE in config: @@ -48,7 +46,5 @@ async def to_code(config): await uart.register_uart_device(var, config) await cg.register_component(var, config) - await fan.register_fan(var, config) - cg.add_global(ifan_ns.using) \ No newline at end of file From f071390ec86376c54be591e08c15e05e8d8bf27f Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 06:56:22 +0200 Subject: [PATCH 04/11] Fix brackets --- components/ifan/fan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/ifan/fan.py b/components/ifan/fan.py index c71d56fa..0c8e7b06 100644 --- a/components/ifan/fan.py +++ b/components/ifan/fan.py @@ -23,7 +23,8 @@ fan.fan_schema(IFan) .extend(cv.Optional(BUZZER_ENABLE, default=True): cv.boolean) .extend(cv.Optional(REMOTE_ENABLE, default=True): cv.boolean) -).extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA) + .extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA) +) FAN_ACTION_SCHEMA = maybe_simple_id( { cv.Required(CONF_ID): cv.use_id(IFan), From 5b75fa2469787e34e6bfe1fac47a18d1fc8fe152 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 06:59:24 +0200 Subject: [PATCH 05/11] Fix schema --- components/ifan04/__init__.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/components/ifan04/__init__.py b/components/ifan04/__init__.py index 30130fe0..55f28f62 100644 --- a/components/ifan04/__init__.py +++ b/components/ifan04/__init__.py @@ -13,12 +13,13 @@ CONF_ON_LIGHT = "on_light" CONF_ON_BUZZER = "on_buzzer" -CONFIG_SCHEMA = ({ +CONFIG_SCHEMA = ( fan.fan_schema(IFan04) - cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True), - cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True), - cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True), -}).extend(uart.UART_DEVICE_SCHEMA) + .extend(cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True)) + .extend(cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True)) + .extend(cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True)) + .extend(uart.UART_DEVICE_SCHEMA) +) async def to_code(config): From 7e198eba48de60a43bac70378079c599bf88dd15 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 07:01:18 +0200 Subject: [PATCH 06/11] Fix validation in schema --- components/ifan04/__init__.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/components/ifan04/__init__.py b/components/ifan04/__init__.py index 55f28f62..974a97c5 100644 --- a/components/ifan04/__init__.py +++ b/components/ifan04/__init__.py @@ -15,9 +15,15 @@ CONFIG_SCHEMA = ( fan.fan_schema(IFan04) - .extend(cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True)) - .extend(cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True)) - .extend(cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True)) + .extend({ + cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True) + }) + .extend({ + cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True) + }) + .extend({ + cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True) + }) .extend(uart.UART_DEVICE_SCHEMA) ) From c74e38130d53d525abfc28f98c08be9c6424fc77 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 07:03:29 +0200 Subject: [PATCH 07/11] Update fan.py --- components/ifan/fan.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/components/ifan/fan.py b/components/ifan/fan.py index 0c8e7b06..087b053c 100644 --- a/components/ifan/fan.py +++ b/components/ifan/fan.py @@ -8,7 +8,7 @@ CONF_OUTPUT_ID, CONF_ID, ) -from esphome.core import coroutine_with_priority +from esphome.core import coroutine_with_priority DEPENDENCIES = ['uart'] @@ -19,33 +19,38 @@ IFan = ifan_ns.class_("IFan", cg.Component, fan.Fan, uart.UARTDevice) CycleSpeedAction = ifan_ns.class_("CycleSpeedAction", automation.Action) +# Fixed CONFIG_SCHEMA with proper dictionary syntax CONFIG_SCHEMA = ( fan.fan_schema(IFan) - .extend(cv.Optional(BUZZER_ENABLE, default=True): cv.boolean) - .extend(cv.Optional(REMOTE_ENABLE, default=True): cv.boolean) - .extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA) + .extend({ + cv.Optional(BUZZER_ENABLE, default=True): cv.boolean, + cv.Optional(REMOTE_ENABLE, default=True): cv.boolean, + }) + .extend(cv.COMPONENT_SCHEMA) + .extend(uart.UART_DEVICE_SCHEMA) ) + FAN_ACTION_SCHEMA = maybe_simple_id( { cv.Required(CONF_ID): cv.use_id(IFan), } ) + @automation.register_action("ifan.cycle_speed", CycleSpeedAction, FAN_ACTION_SCHEMA) async def fan_cycle_speed_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) @coroutine_with_priority(100.0) - async def to_code(config): cg.add_define("USE_FAN") var = await fan.new_fan(config) cg.add(var.set_buzzer_enable(config[BUZZER_ENABLE])) cg.add(var.set_remote_enable(config[REMOTE_ENABLE])) + + # Register UART device if remote is enabled if REMOTE_ENABLE in config: - #await cg.register_component(var, config) await uart.register_uart_device(var, config) - await cg.register_component(var, config) - - cg.add_global(ifan_ns.using) \ No newline at end of file + await cg.register_component(var, config) + cg.add_global(ifan_ns.using) From 9cfbad0416c2227020a9d10c32781a035bdd77a8 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 07:08:05 +0200 Subject: [PATCH 08/11] Revert ifan04 schema --- components/ifan04/__init__.py | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/components/ifan04/__init__.py b/components/ifan04/__init__.py index 974a97c5..a532c067 100644 --- a/components/ifan04/__init__.py +++ b/components/ifan04/__init__.py @@ -1,11 +1,11 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import automation -from esphome.components import fan, uart +from esphome.components import uart +from esphome.const import CONF_ID DEPENDENCIES = ['uart'] - ifan04_ns = cg.esphome_ns.namespace('ifan04') IFan04 = ifan04_ns.class_('IFan04', cg.Component, uart.UARTDevice) @@ -13,23 +13,17 @@ CONF_ON_LIGHT = "on_light" CONF_ON_BUZZER = "on_buzzer" -CONFIG_SCHEMA = ( - fan.fan_schema(IFan04) - .extend({ - cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True) - }) - .extend({ - cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True) - }) - .extend({ - cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True) - }) - .extend(uart.UART_DEVICE_SCHEMA) +# Fixed: Use cv.COMPONENT_SCHEMA instead of fan.fan_schema since IFan04 is not a Fan +CONFIG_SCHEMA = cv.All( + cv.COMPONENT_SCHEMA.extend({ + cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True), + cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True), + cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True), + }).extend(uart.UART_DEVICE_SCHEMA) ) - async def to_code(config): - var = await fan.new_fan(config) + var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await uart.register_uart_device(var, config) @@ -45,4 +39,3 @@ async def to_code(config): await automation.build_automation( var.get_buzzer_trigger(), [], config[CONF_ON_BUZZER] ) - From 4d02dc10e10c07572fe21fa7f6d2154171cd8aef Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 07:08:53 +0200 Subject: [PATCH 09/11] Revert "Revert ifan04 schema" This reverts commit 9cfbad0416c2227020a9d10c32781a035bdd77a8. --- components/ifan04/__init__.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/components/ifan04/__init__.py b/components/ifan04/__init__.py index a532c067..974a97c5 100644 --- a/components/ifan04/__init__.py +++ b/components/ifan04/__init__.py @@ -1,11 +1,11 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import automation -from esphome.components import uart -from esphome.const import CONF_ID +from esphome.components import fan, uart DEPENDENCIES = ['uart'] + ifan04_ns = cg.esphome_ns.namespace('ifan04') IFan04 = ifan04_ns.class_('IFan04', cg.Component, uart.UARTDevice) @@ -13,17 +13,23 @@ CONF_ON_LIGHT = "on_light" CONF_ON_BUZZER = "on_buzzer" -# Fixed: Use cv.COMPONENT_SCHEMA instead of fan.fan_schema since IFan04 is not a Fan -CONFIG_SCHEMA = cv.All( - cv.COMPONENT_SCHEMA.extend({ - cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True), - cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True), - cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True), - }).extend(uart.UART_DEVICE_SCHEMA) +CONFIG_SCHEMA = ( + fan.fan_schema(IFan04) + .extend({ + cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True) + }) + .extend({ + cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True) + }) + .extend({ + cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True) + }) + .extend(uart.UART_DEVICE_SCHEMA) ) + async def to_code(config): - var = cg.new_Pvariable(config[CONF_ID]) + var = await fan.new_fan(config) await cg.register_component(var, config) await uart.register_uart_device(var, config) @@ -39,3 +45,4 @@ async def to_code(config): await automation.build_automation( var.get_buzzer_trigger(), [], config[CONF_ON_BUZZER] ) + From 5f8cb21cd0d9c130b75fb4a83f2c6e4b4841bce9 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 07:11:55 +0200 Subject: [PATCH 10/11] Revert schema --- components/ifan04/__init__.py | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/components/ifan04/__init__.py b/components/ifan04/__init__.py index 974a97c5..ff29bd28 100644 --- a/components/ifan04/__init__.py +++ b/components/ifan04/__init__.py @@ -1,11 +1,11 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import automation -from esphome.components import fan, uart +from esphome.components import uart +from esphome.const import CONF_ID DEPENDENCIES = ['uart'] - ifan04_ns = cg.esphome_ns.namespace('ifan04') IFan04 = ifan04_ns.class_('IFan04', cg.Component, uart.UARTDevice) @@ -13,23 +13,15 @@ CONF_ON_LIGHT = "on_light" CONF_ON_BUZZER = "on_buzzer" -CONFIG_SCHEMA = ( - fan.fan_schema(IFan04) - .extend({ - cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True) - }) - .extend({ - cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True) - }) - .extend({ - cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True) - }) - .extend(uart.UART_DEVICE_SCHEMA) -) - +# Reverted to the original working schema - cv.COMPONENT_SCHEMA without fan.fan_schema +CONFIG_SCHEMA = cv.COMPONENT_SCHEMA.extend({ + cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True), + cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True), + cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True), +}).extend(uart.UART_DEVICE_SCHEMA) async def to_code(config): - var = await fan.new_fan(config) + var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) await uart.register_uart_device(var, config) @@ -45,4 +37,3 @@ async def to_code(config): await automation.build_automation( var.get_buzzer_trigger(), [], config[CONF_ON_BUZZER] ) - From e4718613fd939ae3b52f464d3efb8c25d9d45b76 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Fri, 6 Jun 2025 07:13:04 +0200 Subject: [PATCH 11/11] Update __init__.py --- components/ifan04/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/components/ifan04/__init__.py b/components/ifan04/__init__.py index ff29bd28..ae744506 100644 --- a/components/ifan04/__init__.py +++ b/components/ifan04/__init__.py @@ -15,6 +15,7 @@ # Reverted to the original working schema - cv.COMPONENT_SCHEMA without fan.fan_schema CONFIG_SCHEMA = cv.COMPONENT_SCHEMA.extend({ + cv.GenerateID(): cv.declare_id(IFan04), # Add the ID field cv.Optional(CONF_ON_FAN): automation.validate_automation(single=True), cv.Optional(CONF_ON_LIGHT): automation.validate_automation(single=True), cv.Optional(CONF_ON_BUZZER): automation.validate_automation(single=True),