#pragma once #include "esphome/components/climate_ir/climate_ir.h" namespace esphome { namespace hitachi_rar6ne1 { // Timing del protocollo HITACHI_AC (28 byte), verificati su IRremoteESP8266 // (ir_Hitachi.cpp) e contro le catture reali del RAR-6NE1. static const uint16_t kHeaderMark = 3300; static const uint16_t kHeaderSpace = 1700; static const uint16_t kBitMark = 400; static const uint16_t kOneSpace = 1250; static const uint16_t kZeroSpace = 500; static const uint32_t kCarrierFrequency = 38000; static const uint8_t kStateLength = 28; // byte[9] = "codice tasto premuto" sul telecomando reale (0xE0 mode/idle, // 0xC0 power, ...). L'unita' molto probabilmente lo ignora quando riceve uno // stato completo, ma e' la PRIMA variabile da provare se i comandi sintetizzati // non vengono accettati. Vedi README / nota Obsidian. static const uint8_t kButtonCode = 0xE0; // Limiti dell'entita' climate. RANGE CONSERVATIVO 18-30 scelto per sicurezza. // FLAG: DA VERIFICARE contro il range realmente supportato dal RAR-6NE1 (alcuni // Hitachi arrivano a 16 in Cool e/o 32, altri si fermano prima). Vedi "Blocchi // attivi" nella nota Obsidian projects/hitachi-ir-esphome. static const float kMinTempC = 18.0f; static const float kMaxTempC = 30.0f; static const float kTempStep = 1.0f; class HitachiRar6ne1Climate : public climate_ir::ClimateIR { public: HitachiRar6ne1Climate() : climate_ir::ClimateIR( kMinTempC, kMaxTempC, kTempStep, /*supports_dry=*/true, /*supports_fan_only=*/true, // 4 velocita' + auto, mappate su modi standard HA: // QUIET=1/4 LOW=2/4 MEDIUM=3/4 HIGH=4/4 AUTO {climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_QUIET, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM, climate::CLIMATE_FAN_HIGH}, {climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL, climate::CLIMATE_SWING_HORIZONTAL, climate::CLIMATE_SWING_BOTH}, // Eco = Silent, Boost = Powerful {climate::CLIMATE_PRESET_NONE, climate::CLIMATE_PRESET_ECO, climate::CLIMATE_PRESET_BOOST}) {} // Invia un frame OFF realmente catturato (deterministico) per il test // self-loopback: richiamabile da un button template nello YAML. void send_test_frame(); // Accoppia preset e ventola come il telecomando fisico (Silent=ventola minima, // Powerful=massima, mutuamente esclusivi) prima di applicare il comando. void control(const climate::ClimateCall &call) override; protected: // Costruisce il frame IR dallo stato climate corrente e lo trasmette. void transmit_state() override; // Decodifica un frame ricevuto (telecomando fisico) e aggiorna lo stato. bool on_receive(remote_base::RemoteReceiveData data) override; // Riempie i 28 byte a partire dallo stato climate corrente (checksum incluso). void build_state_(uint8_t state[kStateLength]); // Emette i 28 byte sul trasmettitore IR (header + bit MSB-first + footer). void transmit_frame_(const uint8_t state[kStateLength]); // Checksum identico a IRHitachiAc::calcChecksum(). static uint8_t calc_checksum_(const uint8_t state[kStateLength]); }; } // namespace hitachi_rar6ne1 } // namespace esphome