diff --git a/esphome/components/vornado_ir/__init__.py b/esphome/components/vornado_ir/__init__.py new file mode 100644 index 0000000000..85b5bb56a6 --- /dev/null +++ b/esphome/components/vornado_ir/__init__.py @@ -0,0 +1,31 @@ +import esphome.codegen as cg +from esphome.components import remote_base +import esphome.config_validation as cv +from esphome.const import CONF_ID + +DEPENDENCIES = ["remote_transmitter"] +AUTO_LOAD = ["remote_base"] +CODEOWNERS = ["@jzucker2"] + +CONF_VORNADO_ID = "vornado_id" + +vornado_ir_ns = cg.esphome_ns.namespace("vornado_ir") +VornadoIR = vornado_ir_ns.class_( + "VornadoIR", cg.Component, remote_base.RemoteTransmittable +) + +CONFIG_SCHEMA = ( + cv.Schema( + { + cv.GenerateID(): cv.declare_id(VornadoIR), + } + ) + .extend(cv.COMPONENT_SCHEMA) + .extend(remote_base.REMOTE_TRANSMITTABLE_SCHEMA) +) + + +async def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + await cg.register_component(var, config) + await remote_base.register_transmittable(var, config) diff --git a/esphome/components/vornado_ir/button/__init__.py b/esphome/components/vornado_ir/button/__init__.py new file mode 100644 index 0000000000..6abc48fe70 --- /dev/null +++ b/esphome/components/vornado_ir/button/__init__.py @@ -0,0 +1,41 @@ +import esphome.codegen as cg +from esphome.components import button +import esphome.config_validation as cv + +from .. import CONF_VORNADO_ID, VornadoIR, vornado_ir_ns + +CODEOWNERS = ["@jzucker2"] +FanButton = vornado_ir_ns.class_("FanButton", button.Button) +PowerButton = vornado_ir_ns.class_("PowerButton", button.Button) + +# Toto IR buttons +CONF_FAN = "fan" +CONF_POWER = "power" + +# Additional icons +ICON_POWER_TOGGLE = "mdi:power-cycle" +ICON_FAN = "mdi:heat-wave" + +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(CONF_VORNADO_ID): cv.use_id(VornadoIR), + cv.Optional(CONF_FAN): button.button_schema( + FanButton, + icon=ICON_FAN, + ), + cv.Optional(CONF_POWER): button.button_schema( + PowerButton, + icon=ICON_POWER_TOGGLE, + ), + } +).extend(cv.COMPONENT_SCHEMA) + + +async def to_code(config): + for button_type in [ + CONF_FAN, + CONF_POWER, + ]: + if conf := config.get(button_type): + btn = await button.new_button(conf) + await cg.register_parented(btn, config[CONF_VORNADO_ID]) diff --git a/esphome/components/vornado_ir/button/fan.cpp b/esphome/components/vornado_ir/button/fan.cpp new file mode 100644 index 0000000000..079eb50ef2 --- /dev/null +++ b/esphome/components/vornado_ir/button/fan.cpp @@ -0,0 +1,11 @@ +#include "fan.h" + +namespace esphome { +namespace vornado_ir { + +static const char *const TAG = "vornado_ir.fan_button"; + +void FanButton::press_action() { this->parent_->send_start_fans(true); } + +} // namespace vornado_ir +} // namespace esphome diff --git a/esphome/components/vornado_ir/button/fan.h b/esphome/components/vornado_ir/button/fan.h new file mode 100644 index 0000000000..62e14e7661 --- /dev/null +++ b/esphome/components/vornado_ir/button/fan.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/button/button.h" +#include "../vornado_ir.h" + +namespace esphome { +namespace vornado_ir { + +class FanButton : public button::Button, public Parented { + public: + FanButton() = default; + + protected: + void press_action() override; +}; + +} // namespace vornado_ir +} // namespace esphome diff --git a/esphome/components/vornado_ir/button/power.cpp b/esphome/components/vornado_ir/button/power.cpp new file mode 100644 index 0000000000..ab6ba57775 --- /dev/null +++ b/esphome/components/vornado_ir/button/power.cpp @@ -0,0 +1,11 @@ +#include "power.h" + +namespace esphome { +namespace vornado_ir { + +static const char *const TAG = "vornado_ir.power_toggle_button"; + +void PowerButton::press_action() { this->parent_->send_power_toggle(); } + +} // namespace vornado_ir +} // namespace esphome diff --git a/esphome/components/vornado_ir/button/power.h b/esphome/components/vornado_ir/button/power.h new file mode 100644 index 0000000000..4d11fab6bc --- /dev/null +++ b/esphome/components/vornado_ir/button/power.h @@ -0,0 +1,18 @@ +#pragma once + +#include "esphome/components/button/button.h" +#include "../vornado_ir.h" + +namespace esphome { +namespace vornado_ir { + +class PowerButton : public button::Button, public Parented { + public: + PowerButton() = default; + + protected: + void press_action() override; +}; + +} // namespace vornado_ir +} // namespace esphome diff --git a/esphome/components/vornado_ir/vornado_ir.cpp b/esphome/components/vornado_ir/vornado_ir.cpp new file mode 100644 index 0000000000..26bb2d6404 --- /dev/null +++ b/esphome/components/vornado_ir/vornado_ir.cpp @@ -0,0 +1,44 @@ +#include "esphome/core/log.h" +#include "vornado_ir.h" +#include "vornado_ir_codes.h" +#include "esphome/core/application.h" + +namespace esphome { +namespace vornado_ir { + +static const char *TAG = "vornado_ir"; + +void VornadoIR::setup() { ESP_LOGCONFIG(TAG, "Setting up VornadoIR ..."); } + +void VornadoIR::loop() {} + +void VornadoIR::dump_config() { ESP_LOGCONFIG(TAG, "Toto IR"); } + +void VornadoIR::send_power_toggle(bool reset_timer) { + ESP_LOGI(TAG, "Sending power toggle request"); + this->transmit_(TOTO_IR_FIRST_POWER_TIMINGS); + this->transmit_(TOTO_IR_SECOND_POWER_TIMINGS); + this->transmit_(TOTO_IR_THIRD_POWER_TIMINGS); +} + +void VornadoIR::send_start_fans(bool reset_timer) { + ESP_LOGI(TAG, "Sending start fans request"); + this->transmit_(TOTO_IR_FIRST_FAN_TIMINGS); + this->transmit_(TOTO_IR_SECOND_FAN_TIMINGS); +} + +void VornadoIR::transmit_(RawTimings ir_code) { + ESP_LOGD(TAG, "Sending ir_code"); + auto transmit = this->transmitter_->transmit(); + ESP_LOGD(TAG, "Sending ir_code got transmitter"); + auto data = transmit.get_data(); + data->set_data(ir_code); + data->set_carrier_frequency(38000); + transmit.set_send_times(3); + transmit.set_send_wait(40000); + ESP_LOGD(TAG, "Sending ir_code actual perform transmit"); + transmit.perform(); +} + +} // namespace vornado_ir +} // namespace esphome diff --git a/esphome/components/vornado_ir/vornado_ir.h b/esphome/components/vornado_ir/vornado_ir.h new file mode 100644 index 0000000000..3ef6592ce4 --- /dev/null +++ b/esphome/components/vornado_ir/vornado_ir.h @@ -0,0 +1,27 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/remote_base/remote_base.h" +#include "esphome/components/remote_transmitter/remote_transmitter.h" +#include + +namespace esphome { +namespace vornado_ir { + +using remote_base::RemoteTransmitterBase; +using remote_base::RawTimings; + +class VornadoIR : public Component, public remote_base::RemoteTransmittable { + public: + void setup() override; + void loop() override; + void dump_config() override; + // general functions + void transmit_(RawTimings ir_code); + // direct actions + void send_power_toggle(bool reset_timer = false); + void send_start_fans(bool reset_timer = false); +}; + +} // namespace vornado_ir +} // namespace esphome diff --git a/esphome/components/vornado_ir/vornado_ir_codes.h b/esphome/components/vornado_ir/vornado_ir_codes.h new file mode 100644 index 0000000000..2ee9551559 --- /dev/null +++ b/esphome/components/vornado_ir/vornado_ir_codes.h @@ -0,0 +1,46 @@ +#pragma once + +#include "esphome/components/remote_base/remote_base.h" + +namespace esphome { +namespace vornado_ir { + +// Power Toggle +const remote_base::RawTimings TOTO_IR_FIRST_POWER_TIMINGS = { + 6020, -3037, 537, -575, 537, -1713, 537, -575, 537, -575, 537, -575, 564, -575, 537, -575, 537, + -575, 536, -602, 537, -575, 537, -575, 537, -1713, 537, -576, 536, -576, 560, -552, 560, -578, + 536, -576, 561, -551, 536, -576, 587, -552, 560, -552, 560, -552, 535, -576, 587, -1664, 536, + -576, 536, -1714, 560, -552, 536, -576, 560, -579, 560, -1663, 560, -1691, 536, -1688, 536, -576, + 562, -1688, 560, -553, 535, -577, 586, -552, 535, -1688, 536, -1715, 560}; + +const remote_base::RawTimings TOTO_IR_SECOND_POWER_TIMINGS = { + 5991, -3037, 560, -552, 537, -1713, 537, -576, 536, -576, 536, -576, 586, -552, 537, -575, 537, + -575, 537, -575, 587, -552, 560, -552, 536, -1714, 561, -551, 536, -576, 536, -576, 560, -578, + 536, -576, 560, -552, 536, -576, 536, -603, 560, -552, 559, -552, 537, -576, 562, -1687, 537, + -576, 560, -1690, 536, -576, 536, -576, 536, -603, 535, -1688, 536, -1715, 559, -1665, 560, -552, + 562, -1688, 560, -553, 535, -577, 585, -553, 559, -1665, 559, -1691, 560}; + +const remote_base::RawTimings TOTO_IR_THIRD_POWER_TIMINGS = { + 5992, -3036, 538, -575, 536, -1714, 561, -551, 537, -575, 560, -552, 563, -575, 561, -551, 537, + -575, 537, -576, 562, -576, 536, -576, 536, -1714, 537, -575, 537, -575, 536, -576, 536, -603, + 559, -553, 536, -576, 560, -552, 536, -602, 551, -561, 560, -552, 560, -552, 586, -1664, 536, + -576, 536, -1714, 561, -552, 559, -553, 535, -603, 536, -1688, 535, -1715, 560, -1664, 560, -553, + 561, -1689, 535, -577, 559, -553, 586, -552, 559, -1665, 535, -1715, 560}; + +// Start Fans +const remote_base::RawTimings TOTO_IR_FIRST_FAN_TIMINGS = { + 6019, -3010, 564, -575, 537, -1686, 538, -575, 563, -575, 537, -575, 562, -550, 537, -601, 538, + -574, 537, -576, 537, -575, 560, -578, 537, -1686, 538, -575, 563, -575, 561, -551, 537, -575, + 537, -575, 563, -576, 536, -576, 536, -576, 536, -576, 563, -575, 560, -552, 536, -1714, 537, + -1687, 537, -575, 561, -578, 560, -552, 560, -552, 536, -576, 587, -552, 535, -1688, 536, -1714, + 537, -576, 560, -552, 559, -579, 536, -576, 536, -576, 536, -576, 536}; + +const remote_base::RawTimings TOTO_IR_SECOND_FAN_TIMINGS = { + 6017, -3036, 538, -574, 538, -1686, 564, -574, 538, -574, 562, -550, 538, -575, 563, -575, 537, + -575, 561, -551, 537, -602, 561, -550, 537, -1687, 537, -602, 537, -575, 561, -551, 561, -551, + 536, -602, 537, -575, 537, -575, 537, -575, 563, -576, 536, -576, 536, -576, 536, -1714, 560, + -1664, 536, -603, 536, -576, 560, -551, 537, -575, 561, -578, 536, -576, 536, -1688, 562, -1688, + 536, -576, 560, -552, 563, -576, 560, -552, 560, -551, 536, -577, 586}; + +} // namespace vornado_ir +} // namespace esphome