Initial commit: Hitachi RAR-6NE1 climate via ESP32/ESPHome
Reverse engineering del protocollo IR (HITACHI_AC 28 byte) del telecomando RAR-6NE1 e custom component ESPHome bidirezionale (TX + RX) per Home Assistant. - esphome/: custom component hitachi_rar6ne1 (climate_ir::ClimateIR) + config - src/: firmware Arduino di cattura IR con web UI (strumento di diagnostica) - README.md: documentazione completa (protocollo, decode, checksum, gotcha) - Segreti esclusi dal versionamento (vedi *.example e .gitignore) - Licenza GPL-3.0 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
73
esphome/components/hitachi_rar6ne1/hitachi_rar6ne1.h
Normal file
73
esphome/components/hitachi_rar6ne1/hitachi_rar6ne1.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user