From 9a1c5eb14389e27e19569d067257c063b49cb0b4 Mon Sep 17 00:00:00 2001 From: "anklimov@gmail.com" Date: Sat, 3 Oct 2026 00:41:36 +0300 Subject: [PATCH] fix(ac): rename quiet subitem 'queit' to 'quiet', keep legacy alias The input subitem for the AC quiet mode was misspelled 'queit'. The code now uses 'quiet' and still accepts 'queit' for backward compatibility; docs updated accordingly. Removing the alias is tracked in BACKLOG.md. --- documentation/core/channel_types_reference.md | 2 +- documentation/core/modules_description.md | 2 +- documentation/core/mqtt_quick_reference.md | 4 +- documentation/core/suffixes_reference.md | 10 ++--- lighthub/modules/out_ac.cpp | 5 ++- lighthub/modules/out_ac.h | 42 +++++++++++++++++++ 6 files changed, 54 insertions(+), 11 deletions(-) diff --git a/documentation/core/channel_types_reference.md b/documentation/core/channel_types_reference.md index 39df77d..364e7c5 100644 --- a/documentation/core/channel_types_reference.md +++ b/documentation/core/channel_types_reference.md @@ -129,7 +129,7 @@ ```json "ac_main": [10, 1] // номер порта serial (0-3) // подканалы: fan (LOW/MEDIUM/HIGH), set (16-40), temp, cmd -// также доступны подканалы lock/swing/queit/raw (/mode — число, текстовые режимы — в /cmd) +// также доступны подканалы lock/swing/quiet/raw (/mode — число, текстовые режимы — в /cmd) ``` ### CH_SPILED (11) - SPI LED лента diff --git a/documentation/core/modules_description.md b/documentation/core/modules_description.md index 6268ec2..bf61a5c 100644 --- a/documentation/core/modules_description.md +++ b/documentation/core/modules_description.md @@ -162,7 +162,7 @@ | `/mode` | число (B_MODE) | Режим | | `/lock` | ON/OFF | Блокировка пульта | | `/swing` | ON/OFF | Качание жалюзей | -| `/queit` | ON/OFF | Тихий режим (опечатка в прошивке! Статус публикуется в `/quiet`) | +| `/quiet` | ON/OFF | Тихий режим (legacy «queit» принимается; статус публикуется в `/quiet`) | | `/raw` | - | Сырой кадр протокола | --- diff --git a/documentation/core/mqtt_quick_reference.md b/documentation/core/mqtt_quick_reference.md index b4b1f8d..66abbec 100644 --- a/documentation/core/mqtt_quick_reference.md +++ b/documentation/core/mqtt_quick_reference.md @@ -129,8 +129,8 @@ mosquitto_pub -h 192.168.1.100 -t "myhome/in/ac_main/fan" -m "HIGH" # Направление воздуха (ON, OFF) mosquitto_pub -h 192.168.1.100 -t "myhome/in/ac_main/swing" -m "ON" -# Тихий режим (входной subitem «queit» — опечатка в прошивке; статус — /quiet) -mosquitto_pub -h 192.168.1.100 -t "myhome/in/ac_main/queit" -m "ON" +# Тихий режим (legacy «queit» также принимается; статус — /quiet) +mosquitto_pub -h 192.168.1.100 -t "myhome/in/ac_main/quiet" -m "ON" # Блокировка ПДУ mosquitto_pub -h 192.168.1.100 -t "myhome/in/ac_main/lock" -m "ON" diff --git a/documentation/core/suffixes_reference.md b/documentation/core/suffixes_reference.md index dceaa4e..d13002e 100644 --- a/documentation/core/suffixes_reference.md +++ b/documentation/core/suffixes_reference.md @@ -77,7 +77,7 @@ myhome/in/rgb_light → 240,100,200 | `/fan` | ✅ | ✅ | Скорость вентилятора | LOW, MEDIUM, HIGH, OFF или число | | `/lock` | ✅ | ✅ | Блокировка ПДУ | ON, OFF | | `/swing` | ✅ | ✅ | Направление воздушного потока | ON, OFF | -| `/quiet` | ✅ | ✅ | Режим "тихой работы". Входной subitem — «queit» (опечатка в прошивке); статус публикуется в `/quiet` | ON, OFF | +| `/quiet` | ✅ | ✅ | Режим "тихой работы". Входной subitem — `/quiet` (legacy «queit» принимается); статус публикуется в `/quiet` | ON, OFF | **Примеры**: ``` @@ -93,8 +93,8 @@ myhome/in/ac_main/set → 22 # Максимальная скорость вентилятора myhome/in/ac_main/fan → HIGH -# Включить тихий режим (входной subitem «queit» — опечатка в прошивке) -myhome/in/ac_main/queit → ON +# Включить тихий режим (legacy «queit» также принимается) +myhome/in/ac_main/quiet → ON ``` **Логика срабатывания AC**: @@ -237,7 +237,7 @@ myhome/in/ac/HEAT/set → 25 | 7 | CH_GROUP | `/cmd`, `/set`, `/hue`, `/sat`, `/HSV` | Группа каналов | | 8 | CH_VCTEMP | — | Регулятор Vacon (PID) | | 9 | CH_VC | — | Привод Vacon (Modbus) | -| 10 | CH_AC (Haier) | `/cmd`, `/set` (16-40), `/mode` (0-4), `/fan`, `/lock`, `/swing`, `/queit` (статус `/quiet`), `/temp`, `/raw` | Кондиционер | +| 10 | CH_AC (Haier) | `/cmd`, `/set` (16-40), `/mode` (0-4), `/fan`, `/lock`, `/swing`, `/quiet` (legacy `queit`), `/temp`, `/raw` | Кондиционер | | 11 | CH_SPILED | `/cmd`, `/set`, `/hue`, `/sat`, `/HSV` + subitem-пиксели 10-20 | Адресуемая LED лента | | 12 | CH_MOTOR | `/cmd`, `/set` | Сервопривод | | 13 | CH_PID | `/cmd`, `/set`, `/val` (вход сенсора), `/ctrl` | PID регулятор, теплые полы | @@ -430,7 +430,7 @@ myhome/s_out/rgb_lamp/cmd → ON /fan → HIGH Максимальная скорость вентилятора /lock → ON Заблокировать ПДУ (только кондиционер) /swing → ON Включить направление воздуха -/queit → ON Тихий режим (опечатка в прошивке; статус — /quiet) +/quiet → ON Тихий режим (legacy «queit» принимается; статус — /quiet) ``` --- diff --git a/lighthub/modules/out_ac.cpp b/lighthub/modules/out_ac.cpp index fab4fcb..76404a8 100644 --- a/lighthub/modules/out_ac.cpp +++ b/lighthub/modules/out_ac.cpp @@ -35,7 +35,8 @@ byte lock[] = {255,255,10,0,0,0,0,0,1,3,0,0,14}; // Блокировка пул //Extended subItem set const char LOCK_P[] PROGMEM = "lock"; -const char QUIET_P[] PROGMEM = "queit"; +const char QUIET_P[] PROGMEM = "quiet"; +const char QUIET_LEGACY_P[] PROGMEM = "queit"; // legacy typo, kept for backward compatibility const char SWING_P[] PROGMEM = "swing"; const char RAW_P[] PROGMEM = "raw"; @@ -503,7 +504,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized) // Some additional Subitems if (strcmp_P(subItem, LOCK_P) == 0) suffixCode = S_LOCK; else if (strcmp_P(subItem, SWING_P) == 0) suffixCode = S_SWING; - else if (strcmp_P(subItem, QUIET_P) == 0) suffixCode = S_QUIET; + else if (strcmp_P(subItem, QUIET_P) == 0 || strcmp_P(subItem, QUIET_LEGACY_P) == 0) suffixCode = S_QUIET; else if (strcmp_P(subItem, RAW_P) == 0) suffixCode = S_RAW; if (cmd.isCommand() && !suffixCode && !subItem) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it diff --git a/lighthub/modules/out_ac.h b/lighthub/modules/out_ac.h index 1535d34..a39d817 100644 --- a/lighthub/modules/out_ac.h +++ b/lighthub/modules/out_ac.h @@ -5,6 +5,7 @@ #include #include "itemCmd.h" +/** @brief Byte length of the AC status frame. */ #define LEN_B 37 #define B_CUR_TMP 13 //Текущая температура #define B_CMD 17 // 00-команда 7F-ответ ??? @@ -16,6 +17,7 @@ #define B_FRESH 31 //fresh 00 - off, 01 - on #define B_SET_TMP 35 //Установленная температура +/** Additional suffix codes (beyond the standard suffix_P table). */ #define S_LOCK S_ADDITIONAL+1 #define S_QUIET S_ADDITIONAL+2 #define S_SWING S_ADDITIONAL+3 @@ -23,6 +25,13 @@ extern void modbusIdle(void) ; +/** + * @brief Persistent per-item state of an AC channel, stored in the config tree. + * + * Holds the last 37-byte status frame received from the AC, decoded power + * and mode bytes, the last frame CRC value (inCheck, used to detect + * updates) and a timestamp of the last transmission. + */ class acPersistent : public chPersistent { public: byte data[37]; @@ -32,19 +41,52 @@ public: uint32_t timestamp; }; +/** + * @brief Air conditioner driver (Haier IR-over-UART protocol), channel type CH_AC = 10. + * + * Talks to a Haier AC over UART at 9600 baud using 13-byte request frames + * and 37-byte status frames (frame check = sum of bytes). Periodically + * polls the AC unit and applies control commands. + * + * JSON config (itemArg): [portNum(0-3), callbacksObj] + * - portNum: 0 = default port (Serial3, or USB-CDC Serial), 1..3 = Serial1..Serial3; + * - callbacksObj (optional): object with keys "fan", "set", "cmd", "temp" + * holding execution objects invoked on every polled status update. + * + * Ctrl commands: + * - /set 16-40 - set temperature; + * - /cmd - AUTO / HEAT / COOL / FAN_ONLY / DRY, plus ON / OFF; + * - /fan - LOW / MEDIUM / HIGH / AUTO / OFF, or a 0-255 value; + * - /mode - raw mode code; + * - subitems: "lock" ON/OFF, "swing" ON/OFF, "quiet" ON/OFF (legacy + * "queit" accepted for backward compatibility), "raw". + * + * Published status topics: /set, /temp, /mode, /cmd, /fan, /fresh, /lock, + * /quiet, /compressor, /swing. + */ class out_AC : public abstractOut { public: + /** @brief Default constructor; binds nothing until link() is called. */ out_AC():store(NULL),portNum(0),ACSerial(NULL){}; + /** @brief Links the channel item, attaches persistent storage and reads the config. */ void link(Item * _item){abstractOut::link(_item); if (_item) {store = (acPersistent *) item->getPersistent(); getConfig();} else store = NULL;}; + /** @brief Reads itemArg and selects the UART port (0-3) for the AC line. */ void getConfig(); + /** @brief Initializes persistent storage and starts the UART at 9600 baud. */ int Setup() override; + /** @brief Polls the AC every 5 s, parses the 37-byte status frame and publishes the status topics. */ int Poll(short cause) override; + /** @brief Releases the persistent storage and marks the channel as unknown. */ int Stop() override; + /** @brief Returns 1 if the AC power bit is set, 0 otherwise. */ int isActive() override; + /** @brief Returns CH_THERMO (5). */ int getChanType() override; // int getDefaultStorageType(){return ST_FLOAT_CELSIUS;}; + /** @brief Applies a control command: /set, /cmd, /fan, /mode, and lock/swing/quiet/raw subitems (see class doc). */ int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override; + /** @brief Invokes the named callback object ("fan"/"set"/"cmd"/"temp") from itemArg with a polled value. */ void SubmitParameters(const char * name, itemCmd value); protected: