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.
This commit is contained in:
2026-10-03 00:41:36 +03:00
parent 66d64dda4f
commit 9a1c5eb143
6 changed files with 54 additions and 11 deletions
@@ -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 лента
+1 -1
View File
@@ -162,7 +162,7 @@
| `/mode` | число (B_MODE) | Режим |
| `/lock` | ON/OFF | Блокировка пульта |
| `/swing` | ON/OFF | Качание жалюзей |
| `/queit` | ON/OFF | Тихий режим (опечатка в прошивке! Статус публикуется в `/quiet`) |
| `/quiet` | ON/OFF | Тихий режим (legacy «queit» принимается; статус публикуется в `/quiet`) |
| `/raw` | - | Сырой кадр протокола |
---
+2 -2
View File
@@ -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"
+5 -5
View File
@@ -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)
```
---
+3 -2
View File
@@ -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
+42
View File
@@ -5,6 +5,7 @@
#include <item.h>
#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 <number> - 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: